from Crypto.Util.number import * # from secret import flag flag = b'flag'
defadd(a,b): if(a<b): a0 = str(b).encode() b0 = str(a).encode() else: a0 = str(a).encode() b0 = str(b).encode() ans = 0 for i inrange(len(a0)-len(b0)): ans = ans*10+a0[i]-48 # print(ans) for i inrange(len(b0)): ans = ans*10+(a0[i+len(a0)-len(b0)]+b0[i]+4)%10 return ans
defmul(a,b): if(a<b): a0 = str(b).encode() b0 = str(a).encode() else: a0 = str(a).encode() b0 = str(b).encode() ans = 0 for i inrange(len(b0)): ans = ans*10+((a0[i+len(a0)-len(b0)]+2)*(b0[i]+2))%10 return ans
m = bytes_to_long(flag) e = 65537 p = getPrime(512) q = getPrime(512) n = p*q # c = pow(m,e,n) print(add(p,q)) print(mul(p,q)) # print(n) # print(c) # 10399034381787849923326924881454040531711492204619924608227265350044149907274051734345037676383421545973249148286183660679683016947030357640361405556516408 # 6004903250672248020273453078045186428048881010508070095760634049430058892705564009054400328070528434060550830050010084328522605000400260581038846465000861 # 100457237809578238448997689590363740025639066957321554834356116114019566855447194466985968666777662995007348443263561295712530012665535942780881309520544097928921920784417859632308854225762469971326925931642031846400402355926637518199130760304347996335637140724757568332604740023000379088112644537238901495181 # 49042009464540753864186870038605696433949255281829439530955555557471951265762643642510403828448619593655860548966001304965902133517879714352191832895783859451396658166132732818620715968231113019681486494621363269268257297512939412717227009564539512793374347236183475339558666141579267673676878540943373877937
关键是看懂下面两句话,即没有进位的十进制加法和乘法
1
ans = ans*10+(a0[i+len(a0)-len(b0)]+b0[i]+4)%10
1
ans = ans*10+((a0[i+len(a0)-len(b0)]+2)*(b0[i]+2))%10
from Crypto.Util.number import long_to_bytes from gmpy2 import invert
defadd(a,b): if(a<b): a0 = str(b).encode() b0 = str(a).encode() else: a0 = str(a).encode() b0 = str(b).encode() ans = 0 for i inrange(len(a0)-len(b0)): ans = ans*10+a0[i]-48 # print(ans) for i inrange(len(b0)): ans = ans*10+(a0[i+len(a0)-len(b0)]+b0[i]+4)%10 return ans
defmul(a,b): if(a<b): a0 = str(b).encode() b0 = str(a).encode() else: a0 = str(a).encode() b0 = str(b).encode() ans = 0 for i inrange(len(b0)): ans = ans*10+((a0[i+len(a0)-len(b0)]+2)*(b0[i]+2))%10 return ans
n = 100457237809578238448997689590363740025639066957321554834356116114019566855447194466985968666777662995007348443263561295712530012665535942780881309520544097928921920784417859632308854225762469971326925931642031846400402355926637518199130760304347996335637140724757568332604740023000379088112644537238901495181 ADD = '10399034381787849923326924881454040531711492204619924608227265350044149907274051734345037676383421545973249148286183660679683016947030357640361405556516408' MUL = '6004903250672248020273453078045186428048881010508070095760634049430058892705564009054400328070528434060550830050010084328522605000400260581038846465000861' # print(len(ADD)) # print(len(MUL)) # 155 # 154 # p 154 q 155 or p 155 q 154 MUL = '0' + MUL
candidate = [(0, 0)] for b10 inrange(155): # print(len(candidate), candidate) crit = b10+1 candidateForCandidate, candidate = candidate, [] for p, q in candidateForCandidate: for i inrange(10): for j inrange(10): xx = p + i * 10 ** b10 yy = q + j * 10 ** b10 if ADD[-crit:] != str(add(xx, yy)).zfill(crit): continue if MUL[-crit:] != str(mul(xx, yy)).zfill(crit): continue ifstr(xx * yy)[-crit:] != str(n)[-crit:]: continue if (yy, xx) notin candidate and (xx, yy) notin candidate: candidate.append((xx, yy))
for p, q in candidate: if p * q == n: e = 0x10001 c = 49042009464540753864186870038605696433949255281829439530955555557471951265762643642510403828448619593655860548966001304965902133517879714352191832895783859451396658166132732818620715968231113019681486494621363269268257297512939412717227009564539512793374347236183475339558666141579267673676878540943373877937 d = invert(e, n - p - q + 1) m = pow(c, d, n) print(long_to_bytes(m)) break # b'flag{a4e3676e1e340581f7018972dd1905be}'
from Crypto.Util.number import * from gmpy2 import next_prime from functools import reduce from secret import * import random
defF(x): if (x<4): return1 return F(x-1)+F(x-2)+F(x-3)
m = bytes_to_long(flag) e = random.getrandbits(250) p = getPrime(1001) q = getPrime(1001) k = e**e s = reduce(lambda a, b: a*b, [F(k+i) % e for i inrange(1,5)]) + F(2021**k)**4 p = next_prime(s) c = pow(m,e,p) print(e) print(c) #1292991588783542706506728336494377723983115217051171962646571511384590134899 #229797522574801936576076488492034448896863980731763047709941641260180597290800402814069755381965565755866855389082787759443816945304000719176334587540293777658369250939545994974691382505993209963323032684771922094686136104097942892330051349688373437571196103392801691879287264056022383484359551333197
from Crypto.Util.number import * from gmpy2 import next_prime from functools import reduce
e = 1292991588783542706506728336494377723983115217051171962646571511384590134899 c = 229797522574801936576076488492034448896863980731763047709941641260180597290800402814069755381965565755866855389082787759443816945304000719176334587540293777658369250939545994974691382505993209963323032684771922094686136104097942892330051349688373437571196103392801691879287264056022383484359551333197 M = matrix(IntegerModRing(e), [[1,1,1],[1,0,0],[0,1,0]]) v = vector(ZZ, [1,1,1]) defF(n): returnint((M ^ int((n - 3)) * v)[0])
# https://www.alpertron.com.ar/ECM.HTM p1 = 33285073849485750791903437807279991921 p2 = 38845988283830087557982578789883120419 assert p1 * p2 == e phi = (p1^2 - 1) * (p2^2 - 1) phi2 = euler_phi(p1+1)*euler_phi(p1-1)*euler_phi(p2+1)*euler_phi(p2-1) k = pow(e, e, phi) k2 = pow(e, e, phi2)
s = reduce(lambda a, b: a*b, [F(k + i) for i inrange(1, 5)]) + (F(pow(2021, k2, phi))^4) p = next_prime(s) print(long_to_bytes(pow(c, inverse(e, p - 1), p))) # b'flag{94e2b59bd8e8899be7bfa3ee9e540a2f}'
最后,题目存在不严谨的地方。第17行
1
s = reduce(lambda a, b: a*b, [F(k+i) % e for i inrange(1,5)]) + F(2021**k)**4