2024数据安全比赛trivial_rsa赛后复盘

题目:

from Crypto.Util.number import * 
from sage.all import *
from random import randrange
from secret import flag

m = bytes_to_long(flag)
p = getPrime(1024)
q = getPrime(1024)
n = p * q
e = 65537
r = bin(getPrime(len(flag)))[2:]
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
a = randrange(1, n)
c = (pow(m-pow(a,e,n), d, n)) % n
z = sum([int(r[i])*a**i for i in range(len(r))])
assert z < a**15 + 1
z = z % n

print(f'n = {n}')
print(f'e = {e}')
print(f'c = {c}')
print(f'z = {z}')

题目理论难度不高,就是爆破质数,解方程,其中m较小可以把a消元,然后small_root,刚开始groebner_basis()和resultant消元发现指数比较高,因为有其实有多个f,两次resultant然后HGCD,搞出指数比较小的多项式,自己数据测试,9位没有问题,所以开始爆破,15位质数加9位flag需要3个小时,修改多线程跑:

from sage.all_cmdline import *   # import sage library
 
from sage.all import *
from sage.matrix.matrix2 import Matrix as Matrix2
from Crypto.Util.number import *
import multiprocessing
def resultant(f1, f2, var):
	#print(f1.sylvester_matrix(f2, var))
	return Matrix2.determinant(f1.sylvester_matrix(f2, var))

n = 18958523822965779912899827783107438587572040487657111002474465900654251879648263776126782079490757516910092179229455697277114063200369560902566011503634573360990937108599191248791849618222649751050364361142600937548721273695606870531223115536894668583705065413241189513987778142820106936724774404027632297204326276900214510048550175919812310454623719455076518243383150380368352788245272891910180838780789265307926922228219671680149003036378499914252991087458570463044465887439954979441914227099761352286375336573082314068827094531345166273341200406447201114205915685170884295487124853039513234346915988003083904836693
e = 65537
c = 7686325199783272501572663174944755197791969370073187592251283865295440441060782400934009069787663356292165611134077915144925528467882885709675333515694288666120491594067996922521358065728072307779844654129380190278856814240484104370146630764792937658249106660318159393183856951836389587053477192829545069963314314238475766679268156189975051160344008244559582485586459952479020733368116753984144655302562187636209261364527605350759877694549049990708347877181830797691918826618366455511891171006294630191265136416467827504525021358151857386350805405256624532016401764802206666925927135797484939694162365798975882694400
z = 17950614509301690602331343526239959553361375297339190587035556501079164302293518648188343348695236634911677063321150112475964510884955885124571880690217875346815645822477251375686977571543320490617041697266656309287159844665671440176711392792168744385352881631876228518237664899306901002781611277601364328780219360646320253657773434189290477727573012009061692650151046975693283805592667681572001657620919743316515115813954895134531216761690636659433546138824119350927121917046759668488138718761936764212549027785798985119280676435812256960695225986500366400430644284664200908678552035575318170314847737926483287943789
from tqdm import tqdm



def test_sj(zs,s_i,e_i,c1,flenxx):
  def GCD(a, b):
      
      def HGCD(a, b):
          if 2 * b.degree() <= a.degree() or a.degree() == 1:
              return 1, 0, 0, 1
          m = a.degree() // 2
          a_top, a_bot = a.quo_rem(x**m)
          b_top, b_bot = b.quo_rem(x**m)
          R00, R01, R10, R11 = HGCD(a_top, b_top)
          c = R00 * a + R01 * b
          d = R10 * a + R11 * b
          q, e = c.quo_rem(d)
          d_top, d_bot = d.quo_rem(x**(m // 2))
          e_top, e_bot = e.quo_rem(x**(m // 2))
          S00, S01, S10, S11 = HGCD(d_top, e_top)
          RET00 = S01 * R00 + (S00 - q * S01) * R10
          RET01 = S01 * R01 + (S00 - q * S01) * R11
          RET10 = S11 * R00 + (S10 - q * S11) * R10
          RET11 = S11 * R01 + (S10 - q * S11) * R11
          return RET00, RET01, RET10, RET11
  
      q, r = a.quo_rem(b)
      if r == 0:
          return b
      R00, R01, R10, R11 = HGCD(a, b)
      c = R00 * a + R01 * b
      d = R10 * a + R11 * b
      if d == 0:
          return c.monic()
      q, r = c.quo_rem(d)
      if r == 0:
          return d
      return GCD(d, r)

  for i in tqdm(range(s_i,e_i)):
    if e_i>(len(zs)-2):
      break
    a=zs[i]
    flenxxtmp=8*flenxx-1
  
    #a=30047
    flag=b"flag{"+b"\x00"*flenxx+b"}"
    mbase = bytes_to_long(flag)
    r = bin(a)[2 :]
    P = PolynomialRing(Zmod(n), names=('x', 'y',)); (x, y,) = P._first_ngens(2)
    f=-z
    for i in range(len(r)):
    	f=f+int(r[i])*(x**i)
    f2=x**e+c1-y*256-mbase
    #print(type(f2))
    F = [f,f2]
    I = Ideal(F).groebner_basis()
    #print(I)
    f3=I[0]
    f4=I[1]
    h1=(resultant(f3,f,x))
    h2=(resultant(f4,f,x))
    R = PolynomialRing(Zmod(n), names=('y',))
    h1=R(h1)
    h2=R(h2)
    h3=GCD(h1,h2)
    h1=h3.monic()
    res=h1.small_roots(X=2**flenxxtmp, beta=0.4)      
    if len(res)>0:
      print(flenxx,a,res)
      break 
    

for flen in range(0,1):
  flenxx=9-flen
  print("flenxx=",flenxx)
  i=next_prime(2**(5+flenxx))
  c1=pow(c,e,n)
  print("c1=",c1)
  zs=[]
  while i<2**(6+flenxx):
      zs.append(int(i))
      i=next_prime(i)
  xcs=5
  kk=len(zs)//xcs+1
  for k in range(xcs):
    p = multiprocessing.Process(target=test_sj, args=(zs,kk*k,kk*(k+1),c1,flenxx,))
    p.start()
    print(k,"  start!!!")
#9 27673 [1373504846084034408822]  =>Ju5t_tr1v

后面再看了一下,直接快速幂更加快,1个小时,多线程15分钟内

from sage.all_cmdline import *   # import sage library
 
from sage.all import *
from sage.matrix.matrix2 import Matrix as Matrix2
from Crypto.Util.number import *
import multiprocessing
def resultant(f1, f2, var):
	#print(f1.sylvester_matrix(f2, var))
	return Matrix2.determinant(f1.sylvester_matrix(f2, var))

n = 18958523822965779912899827783107438587572040487657111002474465900654251879648263776126782079490757516910092179229455697277114063200369560902566011503634573360990937108599191248791849618222649751050364361142600937548721273695606870531223115536894668583705065413241189513987778142820106936724774404027632297204326276900214510048550175919812310454623719455076518243383150380368352788245272891910180838780789265307926922228219671680149003036378499914252991087458570463044465887439954979441914227099761352286375336573082314068827094531345166273341200406447201114205915685170884295487124853039513234346915988003083904836693
e = 65537
c = 7686325199783272501572663174944755197791969370073187592251283865295440441060782400934009069787663356292165611134077915144925528467882885709675333515694288666120491594067996922521358065728072307779844654129380190278856814240484104370146630764792937658249106660318159393183856951836389587053477192829545069963314314238475766679268156189975051160344008244559582485586459952479020733368116753984144655302562187636209261364527605350759877694549049990708347877181830797691918826618366455511891171006294630191265136416467827504525021358151857386350805405256624532016401764802206666925927135797484939694162365798975882694400
z = 17950614509301690602331343526239959553361375297339190587035556501079164302293518648188343348695236634911677063321150112475964510884955885124571880690217875346815645822477251375686977571543320490617041697266656309287159844665671440176711392792168744385352881631876228518237664899306901002781611277601364328780219360646320253657773434189290477727573012009061692650151046975693283805592667681572001657620919743316515115813954895134531216761690636659433546138824119350927121917046759668488138718761936764212549027785798985119280676435812256960695225986500366400430644284664200908678552035575318170314847737926483287943789
from tqdm import tqdm
c1=pow(c,e,n)
print("c1=",c1)

def jfc_test(zs,s_i,e_i,flenxx):
  for k in tqdm(range(s_i,e_i)):
    a=zs[k]
    flenxxtmp=8*flenxx-1
  
    #a=30047
    flag=b"flag{"+b"\x00"*flenxx+b"}"
    mbase = bytes_to_long(flag)
    r = bin(a)[2 :]
    P = PolynomialRing(Zmod(n), names=('x', 'y',)); (x, y,) = P._first_ngens(2)
    f=-z
    for i in (range(len(r))):
    	f=f+int(r[i])*(x**i)
    f2=x
    F = 1
    for i in bin(e)[2:][::-1]:
        if i == '1':
            F = (F*f2)%f
        f2 = (f2*f2)%f
    f2=F+c1-y*256-mbase
    #print(f2)
    h1=(resultant(f2,f,x))
    
    R = PolynomialRing(Zmod(n), names=('y',))
    h1=R(h1)
    h1=h1.monic()
    res=h1.small_roots(X=2**flenxxtmp, beta=0.4)      
    if len(res)>0:
      print(flenxx,a,res)
      break 

for flen in range(0,1):
  flenxx=9-flen
  print("flenxx=",flenxx)
  i=next_prime(2**(5+flenxx))  
  zs=[]
  while i<2**(6+flenxx):
      zs.append(int(i))
      i=next_prime(i)
  zs=zs[::-1]
  flenxx=9-flen
  print("flenxx=",flenxx)
  xcs=5
  kk=len(zs)//5+1
  for k in range(xcs):
    p = multiprocessing.Process(target=jfc_test, args=(zs,kk*k,kk*(k+1),flenxx,))
    p.start()
    print(k,"  start!!!")
  

只能说自己还是菜啊。。。。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值