a = 259416965926853287275013962386631097709 n = 8963244108103857378610478915798540027754205184635651624801332901515870452435977078824267979279218575027152343028911705254378598817260939339516835322386427 gy = [1896722249337161391193797083807118705857637064141055866260977430130447249097804719101078827699386498665026965515554644281163046869672493999194358926022865, 1971472878970365404484102034878792535366624572891039926216530789642810299559238977732710681752685090332485586910206690093655977703795335533365202958013518, 4074555112002157403114317690671003025383051142150876016519408756236925988856478235258960189636836867363451314784889114354880607055705753428890566240606935] e = 24 t = bytes_to_long(b'N1Junior_CheckIn')
flag = n - 8963244108103857378610473916499685337958102994866002007958751917348709988813159260063838668865808163331396353132849773965877550546775678652844675901977223 print(long_to_bytes(flag))
gift = b'yX~\xe1\xd3\xe7\xcdw_)/G\xdc\x0er\x18\xc0\xb2\xc1sKv\xd4\x857\x94D\xf91\xc2\x98\x873\x8bG\xc3hG\xbbC\x98\x16e\xe8\x11C\n\x04' block_size = 16 date = bytes_to_long(b'2023-1-31 10:00')
deffast_func(init,time): for i inrange(0, 16, 4): tmp = vector(R2,list(map(convert_to_vec,[init[i],init[i+1],init[i+2],init[i+3]]))) final = (poly_matrix^(time))*tmp for j in final: temp = list(map(str,list(j)[::-1])) print(chr(int("".join(temp),2)),end = "")
for i inrange(0, len(gift), block_size): block = gift[i:i+block_size] fast_func(block, date)
from Crypto.Util.number import * from secret import flag
m = bytes_to_long(flag)
defget_params(nbits): p = getPrime(nbits) q = getPrime(nbits // 2) r = getPrime(nbits // 2) if q < r: q, r = r, q e = 2023 + 666 n = p * q * r phi = (p-1) * (q-1) * (r-1) d = inverse(e, phi) return e, n, d, p, q, r
defmagic_process(dqr_): # only the correct data can pass this magic process! w = 11805048190103811318745740902058585490581588391715507077469771342521346595744141604699124341571677599846725074544467374849004088341619160922679491419964725 x = dqr_ + 666 y = dqr_ + 667 PR.<z> = PolynomialRing(ZZ) f = w*(x*z+y*z-x*y) - 4*x*y*z z = f.roots()[0][0]
''' e = 2689 qr = 47039394845246457267451844933135300719863788804596821520575305333413876649846 n = 102275105641047314957681561255971730180031931453885390971560104545784846810054168298038033889926837832908913447331571300831232278972182034546312860462560455575699889259884894407503661740178853200384106267596198200388045685183747251883536380886761864997738495990864526497955511125021398766971363828732464588761 c = 30057873321817268990724095993213394773233077509126537130493293224220768053789109305889627009912877888765075963369699610910695123551381348483962929764830148523075698671087735427795008522625385598116705013490990766089416767372146754468746664865469005120853463146265400060202176870467493380590559736303051981581 '''
from Crypto.Util.number import * from tqdm import *
e = 2689 qr = 47039394845246457267451844933135300719863788804596821520575305333413876649846 n = 102275105641047314957681561255971730180031931453885390971560104545784846810054168298038033889926837832908913447331571300831232278972182034546312860462560455575699889259884894407503661740178853200384106267596198200388045685183747251883536380886761864997738495990864526497955511125021398766971363828732464588761 c = 30057873321817268990724095993213394773233077509126537130493293224220768053789109305889627009912877888765075963369699610910695123551381348483962929764830148523075698671087735427795008522625385598116705013490990766089416767372146754468746664865469005120853463146265400060202176870467493380590559736303051981581
#part1 get dqr_ w = 11805048190103811318745740902058585490581588391715507077469771342521346595744141604699124341571677599846725074544467374849004088341619160922679491419964725 k = (w-1)//2 x = k y = k+1 z = k*(k+1)*(2*k+1) assert w*(x*z+y*z-x*y) - 4*x*y*z == 0 dqr_ = x-666
#part2 get dqr(use copper) if(0): for tt inrange(4): for k in trange(1,e): PR.<delta> = PolynomialRing(Zmod(n)) f = e*(dqr_+2^3*delta+2*tt+1) - 1 - k*(1+qr) f = f.monic() res = f.small_roots(X=2^52,beta=0.25,epsilon=0.01) if(res != []): print(tt,k,res) #0 2046 [2593202029823482] break dqr = dqr_ + 2^3*2593202029823482 + 2*0 + 1 k = 2046
#part3 factor n if(0): PR.<r> = PolynomialRing(ZZ) f = e*dqr - 1 - k*(r+qr-1)*(r-1) res = f.roots() print(res) r = 67643325987256775010724943844390543569531594444330008512848332012702093716653 q = r + qr p = n // q // r
#part4 get flag phi = (p-1)*(q-1)*(r-1) d = inverse(e,phi) flag = pow(c,d,n) print(long_to_bytes(int(flag)))
import random from Crypto.Util.number import * from secret import flag
assert flag[:8]==b'secpunk{'and flag[-1:]==b'}' flag = flag[8:-1] m = bytes_to_long(flag)
p = getPrime(200) a = random.randint(0, p-1)
whileTrue: b = random.randint(0, p-1) E = EllipticCurve(Zmod(p), [a, b]) if isPrime(E.order()): break Ga = E.gens()[0] gift = bytes_to_long(b'N1CTF Junior') random.seed(gift)
G = [] for i inrange(80): r = random.randint(0,p-1) G.append(tuple((r ^^ m)*Ga)[:-1]) for i inrange(60): r = random.randint(0,p-1) G.append(tuple((r & m)*Ga)[:-1]) for i inrange(60): r = random.randint(0,p-1) G.append(tuple((r | m)*Ga)[:-1]) f = open('output.txt','w') f.write("Ga = "+str(tuple(Ga)[:-1])+"\n") f.write("G = "+str(G))
import random import time from functools import reduce
f = open("output.txt",'r') f.read(5) Ga = eval(f.readline()) f.read(4) G = eval(f.readline())
PR.<a,b> = PolynomialRing(ZZ) polys = []
for i inrange(4): x, y = G[i] polys.append(x*a+b+(x^3-y^2))
gb = Ideal(polys).groebner_basis() p = gb[-1] a = -gb[0].coefficients()[-1]%p b = -gb[1].coefficients()[-1]%p
E=EllipticCurve(Zmod(p),[a, b]) Ga=E(Ga)
defxormat(r, P): mask = 1 v = [] for i inrange(200): if r & mask == 0: v.append(1) else: v.append(-1) P = P-mask*Ga mask = mask << 1 return v, P
defandmat(r, P): mask = 1 v = [] for i inrange(200): if r & mask == 0: v.append(0) else: v.append(1) mask = mask << 1 return v, P
deformat(r, P): mask = 1 v = [] for i inrange(200): if r & mask == 0: v.append(1) else: v.append(0) P = P-mask*Ga mask = mask << 1 return v, P L = [] R = [] random.seed(int.from_bytes(b'N1CTF Junior', 'big'))
print("===construct matrix begin===") start = time.time() for i inrange(80): rn = random.randint(0,p-1) Q = E(G[i]) v, P = xormat(rn, Q) L.append(v) R.append(P) for i inrange(80,140): rn = random.randint(0,p-1) Q = E(G[i]) v, P = andmat(rn, Q) L.append(v) R.append(P) for i inrange(140,200): rn = random.randint(0,p-1) Q = E(G[i]) v, P = ormat(rn, Q) L.append(v) R.append(P) print("===construct matrix end===") end = time.time() print("cost {}s".format(end-start))
q = E.order() L = Matrix(Zmod(q), L) m = '' O = 0*Ga for i inrange(200): u = vector(Zmod(q),[0]*i+[1]+[0]*(199-i)) coeff = L.solve_left(u).change_ring(ZZ) S = 0*Ga for i inrange(200): S += coeff[i]*R[i] if S == O: m = '0'+m else: m = '1'+m
from errorcc_output import * import random from Crypto.Util.number import * from tqdm import *
#part1 groebner to get a,b,p if(0): PR.<a,b> = PolynomialRing(ZZ) F = [] for i inrange(4): f = G[i][1]^2-G[i][0]^3-a*G[i][0]-b F.append(f) res = Ideal(F).groebner_basis() print(res) p = 1287829304049714244524067710692915105281415000125398093331471 a = p-225347669189365890161624438870935953357140181565885210886229 b = p-270712467434746420425713635322490969521436540014940033725570 E = EllipticCurve(Zmod(p),[a,b]) ord = E.order() Ga = E(Ga) for i inrange(len(G)): G[i] = E(G[i])
#part2 construct L gift = bytes_to_long(b'N1CTF Junior') random.seed(gift) L = Matrix(Zmod(ord),200,200) P = []
## 2.1 xor for i in trange(80): ri = random.randint(0,p-1) temp = bin(ri)[2:].zfill(200)[::-1] tempG = G[i] for j inrange(len(temp)): if(temp[j] == "0"): L[i,j] = 1 else: L[i,j] = -1 tempG -= 2^j*Ga P.append(tempG)
## 2.2 and for i in trange(80,140): ri = random.randint(0,p-1) temp = bin(ri)[2:].zfill(200)[::-1] tempG = G[i] for j inrange(len(temp)): if(temp[j] == "0"): L[i,j] = 0 else: L[i,j] = 1 P.append(tempG)
## 2.3 or for i in trange(140,200): ri = random.randint(0,p-1) temp = bin(ri)[2:].zfill(200)[::-1] tempG = G[i] for j inrange(len(temp)): if(temp[j] == "0"): L[i,j] = 1 else: L[i,j] = 0 tempG -= 2^j*Ga P.append(tempG)
#part3 bit by bit to recover flag flag = "" O = 0*Ga for i in trange(200): u = vector(Zmod(ord),[0]*i + [1] + [0]*(199-i)) temp = L.solve_left(u) S = O for j inrange(len(temp)): S += int(temp[j])*P[j] if(S == O): flag += "0" else: flag += "1" print(long_to_bytes(int(flag[::-1],2)))
#secpunk{f4ult_1nj3cti0n~p0werfu1!}
很巧妙的思路,类似的就可以把这个解法也拓展到N1CTF的e2dlp上,虽然都是bit by bit求但是还是有细微差别。