p = 65211247300401312530078141569304950676358489059623557848188896752173856845051471066071652073612337629832155846984721797768267868868902023383604553319793550396610085424563231688918357710337401138108050205457200940158475922063279384491022916790549837379548978141370347556053597178221402425212594060342213485311 g = 27642593390439430783453736408814717946185190497201679721975757020767271070510268596627490205095779429964809833535285315202625851326460572368018875381603399143376574281200028337681552876140857556460885848491160812604549770668188783258592940823128376128198726254875984002214053523752696104568469730021811399216 h = 54585833166051670245656045196940486576634589000609010947618047461787934106392112227019662788387352615714332234871251868259282522817042504587428441746855906297390193418159792477477443129333707197013251839952389651332058368911829464978546505729530760951698134101053626585254469108630886768357270544236516534904
l = (p - 1) % (e**2) // e a = -libnum.invmod(l, e) % e returnpow(x, (1 + a * (p - 1) // e) // e, p)
deffindAllPRoot(p, e): print("Start to find all the Primitive {:#x}th root of 1 modulo {}.".format(e, p)) start = time.time() proot = set() whilelen(proot) < e: proot.add(pow(random.randint(2, p-1), (p-1)//e, p)) end = time.time() print("Finished in {} seconds.".format(end - start)) return proot
deffindAllSolutions(mp, proot, cp, p, e): print("Start to find all the {:#x}th root of {} modulo {}.".format(e, cp, p)) start = time.time() all_mp = set() for root in proot: mp2 = mp * root % p #print('debug -> %d' % pow(root, e3, p)) assert(pow(mp2, e, p) == cp) all_mp.add(mp2) end = time.time() print("Finished in {} seconds.".format(end - start)) return all_mp
e = A-1 e2 = libnum.gcd(e, p-1) m2 = eth_root(ma, e2, p) e3 = e // e2 assertpow(m2, e2, p) == ma
proot = findAllPRoot(p, e2) ms = findAllSolutions(m2, proot, ma, p, e2) d2 = libnum.invmod(e3//2, p-1) for m3 in ms: ifpow(m3, (p-1)//2, p) != 1: # QR continue m = pow(m3, (p+1)//4, p) # 2-root m = pow(m, d2, p) # normal RSA assertpow(m, e, p) == ma flag = libnum.n2s(int(m)) #if b'{' in flag and b'}' in flag: ifb'flag'in flag: print(flag) # b'flag{19e9f185e6a680324cedd6e6d9382743}'