crypto-黄金分割RSA(2020电信和互联网行业赛)

题目源码:

publickey=[0x1d42aea2879f2e44dea5a13ae3465277b06749ce9059fd8b7b4b560cd861f99144d0775ffffffffffff,5]
c=421363015174981309103786520626603807427915973516427836319727073378790974986429057810159449046489151

enc=[1,28657,2,1,3,17711,5,8,13,21,46368,75025,34,55,89,610,377,144,233,1597,2584,4181,6765,10946,987]

老规矩先尝试分解N:

sage: n=0x1d42aea2879f2e44dea5a13ae3465277b06749ce9059fd8b7b4b560cd861f99144d0775ffffffffffff              
sage: factor(n)                                                                                            
9749 * 11237753507624591 * 9127680453986244150392840833873266696712898279308227257525736684312919750469261
sage:     

一般情况直接用以下套路求解:

e = 5
phin = (p - 1) * (q - 1) * (r - 1)
d = gmpy2.invert(e, phin)

但本题中显然e与q-1和r-1均不互素。这时候又要祭出AMM大法,还是参考这篇:

有限域上的高次开根AMM算法在RSA上的应用

因为e与p是互素的,先求解一下m%p:

import gmpy2
c = 421363015174981309103786520626603807427915973516427836319727073378790974986429057810159449046489151
p = 9749 
q = 11237753507624591
r = 9127680453986244150392840833873266696712898279308227257525736684312919750469261
e = 5
 
c1 = c%p
d = gmpy2.invert(e,p-1)
c1 = pow(c1,d,p)
print(c1)
#求出m%p的解
#mmp=7361

然后套入AMM求解脚本,由于本题e数值较小,很快出结果:

import random
import time
import binascii
 
# About 3 seconds to run
def AMM(o, r, q):
    start = time.time()
    print('\n----------------------------------------------------------------------------------')
    print('Start to run Adleman-Manders-Miller Root Extraction Method')
    print('Try to find one {:#x}th root of {} modulo {}'.format(r, o, q))
    g = GF(q)
    o = g(o)
    p = g(random.randint(1, q))
    while p ^ ((q-1) // r) == 1:
        p = g(random.randint(1, q))
    print('[+] Find p:{}'.format(p))
    t = 0
    s = q - 1
    while s % r == 0:
        t += 1
        s = s // r
    print('[+] Find s:{}, t:{}'.format(s, t))
    k = 1
    while (k * s + 1) % r != 0:
        k += 1
    alp = (k * s + 1) // r
    print('[+] Find alp:{}'.format(alp))
    a = p ^ (r**(t-1) * s)
    b = o ^ (r*alp - 1)
    c = p ^ s
    h = 1
    for i in range(1, t):
        d = b ^ (r^(t-1-i))
        if d == 1:
            j = 0
        else:
            print('[+] Calculating DLP...')
            j = - discrete_log(d, a)
            print('[+] Finish DLP...')
        b = b * (c^r)^j
        h = h * c^j
        c = c^r
    result = o^alp * h
    end = time.time()
    print("Finished in {} seconds.".format(end - start))
    print('Find one solution: {}'.format(result))
    return result
 
def findAllPRoot(p, e):
    print("Start to find all the Primitive {:#x}th root of 1 modulo {}.".format(e, p))
    start = time.time()
    proot = set()
    while len(proot) < e:
        proot.add(pow(random.randint(2, p-1), (p-1)//e, p))
        #print(len(proot))
    end = time.time()
    print("Finished in {} seconds.".format(end - start))
    return proot
 
def findAllSolutions(mp, proot, cp, p):
    print("Start to find all the {:#x}th root of {} modulo {}.".format(e, cp, p))
    start = time.time()
    all_mp = set()
    for root in proot:
        mp2 = mp * root % p
        assert(pow(mp2, e, p) == cp)
        all_mp.add(mp2)
    end = time.time()
    print("Finished in {} seconds.".format(end - start))
    return all_mp
 
c = 421363015174981309103786520626603807427915973516427836319727073378790974986429057810159449046489151
p = 9749 
q = 11237753507624591
r = 9127680453986244150392840833873266696712898279308227257525736684312919750469261
e = 5
 
#cp = c % p
cq = c % q
cr = c % r
#mp = AMM(cp, e, p)
mq = AMM(cq, e, q)
mr = AMM(cr, e, r)
#p_proot = findAllPRoot(p, e)
q_proot = findAllPRoot(q, e)
r_proot = findAllPRoot(r, e)
#mps = findAllSolutions(mp, p_proot, cp, p)
mps = [7361]
mqs = findAllSolutions(mq, q_proot, cq, q)
mrs = findAllSolutions(mr, r_proot, cr, r)
print(mqs, '---',mrs)
 
def check(m):
    h = m.hex()
    if len(h) & 1:
        return False
    s=binascii.unhexlify(h)
    #print('checking...',s)
    if s.startswith(b'flag'):
        print(s)
        return True
    else:
        return False
 
# About 16 mins to run 0x1337^2 == 24196561 times CRT
start = time.time()
print('Start CRT...')
for mpp in mps:
    for mqq in mqs:
        for mrr in mrs:
            solution = CRT_list([int(mpp), int(mqq),int(mrr)], [p, q,r])
            if check(solution):
                print(solution)
    print(time.time() - start)
 
end = time.time()
print("Finished in {} seconds.".format(end - start))
'''
b'flag{weadfa9987_adwd23123_454f}'
'''

得到第一个flag后面就是根据enc中打乱的斐波那契数列调整字符顺序,不是本题重点不再赘述。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值