flag = open('flag', 'rb').read() pt = int.from_bytes(flag, 'big') def case1(x): N = 0x9cca93a0eff966a6cc3426dc79f66c0526944c5a51681a3be685daee7506352dfb7bdd76e59995d2ba980158212f4797c3fc1ae81fdd3500e93634e7e5a47944d14b2de0922d0fcbe2ada121444ef6ad908992ffebaf3b710c2eb719b8b67a83711903885a6fcb0959dee527f946efd5f308dbb0e4eb720041a18e0984015da9 e = 0x10001 return pow(x, e, N) def case2(x): N = 0x56dc3d6211ef129bbaeadd8603658fec577ff9d95ad5e5fdd09c793a25dc932c98c0af71876a396663e398ab92ff1e504919ee3f1f5eda7a255ed68ac53d5f62d5b2a5e558fbe377078f8a1534bcfc6164febc51d3e004545106198492ebde663c530aac177ec30970b83e84e04d4251220f5ef3efaa396e81207b5d191bdffb579ad e = 0x10001 return pow(x, e, N) x = case1(pt) x = case2(x) print(x) # 15620344004575314381699909644476548125673811896863391476575828314467946163796453279562013347582204584161257318356658773248127199432536307725788425585122157944323601936111645375226259360207001107437486608453696480819916675738100568407249432260802623357309693764513235205165863599779333368122255526121539664687917017
2段のRSAになっていて、 case1 では N=p*pのRSAで、case 2ではgcd(phi, e) != 1のRSAになっている。
case2では、qが極端に小さいためpがNと近い大きさを持っており、としたときに、暗号文の情報が(たぶん)欠落しない(この式が成り立つのは だから)
case1はRSAにも書いたとおり
e = 65537 def case2_decrypt(x): q = 917519 p = 69707871934620509569728343326146258018582770029493511657054559474862686968409562136128616525777049328581358570890118432267895804235375130688754817769114083316475993705721434805544637977222767286061406234732498641334101774524615069140084400641451544889398258593755469676273142784457956433914529533013432954499 d = pow(e, -1, p-1) return pow(x % p, d, p) def case1_decrypt(x): p = 10492978880681953392127330744339615425831079360535424391240424219033821891058999100168555964454399098070169915149390329031335140789785697131896616096847731 d = pow(e, -1, p*(p-1)) return pow(x, d, p*p) c = 15620344004575314381699909644476548125673811896863391476575828314467946163796453279562013347582204584161257318356658773248127199432536307725788425585122157944323601936111645375226259360207001107437486608453696480819916675738100568407249432260802623357309693764513235205165863599779333368122255526121539664687917017 from Crypto.Util.number import long_to_bytes m = case1_decrypt(case2_decrypt(c)) print(long_to_bytes(m))