The game was terrible. After all, it was too bad for me. No password was given. esayrsa was not easy at all. This problem was given an hour and a half after the game.
1, Title
from Crypto.Util.number import * def add(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 in range(len(a0)-len(b0)): ans = ans*10+a0[i]-48 for i in range(len(b0)): ans = ans*10+(a0[i+len(a0)-len(b0)]+b0[i]+4)%10 return ans def mul(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 in range(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 '''
2, Analysis
1.add() function
The function of add() is to add a and b without carry. It should be regarded as semi addition
I know everything~
2.mul() function
The function of mul() is similar to that of add(). The corresponding two digits are multiplied but not carried
Well, I know everything!
3. Problem solving ideas
In fact, this question is similar to the XOR question of the previous Zhonghai university competition and the fifth space.
The XOR problem tells us p^q, and then violent search, relying on n to verify.
The same is true for this problem. We know that add and mul can decompose the possible numbers in each bit, and then multiply them by n.
Then I took the script of the XOR problem and changed it.
I. decomposition
Find satisfaction in 0 ~ 9 ( x + y ) % 10 = = a (x+y)\%10==a (x+y)%10==a, ( x ∗ y ) % 10 = = b (x*y)\%10==b (x * y)%10==b (x,y)
II. Verification
Add X and y to (p,q), multiply p and Q, and judge p ∗ q p*q Whether the low order of p * q is equal to the low order of n (the low order length is the length of p or q)
If equal, then p and Q are possible values.
Why is this verification? I understand, but I don't understand. It's still too delicious after all
III. storage
Create a list pq0 to save all possible (p,q) in the current step
3, Problem solution
from Crypto.Util.number import * from gmpy2 import * a = 10399034381787849923326924881454040531711492204619924608227265350044149907274051734345037676383421545973249148286183660679683016947030357640361405556516408 b = 6004903250672248020273453078045186428048881010508070095760634049430058892705564009054400328070528434060550830050010084328522605000400260581038846465000861 n = 100457237809578238448997689590363740025639066957321554834356116114019566855447194466985968666777662995007348443263561295712530012665535942780881309520544097928921920784417859632308854225762469971326925931642031846400402355926637518199130760304347996335637140724757568332604740023000379088112644537238901495181 c = 49042009464540753864186870038605696433949255281829439530955555557471951265762643642510403828448619593655860548966001304965902133517879714352191832895783859451396658166132732818620715968231113019681486494621363269268257297512939412717227009564539512793374347236183475339558666141579267673676878540943373877937 def adddddddd(k, p0, q0): if (p0 * q0) % (10 ** (k + 1)) == n % (10 ** (k + 1)): pq0.append((p0, q0)) a0 = str(a) b0 = str(b) pq0 = [(0, 0)] for k in range(len(b0)): pq, pq0 = pq0, [(0, 0)] for i in range(10): for j in range(10): if (i + j) % 10 == int(a0[-k - 1]) and (i * j) % 10 == int(b0[-k - 1]): for (p, q) in pq: p = (p + i * 10 ** k) q = (q + j * 10 ** k) adddddddd(k, p, q) #print(pq0) p = int('1' + str(pq0[1][0])) q = pq0[1][1] #p=12092931636613623040737253079065768977037831274116990695362696899634198318309588587556607732878944639910799730236593646983127255905400637167879667181506829 #q=8307103755174226983699771812499382664784661030503034013965679561410051699975573257899430944515587916063550418050690024796566861042630720583592848475010689 #print(isPrime(p)) phi = (p - 1) * (q - 1) d = inverse(65537, phi) print(long_to_bytes(pow(c, d, n)))
I think the most classic thing in exp is
pq, pq0 = pq0, [(0, 0)]
This thing is true. Unexpectedly, put all the possibilities into pq0, then copy pq0 into PQ for the next step, and reset pq0 to store all the new possibilities.
4, Summary
I thought of a method for this problem, but I couldn't realize it. I got stuck in backtracking, but I don't need backtracking( 🤡 It's actually me). It's too delicious. I've read other people's ready-made scripts and need to work harder.