from Crypto.Util.number import *
import random
import base64
import os
flag = b'xxx'
flag = base64.b64encode(flag)
part_size = len(flag)//3
part1 = flag[:part_size]
part2 = flag[part_size:2 * part_size]
part3 = flag[2 * part_size:]
def gen_keys(bits):
while True:
p = getPrime(bits)
q = getPrime(bits)
n = p * q
k = random.randint(1, n)
if pow(q ** 2 * k, (p - 1) // 2, p) + pow(p ** 2 * k, (q - 1) // 2, q) == p + q - 2:
break
return p, q, n, k
def bit_enc(m,n):
enc = []
m = bin(bytes_to_long(m))[2:]
for x in m:
while True:
r = random.randint(1, n)
if GCD(r, k) == 1:
enc.append((k ** int(x) * r ** 2) % n)
break
return enc
if __name__ == '__main__':
f = open('stepbystep.txt','w')
f.write(f'part_size = {part_size}\n') # 32
p, q, n, k = gen_keys(1024)
y = p ^ (bytes_to_long(part1) << 0x100)
f.write(f'n = {n}\n')
f.write(f'y = {y}\n')
enc1 = bit_enc(part2,n)
f.write(f'enc1 = {enc1}\n')
e = 3
r = getPrime(1024)
m = bytes_to_long(part3 + os.urandom(128))
M = m % r
f.write(f'r = {r}\n')
f.write(f'M = {M}\n')
enc2 = pow(m, e, n)
f.write(f'enc2 = {enc2}\n')
n = 28170615394813994128829444311922294768047711140557403853945487107089509134737767942656361548230221829951460844271639575394883663959935517401286468610803533794281322932272016151070004303694003064267127894498582758474889399072435632149814773794006700377495059535551601562497404157228212268055301420382159240876926718366155907065534007141933306379265213201601388196980959461243178574169497366868119687674891554278269534759630337252574501733517956676373291013127781435489132751470026441547613876124640645867844110455115246109355929378020562498143759261535211073747144498765678339037517382156239422037334011910477313579931
y = 159220553107177193400023378107257900962478698517628796905876914005522464561698874246291191230998317763194901894991385290134307075261722076436131488895536910117912445041560442858379826501161163372467275224931272546634069502187842680578039864204499755434023932362315829340273816781101788682876410192428287564079
p_ = ((y >> 512) << 512) + (y & (2 ^ 256 - 1))
PR.<x> = PolynomialRing(Zmod(n))
f = p_ + (x * 2 ** 256)
f = f.monic()
p0 = f.small_roots(2 ^ 256,0.4)
print(p_ + p0[0] * 2 ** 256)
p = 159220553107177193400023378107257900962478698517628796905876914005522464561698874246291191230998317763194901894991385290134307075261722076436131488895536914601862873373189346623370102585921882621795643375613240095719969918295959844527488766867194677670844144950629130942802580496956921624007957883073349196079
part1 = ((y // 2 ** 256) % 2 ** 256) ^^ ((p // 2 ** 256) % 2 ** 256)
print(long_to_bytes(part1))
# ZmxhZ3s4ZjYzNzc3MTMyZWRkNmJlNmM2
with open('stepbystep.txt') as f:
exec(f.read())
part2 = ''
for i in enc1:
if pow(i,(p-1)//2,p) == 1:
part2 += '0'
else:
part2 += '1'
part2 = int(part2,2)
print(long_to_bytes(part2))
# Yjg4NGQyMTEyMjI5YWI2OWEwYjNkOTgz