CCTF_Public/writeups/vol9_rnd1/tifany/exp.sage

42 lines
3.0 KiB
Python

#!/usr/bin/env sage
from Crypto.Util.number import *
# Some investigation shows that we are applying the `Joye-Libert' cryptosystem, so the decryption function is:
def decrypt(keypair, c):
p, pubkey = keypair
k, n, y = pubkey
assert n % p == 0
z = pow(c, (p - 1) // (2 ** k), p)
x = pow(y, (p - 1) // (2 ** k), p)
m = discrete_log(z, x)
return m
# But we need the private key, or one of the prime factor of modulus of public key. Easily we can check that
# all four modulus have common prime factors, so all public keys can be factored to their prime factors.
# Hence we can call the `decrypt' function for all key-pairs = (p, pubkey).
PUBKEYS = [(64, 5097817878965528130491999342033509383671964377259616798715086934670476350727067457961522894098176448758455154790088591291492140436888345341524809013526529, 2719656862057675929701181954473487234560053809504182870159883838830483677151615636749895148757512803297431604023949928845798307274620135893628483730370165), (64, 7060901523045984042726080087295157550812603117014135470810146736924359487877594696955935359761087723618432268625961633499242025342993080599272255219826689, 4236820856373471395975112418570159264049442285065614702317560670715324826831495654542690903261317999410969993239143341056856173969712835598894202769388189), (64, 5886668253670710710014305751042288929482573229210648408256360809410689379782338231757686802389194096652696623501426797782671696086916718671567800963694593, 677368525715501885225550495329044026746223906252509513138088716119365842650677326813318891234654722631402944420811717518465312218123608617232162852424170), (64, 6114696543898743304257013154635488204390945532201859491053616049905885027429927049234156928074388068529709328066036749070246579808959041037459892329250817, 1021087898515549606893085024245043948068246289952806903035703154407844021232228744683154236268344854762246167228090127959207385970329548719938322873853549)]
ENC = [1286907403972341066242889039669746312604706856103274344009103676324327972578841290574873287897323982618297132672952263919380020818444548599642494468594665, 1838915271351575639601282561214303786600921537529533284271544284380414309392526991211419383097531042880836480777627616721634975396626109131764273669068589, 1895763364891005946887146248268886690926567718566562720182936733403281150463031165139138495033281798780786067518579648144178418947406635436838517465170080, 865258808401079606933739673880885312400885776434889955425887632635573328068544052188598492574428785517787870375464753706677205587063007358817267526317094]
p1 = GCD(PUBKEYS[0][1], PUBKEYS[3][1])
p2 = GCD(PUBKEYS[0][1], PUBKEYS[2][1])
p3 = GCD(PUBKEYS[1][1], PUBKEYS[2][1])
p4 = GCD(PUBKEYS[1][1], PUBKEYS[3][1])
print('Primes: ')
print(f'p1 = {p1}')
print(f'p2 = {p2}')
print(f'p3 = {p3}')
print(f'p4 = {p4}')
m1 = decrypt((p1, PUBKEYS[0]), ENC[0])
m2 = decrypt((p3, PUBKEYS[1]), ENC[1])
m3 = decrypt((p2, PUBKEYS[2]), ENC[2])
m4 = decrypt((p4, PUBKEYS[3]), ENC[3])
flag = long_to_bytes(m1) + long_to_bytes(m2) + long_to_bytes(m3) + long_to_bytes(m4)
print(b'flag = CCTF{' + flag + b'}')