NewStarCTF week2 Rabin题解

from Crypto.Util.number import *
from somewhere_you_do_not_know import flag
#flag格式为 flag{XXXX}
def ezprime(n):
    p=getPrime(n)
    while p%4!=3:
        p=getPrime(n)
    return p
p=ezprime(512)
q=ezprime(512)
n=p*q
m=bytes_to_long(flag)
m=(m<<(300))+getRandomNBitInteger(300)
assert m**2>n and m<n
c=pow(m,4,n)
print('c=',c)
print('p=',p)
print('q=',q)
'''
c= 59087040011818617875466940950576089096932769518087477304162753047334728508009365510335057824251636964132317478310267427589970177277870220660958570994888152191522928881774614096675980017700457666192609573774572571582962861504174396725705862549311100229145101667835438230371282904888448863223898642183925834109
p= 10522889477508921233145726452630168129218487981917965097647277937267556441871668611904567713868254050044587941828674788953975031679913879970887998582514571
q= 11287822338267163056031463255265099337492571870189068887689824393221951058498526362126606231275830844407608185240702408947800715624427717739233431252556379
就要花里胡哨(
'''

观察题目,可以发现与rsa不同的是e是偶数,也就是变异rsa,rabin解密。

c =pow(m,4,n)可以得出m^4 =c mod n 因此本题的思路是开方

利用二次剩余先开二次方得到m^2的解

c1=pow(c,(p+1)//4,p)
c2=pow(c,(q+1)//4,q)
cp1=p-c1
cp2=q-c2
t1=gmpy2.invert(p,q)#p的模q逆元
t2=gmpy2.invert(q,p)#q的模p逆元
m1=(q*c1*t2+p*c2*t1)%n
m2=(q*c1*t2+p*cp2*t1)%n # or m2=n-m1
m3=(q*cp1*t2+p*c2*t1)%n
m4=(q*cp1*t2+p*cp2*t1)%n # or m4=n-m3

通过 assert m**2>n and m<n 可以发现我们无法对m^2直接进行开方

因此还是通过二次剩余来求解m

这边注意,因为会出现16种解,所以我们最好不要求解所有解,可以一组一组慢慢来,得出结果后观察题目,需要移位,因此结果移位再转字符,出现flag

x1=q*c1*t2+p*c2*t1
x2=q*c1*t2+p*cp2*t1
x3=q*cp1*t2+p*c2*t1
x4=q*cp1*t2+p*cp2*t1
mm1 = pow(x1,(p+1)//4,p)
mm11 = pow(x1,(q+1)//4,q)
mm2 = pow(x2,(p+1)//4,p)
mm22 = pow(x2,(q+1)//4,q)
mm3 = pow(x3,(p+1)//4,p)
mm33 = pow(x3,(q+1)//4,q)
mm4 = pow(x4,(p+1)//4,p)
mm44 = pow(x4,(q+1)//4,q)
l1 = (q*mm1*t2 + p*mm11*t1)%n
l11 = (q*mm1*t2 + p*(q-mm11)*t1)%n
l111= (q*(p-mm1)*t2 + p*mm11*t1)%n
l1111 = (q*(p-mm1)*t2 + p*(q-mm11)*t1)%n
for i in(l1,l11,l111,l1111):
    i = (i>>300)
    x = long_to_bytes(i)
    print(x)

最后得出flag

下面给出完整代码

from Crypto.Util.number import *
import gmpy2
c= 59087040011818617875466940950576089096932769518087477304162753047334728508009365510335057824251636964132317478310267427589970177277870220660958570994888152191522928881774614096675980017700457666192609573774572571582962861504174396725705862549311100229145101667835438230371282904888448863223898642183925834109
p= 10522889477508921233145726452630168129218487981917965097647277937267556441871668611904567713868254050044587941828674788953975031679913879970887998582514571
q= 11287822338267163056031463255265099337492571870189068887689824393221951058498526362126606231275830844407608185240702408947800715624427717739233431252556379
n = p*q
e = 4
c1=pow(c,(p+1)//4,p)
c2=pow(c,(q+1)//4,q)
cp1=p-c1
cp2=q-c2
t1=gmpy2.invert(p,q)#p的模q逆元
t2=gmpy2.invert(q,p)#q的模p逆元
m1=(q*c1*t2+p*c2*t1)%n
m2=(q*c1*t2+p*cp2*t1)%n # or m2=n-m1
m3=(q*cp1*t2+p*c2*t1)%n
m4=(q*cp1*t2+p*cp2*t1)%n # or m4=n-m3
x1=q*c1*t2+p*c2*t1
x2=q*c1*t2+p*cp2*t1
x3=q*cp1*t2+p*c2*t1
x4=q*cp1*t2+p*cp2*t1
mm1 = pow(x1,(p+1)//4,p)
mm11 = pow(x1,(q+1)//4,q)
mm2 = pow(x2,(p+1)//4,p)
mm22 = pow(x2,(q+1)//4,q)
mm3 = pow(x3,(p+1)//4,p)
mm33 = pow(x3,(q+1)//4,q)
mm4 = pow(x4,(p+1)//4,p)
mm44 = pow(x4,(q+1)//4,q)
l1 = (q*mm1*t2 + p*mm11*t1)%n
l11 = (q*mm1*t2 + p*(q-mm11)*t1)%n
l111= (q*(p-mm1)*t2 + p*mm11*t1)%n
l1111 = (q*(p-mm1)*t2 + p*(q-mm11)*t1)%n
for i in(l1,l11,l111,l1111):
    i = (i>>300)
    x = long_to_bytes(i)
    print(x)
posted @ 2022-10-16 18:36  m0feng  阅读(66)  评论(0编辑  收藏  举报