|
# 0. the game is matching pairs by multiplying their identifiers and checking if a given modulus exists |
|
# 1. recover all moduli and their ciphertexts |
|
# 2. grab all primes from the program |
|
# 3. match all known primes with moduli, crack the remaining ones with yafu - https://github.com/bbuhrow/yafu |
|
# 4. decrypt all ciphertext to get the full flag |
|
|
|
def exgcd(a, b): |
|
old_s, s = 1, 0 |
|
old_t, t = 0, 1 |
|
while b: |
|
q = a // b |
|
s, old_s = old_s - q * s, s |
|
t, old_t = old_t - q * t, t |
|
a, b = b, a % b |
|
return a, old_s, old_t |
|
|
|
def invmod(e, m): |
|
g, x, y = exgcd(e, m) |
|
assert g == 1 |
|
if x < 0: |
|
x += m |
|
return x |
|
|
|
|
|
def gcd(a, b): |
|
while b: |
|
a, b = b, a % b |
|
return a |
|
|
|
|
|
def lcm(a, b): |
|
return a // gcd(a, b) * b |
|
|
|
# [ciphertext, p, q] |
|
chunks = [ |
|
[ |
|
538634309079148116363912301816926031930258573110799122862941, |
|
885099533904372795874859687719, |
|
1167170536952850475909418174911 |
|
], |
|
[ |
|
562733309494608716994364770937828277740523146074677621141932, |
|
778021292426438436606425112727, |
|
1055301397731143498286103730113 |
|
], |
|
[ |
|
319243791255303502020259161971610515049913374771288695699737, |
|
1215072113218197541320209640371, |
|
1038934092753097872730253139059 |
|
], |
|
[ |
|
941629393855667943649547190044646980315269461850095508227115, |
|
1033646404229761438304319507287, |
|
1255561944672568469862862185019 |
|
], |
|
[ |
|
914355749731699186791425204706414002614646261411469947941828, |
|
1142600241573404407687535573629, |
|
993312580651766761514801353103 |
|
], |
|
[ |
|
558030107305255463640139626217118512514526900834839072384186, |
|
892852023919058398648656968671, |
|
1262714843670806964782879865877 |
|
], |
|
[ |
|
251738364156397018723696894127984058119319062121032554046180, |
|
646707326780153459647011532987, |
|
813122100173370069804649439983 |
|
], |
|
[ |
|
774165720938595325818024236038187794673577169187146034055752, |
|
693661003419668078345820408199, |
|
1253977927505847682354254592843 |
|
] |
|
] |
|
|
|
|
|
for ct, p, q in chunks: |
|
e = 65537 |
|
t = lcm(p - 1, q - 1) |
|
n = p * q |
|
d = invmod(e, t) |
|
|
|
decrypted = pow(ct, d, n) |
|
print(decrypted.to_bytes(8)) |