buu [NPUCTF2020]共 模 攻 击 1

题目描述:

task:

hint: 

题目分析:

  •  先看hint(提示)这一部分,标题已经提示了是共模攻击,看到有e1,e2,c1,c2,n也可以想到是共模攻击,之后得到c,继续往下做

c = m^{256} mod p

  • 此时有点不知如何下手,e = 256 = 2^{8}

并且

gcd(e // 4,p-1) = 4

gcd(e // 4 // 4,p-1) = 4

gcd(e // 4 // 4 // 4,p-1) = 4

啊这......(这怎么去做)

  • 看到别人写的,用sympy库中的nthroot_mod(c,e,n)函数可以做出来 ,目前第一次用此函数,还没什么经验,也不好多分享什么,大家多摸索吧
  •  hint部分的解题代码
p = 107316975771284342108362954945096489708900302633734520943905283655283318535709
n = 6807492006219935335233722232024809784434293293172317282814978688931711423939629682224374870233587969960713638310068784415474535033780772766171320461281579
e1 = 2303413961
c1 = 1754421169036191391717309256938035960912941109206872374826444526733030696056821731708193270151759843780894750696642659795452787547355043345348714129217723
e2 = 2622163991
c2 = 1613454015951555289711148366977297613624544025937559371784736059448454437652633847111272619248126613500028992813732842041018588707201458398726700828844249
import gmpy2
from Crypto.Util.number import *
from sympy import *
s,s1,s2 = gmpy2.gcdext(e1,e2)
c = pow(c1,s1,n) * pow(c2,s2,n)%n
e = 256
m = nthroot_mod(c,e,p)
print(long_to_bytes(m))
# b'm.bit_length() < 400'
  • 这里也可以直接在sage中解,代码如下:
    from Crypto.Util.number import *
    c = 19384002358725759679198917686763310349050988223627625096050800369760484237557
    p = 107316975771284342108362954945096489708900302633734520943905283655283318535709
    # c = m ^ 256 mod p
    P.<x> = Zmod(p)[]
    f = x ^ 256 - c
    a = f.roots()
    for i in a:
        print(long_to_bytes(int(i[0])))
     得到:

 

知道了m的比特位小于400位

  • 接下来看task,显然,根据提示,可以尝试使用coppersmith定理

 '''构造关于m的同余式,已知的模数是n,所以要尽量让构造出的m的等式是n的倍数(也就是模n等于0)当然也可以是余数不等于0的情况但是一定要已知余数是多少(这里似乎没有什么数学定理可以应用,大概率就是直接构造一个等式等于n的倍数即可)'''

  •  代码如下:
# sage

from Crypto.Util.number import *
n = 128205304743751985889679351195836799434324346996129753896234917982647254577214018524580290192396070591032007818847697193260130051396080104704981594190602854241936777324431673564677900773992273463534717009587530152480725448774018550562603894883079711995434332008363470321069097619786793617099517770260029108149
c1 = 96860654235275202217368130195089839608037558388884522737500611121271571335123981588807994043800468529002147570655597610639680977780779494880330669466389788497046710319213376228391138021976388925171307760030058456934898771589435836261317283743951614505136840364638706914424433566782044926111639955612412134198
c2 = 9566853166416448316408476072940703716510748416699965603380497338943730666656667456274146023583837768495637484138572090891246105018219222267465595710692705776272469703739932909158740030049375350999465338363044226512016686534246611049299981674236577960786526527933966681954486377462298197949323271904405241585
sum = c1 + c2
mult = c1 * c2
PR.<x> = PolynomialRing(Zmod(n))
# R.<x> = PolynomialRing(Zmod(n),implementation = 'NTL')
# R.<x> = Zmod(n)[]
# 上面三个都行
f = x ^ 2 + mult - sum * x
flag = f.small_roots(X = 2 ^ 400)[0] # 2 ^ 400是根的上界
print(flag)
# print(long_to_bytes(flag)
flag = 4242839043019782000788118887372132807371568279472499477998758466224002905442227156537788110520335652385855
print(long_to_bytes(flag))

收获与体会:

  • 以后遇到e还算小的可以尝试用sympy.nthroot_mod(),感觉这东西还挺🐂的,哈哈哈
m = nthroot_mod(c,256,p,all_roots=True) # 所有根,列表中
print (m)
for i in m:
    print (i)
    hint = long_to_bytes(i)
    print (hint)

  •  以上copper法值得收藏(求m,m位数已知,并且c1 = m^p mod n, c2 = m^q mod n)

以下三个可以互换使用,目前还没看到局限(可能是做题少了吧)

PR.<x> = PolynomialRing(Zmod(n))
R.<x> = PolynomialRing(Zmod(n),implementation = 'NTL')
R.<x> = Zmod(n)[]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值