from sage.all import * MOD = 2**128 t = 16 PR = PolynomialRing(Zmod(MOD), t, names = 'x') xx = [PR.gen(i) for i in range(t)] base_num = 0x6C62272E07BB014262B821756295C58D x = 0x0000000001000000000000000000013B giao = 201431453607244229943761366749810895688 for i in range(t): base_num = base_num * x base_num = base_num+xx[i] f = base_num-giao coe = f.coefficients() M = matrix(ZZ,t+2,t+2) for i in range(t): M[i,i] = 1 M[t,t] = 256 for i in range(t+1): M[i,-1] = coe[i] M[-1,-1] = MOD H = M.LLL() for i in H: if(256 in i): res = i break
base_num = 0x6c62272e07bb014262b821756295c58d x = 0x0000000001000000000000000000013b MOD = 2**128 flag = [] for i in range(len(res)): base_num = (base_num * x) & (MOD - 1) for k in range(256): if((base_num^k)-base_num == res[i]): base_num ^ = k flag.append(k) break ss = '' for i in flag: ss+ = hex(i)[2:].zfill(2) print(ss)
from tqdm import * import math from Crypto.Util.number import * from sage.all import * n = 15428378682808047369729539612849773977351266907005249848551927745179589793201094228559121175032737955878647870160177160397245988513653262495752422128908799243256506605455757248368872726223873708635139946850304152435502570141379286853985364541354685264122339662762441747372478895242822893933897462705436998125064994343778026334193014741078794234731029543321503363519697567486316749015392604019903565484166338202778119436114878787666820006192734321442574905682701228037779919642807430553465725881974172731400277846697398837064840194185750356843931240280984419631010218867389259679817956941531563720176489959565536188397 c = 12311541499004604200236916499349205846427096674314588086510631788926072078719351448646169918289109610507742992745781039518728731071967436965061884458130326005168245432412279626906101863478338683877895019784422395240860608685913496357594241053186169697293064446273562113197595287624822079722824077054648562740537822534033140390319787295623650383968704875832547313466734377262050704021334193507275258922262660647824318306838104067714316000286869379693942751129882040996725977381520370180207186392901674104709320401895811780418145615330784795101228750698014242817456836562876899931370268409067660675018643871717227313658 hint1 = 1642169733436771135664520656142188761411845959348096784398376090505380052495290097851697457504611854584152629529425307316772033432534375461053077627455193773130301015652592603250376477669193772833357092836311168720444956930063724726061060140962165091692267031606422347042905067658647729884255199407653433190610665322919179561630336761190467365 hint2 = 5551747138618727171773321575791733273076756615723885567436415904604966959458490277318362541649129337808802118926493262634763937750210378053453527713899901774935433023207535935321843155751766422374491886434532618700040108440935479135753975555403376309454682833100109181877266998543543846909295860103484771406415217260109315235129296658055184813958169218495709245196271855267640622190375062939285960112201873430002149251649679935167927817626331832294069313328206778 hint1 = hint1+0x114 hint2 = hint2+0x514 def getp(hint1,hint2,n): for x1 in trange(1,2**11): for x2 in range(1,2**11): p = math.gcd(hint2*x1-hint1*x2,n) if(p! = 1): return p p = getp(hint1,hint2,n) q = n//p e = 0x10001 d = inverse(e,(p-1)*(q-1)) flag = b'' flag+ = long_to_bytes(int(pow(c,d,n))) n = 27304780849694423339383484977186266330389425646528065625497565745795638648828062639473996623588698762753146235151108126420977796844428501160763319666798715218447902834612303735177872027008920401294357482031854938125709140433065827081300839613511804160316491491031632730824994184914234660446289671804022045677787702098863099539651943453926045087901898426244698413091456344802150260007283612823928043655412081343588031466645814347820061064753335412269236089640592319528756769313451596405487571315468336477244984077644293384871690534279543863484767904901210496058795440596942630968255014984731155489864246840234667001417 c = 15345714434074055292694048806935544270153104021609550824876952306034067479894701698573290606861629285414856546362924472951947263518612748639904603022632760447886103691397382763388218549691497957562969398205996016066835482973092125604584119551351190484227333681302207328483167508461378264653318581823728471816676463601178380020697690176558636427767120185430857580427504967241695510761471224004993094661089353253222240299229409715246243046129930003638405080254505248363707962924419789835146265839618520569141805792060381649038337877178822148975540522056612034461760014474075882340504541481513970630835462554235470346475 hint1 = 17602174385973044814178733507403094284745791129903364104533711640443330458579716563753178246981073542692332433844902742118325919571150280367606023196267358245762199293741825875527085813095646769963953826540824744879337001014346793390335985309617368648336161014893966160872805800912168191899742324853272847938704487420436610804168779631219370534647095461154552565485779033131497101303042725461524799298270217450073396092439394777919860949842498974276505857076208386972099387042756791993606329357195903926533712694571189872758863613002801173053427969910237331140104634532523474080106045440196525334795994605760965286097 var('p,q') c1 = inverse(hint1,n) f = 514*p - 114*q-c1 g = p * q-n print(solve([f,g],[p,q])) p = 160247203535926288327472656601878781443989033826771766955734470318827419391305327872790796496428041845814802384723559871289959299088000887848984637610216098983438408353121194529852283540070441367798473737141676032568377447595601130840102873781251017230839516821654257824215338216643049472594309958707439106441 q = 170391621489812050399712037637431632018509218121185391060891105777675416473171049932716729939354748557973484195449133496291238596503578305511179199378536936739711381230517911177551655316019732468100928430291180811640657984776088247830397489245305174528823256517954781339979951279712313196947494726049133459137 d = inverse(e,(p-1)*(q-1)) print(flag+long_to_bytes(int(pow(c,d,n)))) #flag{edd3d199-1b37-47ff-94dc-05628985f54d}
from Crypto.Util.number import * from sage.all import * from re import findall from subprocess import check_output from tqdm import * def flatter(M): # compile https://github.com/keeganryan/flatter and put it in $PATH z = "[[" + "]\n[".join(" ".join(map(str, row)) for row in M) + "]]" ret = check_output(["flatter"], input = z.encode()) return matrix(M.nrows(), M.ncols(), map(int, findall(b"-?\\d+", ret))) def decrypt(const, lwe_pubkey2, enc): return (int(enc)-int(const * vector(GF(lwe_ciphertext_modulus), lwe_pubkey2)))%lwe_plaintext_modulus
n = 512 m = n + 100 p = 257 q = next_prime(1048576) c1,c2 = load('/home/martin/code/task3/lwe_ciphertext.sobj') k1,k2 = load('/home/martin/code/task3/lwe_public_key.sobj') pk_A = Matrix(GF(q),k1) pk_b = Matrix(GF(q),k2) encrypt_A = c1 encrypt_b = c2
def pk_Aexpress(pk_A): pkA_1 = pk_A[:512,:] pkA_2 = pk_A[512:,:] ks = [] for row in pkA_2: ks.append(pkA_1.solve_left(row)) return Matrix(ZZ,ks)
def fuck(A,pk_A): c_tmp = pk_A.solve_left(A)[:-100] tmpks = pk_Aexpress(pk_A) ks = tmpks[:,:100] ks = ks.stack(Matrix(ZZ,[c_tmp[:100]])) M = Matrix(ZZ,100 + 100 + 1,100 + 100 + 1) M[:101,:101] = identity_matrix(101) M[:101,101:] = ks[:,:100] M[101:,101:] = q * identity_matrix(100) ML = flatter(M) rows = ML[0] c_new = [0 for i in range(612)] c_list = Matrix(ZZ,Matrix(GF(q),rows[:100]*tmpks) + Integer(rows[100]) * Matrix(GF(q),c_tmp))[0] for _ in range(512): if c_list[_] == q-1: c_new[_] = -1 else: c_new[_] = int(c_list[_]) for _ in range(100): if rows[_] == q-1: c_new[_+512] = -1 else: c_new[_+512] = int(rows[_])
return c_new
flag = '' for _ in trange(len(encrypt_A)): A = vector(GF(q),encrypt_A[_]) b = encrypt_b[_] c_new = fuck(A,pk_A)
c_first = c_new[:512] c_secon = c_new[512:]
c = vector(ZZ, c_first+c_secon) if c*pk_A ! = A: c_first = [-i for i in c_first] c = vector(ZZ, c_first+c_secon)
if c*pk_A ! = A: c_first = [-i for i in c_first] c_secon = [-i for i in c_secon] c = vector(ZZ, c_first+c_secon)
if c*pk_A ! = A: c_first = [-i for i in c_first] c = vector(ZZ, c_first+c_secon) # print(c*pk_A == A) s = vector(GF(q),c) flag+ = chr(decrypt(s,k2,encrypt_b[_])) print(flag) #a3bc5491-fa53-4f47
K1 = matrix(ZZ, k1) K2 = vector(ZZ, k2) K1r = K1.change_ring(RDF) K2r = K2.change_ring(RDF) sk = K1r.solve_right(K2r) sk = vector(GF(lwe_ciphertext_modulus), [round(x) forxinsk]) flag = []
for tmp1, tmp2 in zip(*lwe_ciphertext): T1 = vector(GF(lwe_ciphertext_modulus), tmp1) m = ZZ(tmp2 - T1 *sk) if m > = lwe_ciphertext_modulus // 2: m - = lwe_ciphertext_modulus m = m % lwe_plaintext_modulus flag1.append(m) print(bytes(flag1))
对于flag的第二部分
这个是在一个RLWE问题,在商环f下我们有$b = a * s + e$,e就是一个噪声,所以对于这个题思路很简单就是构造一个关于a,b的格直接格规约即可,但是由于是在商环上进行的,我们需要处理多项式的乘法和模就可以成功构造格,还原flag了。
from Crypto.Util.number import * from sage.all import * from re import findall from subprocess import check_output def flatter(M): # compile https://github.com/keeganryan/flatter and put it in $PATH z = "[[" + "]\n[".join(" ".join(map(str, row)) for row in M) + "]]" ret = check_output(["flatter"], input = z.encode()) return matrix(M.nrows(), M.ncols(), map(int, findall(b"-?\\d+", ret))) a, b, f, rlwe_modulus = load('/home/martin/code/task3/rlwe_ciphertext.sobj') n = 64 A = a B = b.list() p = rlwe_modulus def construct_poly_mul_mat(n,v,b): assert v[-1] == 1 mat1 = Matrix(ZZ,n,2*n-1) for i in range(n): for j in range(n): mat1[i,j+i] = b[j] mat2 = Matrix(ZZ,2*n-1,n) for i in range(n): mat2[i,i] = 1 for i in range(n,2*n-1): for j in range(i-n,n): mat2[i,j] = -v[j-(i-n)]
init_row = vector(ZZ,n*[0]) for j in range(i-n): temp = -v[n-1-j]*vector(ZZ,mat2[i-j-1]) init_row + = temp for j in range(n): mat2[i,j] + = init_row[j] return(mat1*mat2)
v = f.list() poly_mul_mat = construct_poly_mul_mat(n,v,A)
I = identity_matrix(n) B_mat = Matrix(ZZ,B) O = diagonal_matrix([0]*n) O_vec = Matrix(ZZ,1,n) O_vec_T = Matrix(ZZ,n,1) L = block_matrix(ZZ,[[p*I,O,0],[poly_mul_mat,I,O_vec_T],[B_mat,O_vec,1]])
res = flatter[L](0)
s = res[n:2*n] for i in s: print(chr(abs(i)),end = "") # -8819-856a8fe5ada0 # flag{a3bc5491-fa53-4f47-8819-856a8fe5ada0}
res = [] for i in range(1,26): res.append(N[i]-N[0]) m = matrix(ZZ,25,25) for i in range(1,25): m[0,i] = res[i] m[i,i] = -res[0] m[0,0] = 2**(704*2) H = m.LLL() for i in H: if(i[0]%2**(704*2) == 0): d = i[0]//(2**(704*2)) if(res[0]%d == 0): d = abs(d) pq = (res[0]//d-d) print(pq) break var('p q') f = p*q-N[0] g = p+q-pq solution = solve([f,g],[p,q]) # p,q p = p>>282 q = q>>282 d = [] for i in res: d.append(iroot[i%pq,2](0))
from random import getrandbits from sage.all import * from pwn import * from gmpy2 import iroot from extend_mt19937_predictor import ExtendMT19937Predictor from re import findall from subprocess import check_output def flatter(M): # compile https://github.com/keeganryan/flatter and put it in $PATH z = "[[" + "]\n[".join(" ".join(map(str, row)) for row in M) + "]]" ret = check_output(["flatter"], input = z.encode()) return matrix(M.nrows(), M.ncols(), map(int, findall(b"-?\\d+", ret))) while(1): r = remote('', '') s = r.recvuntil(b'N = ') N = eval(r.recvuntil(b']').decode()) res = [] for i in range(1,26): res.append(N[i]-N[0]) m = matrix(ZZ,25,25) for i in range(1,25): m[0,i] = res[i] m[i,i] = -res[0] m[0,0] = 2**(704*2) H = flatter(m) for i in H: if(i[0]%2**(704*2) == 0): d = i[0]//(2**(704*2)) if(res[0]%d == 0): d = abs(d) pq = (res[0]//d-d) break p,q = var('p,q') f = p*q-N[0] g = p+q-pq solution = solve([f,g],[p,q]) s = str(solution[0]).split(' == ') p = eval(s[1].split[','](0)) q = eval(s[2].split[']'](0)) p = p>>282 q = q>>282 d = [] print('getpq!!') for i in res: d.append(iroot[i%pq,2](0)) rc = ExtendMT19937Predictor() sub = '' sub+ = bin[p](2:).zfill(1184) sub+ = bin[q](2:).zfill(1184) for i in d: sub+ = bin[i](2:).zfill(704) for i in range(78): c = int(sub[i:i+256],2) rc.setrandbits(c,256) for _ in range(78): s = rc.backtrack_getrandbits(256) m = rc.backtrack_getrandbits(256) s = r.recvuntil(b'm: ') r.sendline(str(m).encode()) s = r.recvuntil(b'sinature = ') sig = r.recvuntil[b'\n'](:-1) s = r.recvuntil(b'signatures: ') sig = b"['"+sig+b"']" r.sendline(sig) flag = r.recv() if(b'}' in flag): print(flag) break r.close()