from Crypto.Util.number import * from pwn import *
sh = remote("node4.anna.nssctf.cn",28552)
#part1 construct division of number defconstruct_set(n): setlist = [[] for i inrange(11)] for i inrange(n): for j inrange(len(setlist)): Issame = 0 if(len(setlist[j]) < 20): for k in setlist[j]: if(pow(i,2,n) == pow(k,2,n) orpow(i,2,n) == pow(k,2,n)-1orpow(i,2,n) == pow(k,2,n)+1): Issame = 1 if(Issame == 0): setlist[j].append(i) break while([] in setlist): setlist=setlist[:-1] return setlist n = 127 setlist = construct_set(n)
#part2 send set by set and get flag K = [] for i inrange(len(setlist)): ans = setlist[i] sh.sendline(str(ans)[1:-1].encode()) sh.recvuntil(b"DID = ") did = eval(sh.recvline().strip().decode()) if(len(did) != len(ans)): for j in ans: if(pow(j,2,n) notin did andpow(j,2,n)+1notin did): K.append(j)
#part1 bruteforce to factor n for nl in trange(2**7): n = nh + 2*nl + 1
f = FactorDB(n) f.connect() fs = f.get_factor_list() if(len(fs) == 2): p = fs[0] q = fs[1] if(isPrime(p) and isPrime(q) andlen(bin(p)[2:]) == 128): phi = (p-1)*(q-1) break
#part2 bruteforce c,e for el in trange(2**7): e = eh + 2*el + 1 if(not isPrime(e)): continue for cl inrange(2**8): try: c = ch + cl d = invert(e,phi) flag = long_to_bytes(pow(c,d,n)).decode() print(flag) except: pass
defgen_seed(s): i, j, k = 0, len(s), 0 while i < j: k = k + ord(s[i]) i += 1 i = 0 while i < j: if (i % 2) != 0: k = k - (ord(s[i]) * (j - i + 1)) else: k = k + (ord(s[i]) * (j - i + 1)) k = k % 2147483647 i += 1
k = (k * j) % 2147483647 return k
defreseed(s): return s * 214013 + 2531011
defencrypt(s, msg): assert s <= 2**32 c, d = 0, s enc, l = b'', len(msg) while c < l: d = reseed(d) enc += (msg[c] ^ ((d >> 16) & 0xff)).to_bytes(1, 'big') c += 1 return enc
mod = 2**24 for seed in trange(2**24): s = seed flag = "" for i in range(len(enc)): s = (s*214013+2531011)%(mod) flag += chr(enc[i] ^ ((s>>16)&0xff)) if("CCTF" in flag): print(flag)
#CCTF{__B4ck_0r!F1c3__C1pHeR_!!}
medium
Derik
题目:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#!/usr/bin/env python3
from Crypto.Util.number import * from secret import C, e, d, p, q, r, flag
O = [1391526622949983, 2848691279889518, 89200900157319, 31337]
assert isPrime(e) and isPrime(d) and isPrime(p) and isPrime(q) and isPrime(r) assert C[0] * p - C[1] * q >= 0 assert C[2] * q - C[3] * r >= 0 assert C[4] * r - C[5] * p >= 0 assert (C[0] * p - C[1] * q) ** e + (C[2] * q - C[3] * r) ** e + (C[4] * r - C[5] * p) ** e == d * (C[0] * p - C[1] * q) * (C[2] * q - C[3] * r) * (C[4] * r - C[5] * p) assert C[6] * e - C[7] * d == O[3]
n = e * d * p * q * r m = bytes_to_long(flag) c = pow(m, 65537, n) print(f'C = {C}') print(f'c = {c}')
O = [1391526622949983, 2848691279889518, 89200900157319, 31337] C = [5960650533801939766973431801711817334521794480800845853788489396583576739362531091881299990317357532712965991685855356736023156123272639095501827949743772, 6521307334196962312588683933194431457121496634106944587943458360009084052009954473233805656430247044180398241991916007097053259167347016989949709567530079, 1974144590530162761749719653512492399674271448426179161347522113979158665904709425021321314572814344781742306475435350045259668002944094011342611452228289, 2613994669316609213059728351496129310385706729636898358367479603483933513667486946164472738443484347294444234222189837370548518512002145671578950835894451, 8127380985210701021743355783483366664759506587061015828343032669060653534242331741280215982865084745259496501567264419306697788067646135512747952351628613, 5610271406291656026350079703507496574797593266125358942992954619413518379131260031910808827754539354830563482514244310277292686031300804846114623378588204, 10543, 4] c = 80607532565510116966388633842290576008441185412513199071132245517888982730482694498575603226192340250444218146275844981580541820190393565327655055810841864715587561905777565790204415381897361016717820490400344469662479972681922265843907711283466105388820804099348169127917445858990935539611525002789966360469324052731259957798534960845391898385316664884009395500706952606508518095360995300436595374193777531503846662413864377535617876584843281151030183895735511854
#part1 get e,d if(1): for e inrange(1000000): if((C[6]*e-O[3])%C[7]==0): d = (C[6]*e-O[3])//C[7] if(isPrime(d)): print(e,d) break #e,d = 3,73
#part2 construct ECC to get a solution of X^3+Y^3+Z^3=73XYZ R.<x,y,z> = QQ[] cubic = x^3 + y^3 + z^3 - 73*x*y*z P = [1,-1,0] E = EllipticCurve_from_cubic(cubic, P, morphism=False) f = EllipticCurve_from_cubic(cubic, P, morphism=True) finv = f.inverse() R = E.gens()[0] PP = f(P) print(finv(R)) #find solution of original equation
defmul_barak(m, P, E): if P == (0, 0): return P R = (0, 0) while m != 0: if m & 1: R = add_barak(R, P, E) m = m >> 1 if m != 0: P = add_barak(P, P, E) return R
defrand_barak(E): c, d, p = E whileTrue: y = randint(1, p - 1) K = Zmod(p) P.<x> = PolynomialRing(K) f = x**3 - d*x*y + c + y^3 R = f.roots() try: r = R[0][0] return (r, y) except: continue
p = 73997272456239171124655017039956026551127725934222347 d = 68212800478915688445169020404812347140341674954375635 c = 1 E = (c, d, p)
P = rand_barak(E)
FLAG = flag.lstrip(b'CCTF{').rstrip(b'}') m = bytes_to_long(FLAG) assert m < p Q = mul_barak(m, P, E) print(f'P = {P}') print(f'Q = {Q}')
p = 73997272456239171124655017039956026551127725934222347 d = 68212800478915688445169020404812347140341674954375635 c = 1 P = (71451574057642615329217496196104648829170714086074852, 69505051165402823276701818777271117086632959198597714) Q = (40867727924496334272422180051448163594354522440089644, 56052452825146620306694006054673427761687498088402245)
#part1 construct ECC to get a solution of X^3+Y^3+Z^3=dXYZ R.<x,y,z> = Zmod(p)[] cubic = x^3 + y^3 + z^3 - d*x*y*z E = EllipticCurve_from_cubic(cubic,morphism=True) P = E(P) Q = E(Q) m = P.discrete_log(Q) P_ord = P.order()
for i inrange(10000): try: flag = long_to_bytes(int(m)).decode() print(flag) except: m += P_ord
from Crypto.Util.number import * from secret import m, flag
defgenPrime(m, nbit): assert m >= 2 whileTrue: a = getRandomNBitInteger(nbit // m) r = getRandomNBitInteger(m ** 2 - m + 2) p = a ** m + r if isPrime(p): return (p, r)
defgenkey(m, nbit): p, r = genPrime(m, nbit // 2) q, s = genPrime(m, nbit // 2) n = p * q e = r * s return (e, n)
defencrypt(msg, pkey): e, n = pkey m = bytes_to_long(msg) c = pow(m, e, n) return c
from Crypto.Util.number import * from gmpy2 import *
e,n = (150953688, 373824666550208932851344358703053061405262438259996622188837935528607451817812480600479188884096072016823491996056842120586016323642383543231913508464973502962030059403443181467594283936168384790367731793997013711256520780338341018619858240958105689126133812557401122953030695509876185592917323138313818881164334490044163316692588337720342646339764174333821950301279825316497898035760524780198230860089280791887363472060435443944632303774987556026740232641561706904946900169858650106994947597642013168757868017723456208796677559254390940651802333382820063200360490892131573853635471525711894510477078934343423255983) c = 275574424285842306309073814038154403551700455145115884031072340378743712325975683329051874910297915882286569143815715537085387363420246497061870251520240399514896001311724695996978111559476733709139080970977190150345474341853495386364275702356438666152069791355990718058189043717952080875207858163490627801836274404446661613239167700736337269924479349700031535265765885064606399858172168036794462235707003475360358004643720927563261787867952228496769300443415094124132722170498229611285689671203272698693505808912907778910378274197503048226322090611405601517624884408718689404556983397217070272851442351897456769883
#part1 factor n a1a2 = iroot(n,4)[0] #n=(a1^4+r)(a2^4+s) #t1=sa1^4,t2=ra2^4 #use Vieta theorem t1_t2 = n - e - a1a2**4 t1t2 = e*a1a2**4 delta = t1_t2**2-4*t1t2 t1 = (t1_t2+iroot(delta,2)[0])//2 t2 = (t1_t2-iroot(delta,2)[0])//2
for s inrange(1,2**14,2): if(iroot(t1//s,4)[1]): a1 = iroot(t1//s,4)[0] r = e // s a2 = iroot(t2//r,4)[0] break
p = a1**4+r q = a2**4+s
#part2 get flag cq = pow(c,inverse(e//72,q-1),q) PR.<x> = PolynomialRing(Zmod(q)) f = x^72 - cq resq = f.roots() for i in resq: print(long_to_bytes(int(i[0])))
from Crypto.Util.number import * from pyope.ope import OPE as enc from pyope.ope import ValueRange import sys from secret import key, flag
defdie(*args): pr(*args) quit()
defpr(*args): s = " ".join(map(str, args)) sys.stdout.write(s + "\n") sys.stdout.flush()
defsc(): return sys.stdin.buffer.readline()
defencrypt(msg, key, params): iflen(msg) % 16 != 0: msg += (16 - len(msg) % 16) * b'*' p, k1, k2 = params msg = [msg[_*16:_*16 + 16] for _ inrange(len(msg) // 16)] m = [bytes_to_long(_) for _ in msg] inra = ValueRange(0, 2**128) oura = ValueRange(k1 + 1, k2 * p + 1) _enc = enc(key, in_range = inra, out_range = oura) C = [_enc.encrypt(_) for _ in m] return C
defmain(): border = "|" pr(border*72) pr(border, " Welcome to Roldy combat, we implemented an encryption method to ", border) pr(border, " protect our secret. Please note that there is a flaw in our method ", border) pr(border, " Can you examine it and get the flag? ", border) pr(border*72)
from Crypto.Util.number import * from pwn import * from tqdm import *
sh = remote("node4.anna.nssctf.cn",28724) sh.recvuntil(b"Generating parameters, please wait...")
#part1 get flag_enc sh.sendline(b"e") sh.recvuntil(b"params) = ") C = eval(sh.recvline().strip().decode())
#part2 binary_search for i inrange(len(C)): left = 0 right = 2**128 for j in trange(128): temp = (left+right)//2 sh.recvuntil(b"[Q]uit") sh.sendline(b"t") sh.recvuntil(b"Please send your message to encrypt: ") sh.sendline(long_to_bytes(temp)) sh.recvuntil(b"C = ") ans = eval(sh.recvline().strip().decode())[0] if(abs(ans - C[i]) <= 1): print(long_to_bytes(temp)) break if(ans < C[i]): left = temp else: right = temp
""" Setting debug to true will display more informations about the lattice, the bounds, the vectors... """ debug = True
""" Setting strict to true will stop the algorithm (and return (-1, -1)) if we don't have a correct upperbound on the determinant. Note that this doesn't necesseraly mean that no solutions will be found since the theoretical upperbound is usualy far away from actual results. That is why you should probably use `strict = False` """ strict = False
""" This is experimental, but has provided remarkable results so far. It tries to reduce the lattice as much as it can while keeping its efficiency. I see no reason not to use this option, but if things don't work, you should try disabling it """ helpful_only = True dimension_min = 7# stop removing if lattice reaches that dimension
# display stats on helpful vectors defhelpful_vectors(BB, modulus): nothelpful = 0 for ii inrange(BB.dimensions()[0]): if BB[ii,ii] >= modulus: nothelpful += 1
print (nothelpful, "/", BB.dimensions()[0], " vectors are not helpful")
# display matrix picture with 0 and X defmatrix_overview(BB, bound): for ii inrange(BB.dimensions()[0]): a = ('%02d ' % ii) for jj inrange(BB.dimensions()[1]): a += '0'if BB[ii,jj] == 0else'X' if BB.dimensions()[0] < 60: a += ' ' if BB[ii, ii] >= bound: a += '~' print (a)
# tries to remove unhelpful vectors # we start at current = n-1 (last vector) defremove_unhelpful(BB, monomials, bound, current): # end of our recursive function if current == -1or BB.dimensions()[0] <= dimension_min: return BB
# we start by checking from the end for ii inrange(current, -1, -1): # if it is unhelpful: if BB[ii, ii] >= bound: affected_vectors = 0 affected_vector_index = 0 # let's check if it affects other vectors for jj inrange(ii + 1, BB.dimensions()[0]): # if another vector is affected: # we increase the count if BB[jj, ii] != 0: affected_vectors += 1 affected_vector_index = jj
# level:0 # if no other vectors end up affected # we remove it if affected_vectors == 0: print ("* removing unhelpful vector", ii) BB = BB.delete_columns([ii]) BB = BB.delete_rows([ii]) monomials.pop(ii) BB = remove_unhelpful(BB, monomials, bound, ii-1) return BB
# level:1 # if just one was affected we check # if it is affecting someone else elif affected_vectors == 1: affected_deeper = True for kk inrange(affected_vector_index + 1, BB.dimensions()[0]): # if it is affecting even one vector # we give up on this one if BB[kk, affected_vector_index] != 0: affected_deeper = False # remove both it if no other vector was affected and # this helpful vector is not helpful enough # compared to our unhelpful one if affected_deeper andabs(bound - BB[affected_vector_index, affected_vector_index]) < abs(bound - BB[ii, ii]): print ("* removing unhelpful vectors", ii, "and", affected_vector_index) BB = BB.delete_columns([affected_vector_index, ii]) BB = BB.delete_rows([affected_vector_index, ii]) monomials.pop(affected_vector_index) monomials.pop(ii) BB = remove_unhelpful(BB, monomials, bound, ii-1) return BB # nothing happened return BB
""" Returns: * 0,0 if it fails * -1,-1 if `strict=true`, and determinant doesn't bound * x0,y0 the solutions of `pol` """ defboneh_durfee(pol, modulus, mm, tt, XX, YY): """ Boneh and Durfee revisited by Herrmann and May finds a solution if: * d < N^delta * |x| < e^delta * |y| < e^0.5 whenever delta < 1 - sqrt(2)/2 ~ 0.292 """
# x-shifts gg = [] for kk inrange(mm + 1): for ii inrange(mm - kk + 1): xshift = x^ii * modulus^(mm - kk) * polZ(u, x, y)^kk gg.append(xshift) gg.sort()
# x-shifts list of monomials monomials = [] for polynomial in gg: for monomial in polynomial.monomials(): if monomial notin monomials: monomials.append(monomial) monomials.sort() # y-shifts (selected by Herrman and May) for jj inrange(1, tt + 1): for kk inrange(floor(mm/tt) * jj, mm + 1): yshift = y^jj * polZ(u, x, y)^kk * modulus^(mm - kk) yshift = Q(yshift).lift() gg.append(yshift) # substitution # y-shifts list of monomials for jj inrange(1, tt + 1): for kk inrange(floor(mm/tt) * jj, mm + 1): monomials.append(u^kk * y^jj)
# construct lattice B nn = len(monomials) BB = Matrix(ZZ, nn) for ii inrange(nn): BB[ii, 0] = gg[ii](0, 0, 0) for jj inrange(1, ii + 1): if monomials[jj] in gg[ii].monomials(): BB[ii, jj] = gg[ii].monomial_coefficient(monomials[jj]) * monomials[jj](UU,XX,YY)
# Prototype to reduce the lattice if helpful_only: # automatically remove BB = remove_unhelpful(BB, monomials, modulus^mm, nn-1) # reset dimension nn = BB.dimensions()[0] if nn == 0: print ("failure") return0,0
# check if vectors are helpful if debug: helpful_vectors(BB, modulus^mm) # check if determinant is correctly bounded det = BB.det() bound = modulus^(mm*nn) if det >= bound: print ("We do not have det < bound. Solutions might not be found.") print ("Try with highers m and t.") if debug: diff = (log(det) - log(bound)) / log(2) print ("size det(L) - size e^(m*n) = ", floor(diff)) if strict: return -1, -1 else: print ("det(L) < e^(m*n) (good! If a solution exists < N^delta, it will be found)")
# display the lattice basis if debug: matrix_overview(BB, modulus^mm)
# LLL if debug: print ("optimizing basis of the lattice via LLL, this can take a long time")
BB = BB.LLL()
if debug: print ("LLL is done!")
# transform vector i & j -> polynomials 1 & 2 if debug: print ("looking for independent vectors in the lattice") found_polynomials = False for pol1_idx inrange(nn - 1): for pol2_idx inrange(pol1_idx + 1, nn): # for i and j, create the two polynomials PR.<w,z> = PolynomialRing(ZZ) pol1 = pol2 = 0 for jj inrange(nn): pol1 += monomials[jj](w*z+1,w,z) * BB[pol1_idx, jj] / monomials[jj](UU,XX,YY) pol2 += monomials[jj](w*z+1,w,z) * BB[pol2_idx, jj] / monomials[jj](UU,XX,YY)
# are these good polynomials? if rr.is_zero() or rr.monomials() == [1]: continue else: print ("found them, using vectors", pol1_idx, "and", pol2_idx) found_polynomials = True break if found_polynomials: break
ifnot found_polynomials: print ("no independant vectors could be found. This should very rarely happen...") return0, 0 rr = rr(q, q)
# solutions soly = rr.roots()
iflen(soly) == 0: print ("Your prediction (delta) is too small") return0, 0
soly = soly[0][0] ss = pol1(q, soly) solx = ss.roots()[0][0]
# return solx, soly
nbit = 1024 n = 12765231982257032754070342601068819788671760506321816381988340379929052646067454855779362773785313297204165444163623633335057895252608396010414744222572161530653104640020689896882490979790275711854268113058363186249545193245142912930804650114934761299016468156185416083682476142929968501395899099376750415294540156026131156551291971922076435528869024742993840057342092865203064721826362149723366381892539617642364692012936270150691803063945919154346756726869466855557344213050973081755499746750276623648407677639812809665472258655462846021403503851719008687214848550916999977775070011121527941755954255781343103086789 e = 459650454686946706615371845737527916539205656667844780634386049268800615782964920944229084502752167395446158290854047696006034750210758341744841762479191173017773034647739346927390580848998121830029134542880713409306092967282675122699586503684943407535067216738556403169403622104762516293879994387324370835718056251706150557820106296417750402984941838652433642298378976899556042987560946508887315484380807248331504458640857234708123277403252632993828101306072382329879857946191508782246793011691530554606521701055094223574951862129713872918021549814674387049788995785872980320871421550616327471735316980754238323013 c = 10992248752412909788626396175372747713079469256270100576886987393986576680666320383209810005318254336440105142571546847427454822405793626080251363454531982746373841267986148332456716023293306870382809568309620264499225135226626560298741596462262513921032733814032790312163314776421380481083058518893602887082464123177575742160690315666730642727773288362853901330620841098230284739614618790097180848133698381487679399364400048499041582830157094876815030301231505774900176910650887780842536610942820066913075027528705150102760422836458745949063992228680293226303245265232017738712226154128654682937687199768621565945171 L = bin(bytes_to_long(b'Practical'))[2:] ph = int(L+"1",2)*2^(nbit-len(L+"1")) qh = ph #known 72 high bits
#part1 boneh and durfee to get d if(1): m = 8 delta = 0.30 t = int((1-2*delta) * m) # optimization from Herrmann and May X = 2*floor(n^delta) # this _might_ be too much Y = 2^(nbit-len(L+"1")) # correct if p, q are ~ same size
A = (n+1)//2 - (ph+qh)//2 PR.<x,y> = PolynomialRing(ZZ) pol = 1+x*(A+y) res = boneh_durfee(pol, e, m, t, X, Y) print(res)
#part2 get d k2 = 49977986915659605429345289223812619569200398624947376450000245097914425323254468264973009610079433427753410860067909320180393446912719527813521669872296939128853941260184779168808 pl_ql = -26225793397477672414138436461088692023641486423848109679632696585093272843809115665873260921093208795526382416734843864007298933841051250143140940470093595985249689125607975667724436632465193533116961405126679193559648564948639967803860314403909842190409143666008313060949901033553728989 d = (1+k2*(A+pl_ql)) // e print(long_to_bytes(int(pow(c,d,n))))
defcontinuedFra(x, y): cF = [] while y: cF += [x // y] x, y = y, x % y return cF
defSimplify(ctnf): numerator = 0 denominator = 1 for x in ctnf[::-1]: numerator, denominator = denominator, x * denominator + numerator return (numerator, denominator)
defgetit(c): cf = [] for i inrange(1, len(c)): cf.append(Simplify(c[:i])) return cf
#part1 use wiener to get d if(1): cf = continuedFra(eh, nh) for d,k in getit(cf): if(len(bin(d)[2:]) == 64and isPrime(d)): print(d) break d = 10254340117704573547
#part2 bruteforce n,c for nl in trange(1,2**8,2): for cl inrange(2**8): n = nh+nl c = ch+cl flag = powmod(c,d,n)
try: flag = long_to_bytes(flag).decode() print(flag) except: pass
from Crypto.Util.number import * from flag import flag
defbase(n, l): D = [] while n > 0: n, r = divmod(n, l) D.append(r) return''.join(str(d) for d inreversed(D)) or'0'
defasiv_prng(seed): l = len(seed) _seed = base(bytes_to_long(seed), 3) _seed = [int(_) for _ in _seed] _l = len(_seed) R = [[getRandomRange(0, 3) for _ inrange(_l)] for _ inrange(_l**2)] S = [] for r in R: s = 0 for _ inrange(_l): s += (r[_] * _seed[_]) % 3 # s += getRandomRange(0, 3) s %= 3 S.append(s) return R, S
seed = flag.lstrip(b'CCTF{').rstrip(b'}') R, S = asiv_prng(seed)
f = open('output.txt', 'w') f.write(f'R = {R}\nS = {S}') f.close()
defpr(*args): s = " ".join(map(str, args)) sys.stdout.write(s + "\n") sys.stdout.flush()
defsc(): return sys.stdin.buffer.readline()
defcheck_inputs(a, b, c): ifnotall(isinstance(x, int) for x in [a, b, c]): returnFalse if a == 0or b == 0or c == 0: returnFalse if a == b or b == c or a == c: returnFalse returnTrue
defmain(): border = "|" pr(border*72) pr(border, ".:: Hi all, she DID it, you should do it too! Are you ready? ::. ", border) pr(border, "Welcome to the Ternary World! You need to pass each level until 20 ", border) pr(border, "to get the flag. Pay attention that your solutions should be nonzero", border) pr(border, "distinct integers. Let's start! ", border) pr(border*72)
level, step = 0, 19 while level <= step: a = random.randint(2**(level * 12), 2**(level*12 + 12)) equation = f'x^2 + y^2 - xy = {a}*z^3' pr(f"Level {level + 1}: {equation}") inputs = input().strip().split(",") try: x, y, z = map(int, inputs) except: die(border, "Invalid input, Bye!!") if check_inputs(x, y, z): if check_solution(a, x, y, z): pr(border, "Correct! Try the next level :)") level += 1 else: pr(border, "You didn't provide the correct solution.") die(border, "Better luck next time!") else: pr(border, "Your solutions should be non-zero distinct integers") die(border, "Quiting...") if level == step: pr(border, "Congratulations! You've successfully solved all the equations!") die(border, f"flag: {flag}")
#part1 factor n PR.<p> = PolynomialRing(ZZ) for delta inrange(10000): f = p*(2*(p-2^255+2^128)+1+delta)-n res = f.roots() if(res != []): p = int(res[0][0]) q = n // p break f = p*(2*(p-2^255-2^128)+1+delta)-n res = f.roots() if(res != []): p = int(res[0][0]) q = n // p break
#part2 get flag Ep = EllipticCurve(GF(p), [a, b]) Eq = EllipticCurve(GF(q), [a, b]) Cp = Ep(enc) Mp = inverse(e,Ep.order())*Cp Cq = Eq(enc) Mq = inverse(e,Eq.order())*Cq
En = EllipticCurve(Zmod(n), [a, b]) from sympy.ntheory.modular import crt X = crt([p,q],[int(Mp.xy()[0]),int(Mq.xy()[0])])[0] print(long_to_bytes(X))
from Crypto.Util.number import * from hashlib import sha512 from flag import flag
defgenkey(nbit): whileTrue: p = getPrime(nbit) if p % 4 == 3: q = int(str(p)[::-1]) if isPrime(q): return p * q, (p, q)
defsetup(msg, pkey): hid = sha512(msg).digest() whileTrue: a = bytes_to_long(hid) if kronecker(a, pkey) == 1: return a else: hid = sha512(hid).digest()
defencrypt(msg, pkey): a, m = setup(msg, pkey), bytes_to_long(msg) B, C = bin(m)[2:], [] for b in B: whileTrue: t = randint(1, pkey) if kronecker(t, pkey) == 2 * int(b) - 1: C.append((t - a * inverse(t, pkey)) % pkey) break return (a, C)
pkey, privkey = genkey(512) E = encrypt(flag, pkey)
from Crypto.Util.number import * from tqdm import *
pkey = 72271787633166084700895603235291055045699965307538401174867474485084272711938364003794151073975875159886045553516299177522950407802715116792937858353646755246888532333536918663888208381012106370000886903776721867958523682675624556576505534100750339626081218194389244007622749982917071344697799413034317147013 E =
n = pkey a,tlist = E[0],E[1]
#part1 get p,q dec_len = 154 deffind(ph,qh,pl,ql): #check1 padding0 = (dec_len-len(ph)-len(pl))*"0" padding9 = (dec_len-len(ph)-len(pl))*"9" if(int(qh+padding0+ql)*int(ph+padding0+pl) > n orint(qh+padding9+ql)*int(ph+padding9+pl) < n): return #check2 mask = 10**len(pl) if(int(ql)*int(pl) % mask != n % mask): return #return if(len(ph+pl) == dec_len): p = int(ph+pl) q = int(qh+ql) if(p*q==n): print(p) print(q) #search for i inrange(10): for j inrange(10): find(ph + str(i), qh + str(j), str(j) + pl, str(i) + ql)
if(0): for i inrange(1,10,2): for j inrange(1,10,2): find(str(i),str(j),str(j),str(i)) p = 7690745050590286968025665448815927548186441771518218204702842288098845344789340509868897149374937793107491606741591691437711395848517107039674900831427939 q = 9397241380094769307017158485931177341961951476061947013977394739417988689050439874435488908822482074028128151771446818457295188445665208696820950505470967
#part2 get flag bit by bit flag = "" for i in tqdm(tlist): PR.<t> = PolynomialRing(Zmod(p)) f = t^2 -i*t - a resp = f.roots()[0][0] PR.<t> = PolynomialRing(Zmod(q)) f = t^2 -i*t - a resq = f.roots()[0][0]
if(kronecker(resp,p)*kronecker(resq,q) == 1): flag += "1" else: flag += "0" print(long_to_bytes(int(flag,2)))
import sys from Crypto.Util.number import * from hashlib import sha256 from flag import flag
p = 114863632180633827211184132915225798242263961691870412740605315763112513729991 A = -3 B = 105675527217961035404524512435875047840495516468907806313576241823653895562912 E = EllipticCurve(GF(p), [A, B]) G = E.random_point() _o = E.order() original_msg = 'I love all cryptographers!!!'
defdie(*args): pr(*args) quit()
defpr(*args): s = " ".join(map(str, args)) sys.stdout.write(s + "\n") sys.stdout.flush()
defencrypt(msg, pkey): e, l = randint(1, _o), len(msg) m1, m2 = bytes_to_long(msg[:l // 2]), bytes_to_long(msg[l // 2:]) assert m1 < p and m2 < p e1, e2 = (e * pkey).xy() c1, c2 = m1 * e1 % p, m2 * e2 % p return (c1, c2, e * G)
defsign(msg, skey): _tail = bytes_to_long(sha256(str(skey).encode('utf-8')).digest()) % (1 << 24) whileTrue: K = [randint(1, 2**255) // (1 << 24) + _tail for _ in'__'] r, s = int((K[0] * G).xy()[0]), int((K[1] * G).xy()[1]) if r * s != 0: break h = bytes_to_long(sha256(msg).digest()) t = inverse(K[0], _o) * (h * r - s * skey) % _o return (r, s, t)
defverify(msg, pkey, _sign): r, s, t = [int(_) % _o for _ in _sign] h = bytes_to_long(sha256(msg.encode('utf-8')).digest()) u = int(h * r * inverse(t, _o) % _o) v = int(s * inverse(t, _o) % _o) # u = h * r * inverse(t, _o) % _o # v = s * inverse(t, _o) % _o _R = (u * G - v * pkey).xy()[0] return _R == r
defmain(): border = "|" pr(border*72) pr(border, "Hi all, now it's time to solve a probably simple ECC challenge about", border) pr(border, "encryption and signing in elliptic curves! Follow the questions and ", border) pr(border, "find the secret flag, are you ready!? ", border) pr(border*72)
pkey, skey = keygen(E)
whileTrue: pr("| Options: \n|\t[E]ncrypt a message! \n|\t[G]et the flag \n|\t[P]ublic Key \n|\t[S]ign a message \n|\t[V]erify signature \n|\t[Q]uit") ans = sc().decode().lower().strip() if ans == 'e': pr(border, 'Send your message here: ') _msg = sc() _enc = encrypt(_msg, pkey) pr(border, f'enc = {_enc}') elif ans == 'g': pr(border, 'You should send the valid signature for my given message!') pr(border, 'Send the signature of original message here: ') _sgn = sc().split(b',') try: _sgn = [int(_) for _ in _sgn] if verify(original_msg, pkey, _sgn): die(border, f'Congratz! You got the flag: {flag}') else: pr(border, 'Your signature is not correct!') except: import traceback; traceback.print_exc() pr(border, 'Try to send valid signature!') continue elif ans == 's': pr(border, 'Send your message to sign: ') _msg = sc() iflen(_msg) >= 10: die(border, 'Sorry, I sign only short messages! :/') _sgn = sign(_msg, skey) pr(border, f'sgn = {_sgn}') elif ans == 'v': pr(border, 'Send your signature to verify: ') _sgn = sc().split(b',') try: _sgn = [int(_) for _ in _sgn] pr(border, 'Send your message: ') _msg = sc() if verify(_msg, pkey, _sgn): pr(border, 'Your message successfully verified :)') else: pr(border, 'Verification failed :(') except: pr(border, 'Try to send valid signature!') continue elif ans == 'p': pr(border, f'pkey = {pkey}') pr(border, f'G = {G}') elif ans == 'q': die(border, 'Quitting...') else: die(border, 'You should select valid choice!')
from Crypto.Util.number import * from Pwn4Sage.pwn import * from hashlib import sha256 from tqdm import * from random import * import os
p = 114863632180633827211184132915225798242263961691870412740605315763112513729991 A = -3 B = 105675527217961035404524512435875047840495516468907806313576241823653895562912 E = EllipticCurve(GF(p), [A, B]) _o = E.order() original_msg = 'I love all cryptographers!!!'
#part2 get groups of sign to construct matrix groups = 20 A = [] B = [] C = []
sh.recvuntil(b"[Q]uit") sh.sendline(b"s") msg = long_to_bytes(0) sh.sendline(msg) sh.recvuntil(b"sgn = ") r0,s0,t0 = eval(sh.recvline().strip().decode()) h0 = bytes_to_long(sha256(msg+b"\n").digest()) for i in trange(1,groups): sh.recvuntil(b"[Q]uit") sh.sendline(b"s") msg = os.urandom(8) sh.sendline(msg) sh.recvuntil(b"sgn = ") ri,si,ti = eval(sh.recvline().strip().decode()) hi = bytes_to_long(sha256(msg+b"\n").digest()) A.append(t0*si) B.append(-ti*s0) C.append(hi*ri*s0-h0*r0*si)
T = 2^300 L = Matrix(ZZ,2*groups,2*groups) for i inrange(groups): L[i,i] = 1 L[groups,groups] = 2^231 for i inrange(groups-1): L[0,groups+1+i] = A[i]*T L[1+i,groups+1+i] = B[i]*T L[groups,groups+1+i] = C[i]*T L[groups+1+i,groups+1+i] = _o*T
#part3 LLL to get k res = L.LLL() for i in res: if(abs(i[groups])==2^231): k0 = abs(i[0]) break
#part4 get skey and get signature of original message skey = (h0*r0-t0*k0)*inverse(s0,_o) % _o print(skey*G == pkey) _tail = bytes_to_long(sha256(str(skey).encode('utf-8')).digest()) % (1 << 24) whileTrue: K = [randint(1, 2**255) // (1 << 24) + _tail for _ in'__'] r, s = int((K[0] * G).xy()[0]), int((K[1] * G).xy()[1]) if r * s != 0: break h = bytes_to_long(sha256(original_msg.encode()).digest()) t = inverse(K[0], _o) * (h * r - s * skey) % _o
sh.recvuntil(b"[Q]uit") sh.sendline(b"g") sh.sendline((str(r)+","+str(s)+","+str(t)).encode()) sh.recvuntil(b"You got the flag: ") print(sh.recvline())
import sys import random import binascii from flag import flag
defdie(*args): pr(*args) quit()
defpr(*args): s = " ".join(map(str, args)) sys.stdout.write(s + "\n") sys.stdout.flush()
defsc(): return sys.stdin.buffer.readline()
defvinefruit(msg, mod, flag = 0): P = [16777619, 1099511628211, 309485009821345068724781371] O = [2166136261, 14695981039346656037, 144066263297769815596495629667062367629] assert mod in [0, 1, 2] p, o, m = P[mod], O[mod], 2 ** (2 << (4 + mod)) vine = o for b in msg: if flag == 1: vine = (vine + b) % (2 ** 128) else: vine = vine ^ b vine = (vine * p) % m return vine
defmain(): border = "|" pr(border*72) pr(border, " Hi all, I have designed a gorgeous cryptography hash function in ", border) pr(border, " order to secure the world! Your mission is to find collision for ", border) pr(border, " this function with specific conditions. ", border) pr(border*72) step = 19
whileTrue: pr("| Options: \n|\t[S]ubmit collision \n|\t[Q]uit") ans = sc().decode().lower().strip() if ans == 's': S = [] for level inrange(step): mod = random.randint(0, 2) pr(border, f'Submit two different string such that vinefruit(m1, {mod}, 1) = vinefruit(m2, {mod}, 1)') pr(border, f'You are at level: {level + 1}') if level == step - 1andlen(S) == step - 1: die(border, f'Congrats, you got the flag: {flag}') try: pr(border, f'Please send first byte string: ') s1 = sc()[:-1] pr(border, f'Please send second byte string: ') s2 = sc()[:-1] s1, s2 = binascii.unhexlify(s1), binascii.unhexlify(s2) except: pr(border, 'You should send valid hex strings.') break iflen(s1) == len(s2) == 35 - level and s1 != s2: if vinefruit(s1, mod, 1) == vinefruit(s2, mod, 1): if vinefruit(s1, mod, 1) notin S: S.append(vinefruit(s1, mod, 1)) pr(border, 'gj, try the next level :)') else: break else: break else: die(border, 'Kidding me?! Try again and be smart!! Bye!!!') elif ans == 'q': die(border, 'Quitting...') else: die(border, 'You should select valid choice!')
from Pwn4Sage.pwn import * from Crypto.Util.number import * from tqdm import *
defgen_s1_s2(level,mod): length = 35-level P = [16777619, 1099511628211, 309485009821345068724781371] O = [2166136261, 14695981039346656037, 144066263297769815596495629667062367629] p, o, m = P[mod], O[mod], 2 ** (2 << (4 + mod))
T = 2^1000 L = Matrix(ZZ,length+2,length+2) for i inrange(length): L[i,i] = 1 L[i,-1] = p^(length-i)*T L[-2,-2] = T L[-2,-1] = (p^length)*T L[-1,-1] = m*T
res = L.LLL() for i in res: if(i[-2] == 0): S = i[:-2] break s1 = [128for i inrange(length)] s2 = [s1[i] + S[i] for i inrange(length)] assertall (i inrange(0,256) for i in s2)
defmain(): border = "|" pr(border*72) pr(border, "Hi all, I have created a basic and rudimentary version of a sumcheck", border) pr(border, "protocol. Your task is to generate a false statement and persuade ", border) pr(border, "verifier of its validity. ", border) pr(border*72) q = 2**61 - 1# Mersenne prime F = GF(q)
whileTrue: pr("| Options: \n|\t[C]laim the statement \n|\t[D]etermine parameters and polynomial \n|\t[Q]uit") ans = sc().decode().lower().strip() if ans == 'd': pr(border, f'Please first send the number of variable and the degree of your desired polynomial:') _ans = sc() try: _n, _d = [int(_) for _ in _ans.split(b',')] if (_n * _d) // q < 5e-17and _n >= 5and _d >= 3: R = PolynomialRing(F, _n, 'x') x = R.gens() else: raise Exception() except: die(border, 'The parameters are not consistent! Try again!!') pr(border, f'Now, please send the {_n}-variable polynomial as p: ') _p = sc().strip().decode() try: _p = R(_p) p = _p _deg = _p.degree(std_grading=True) if _deg != _d: raise Exception() except: die(border, 'The polynomial is not valid or does not hold true in the given situations!') g = slowsum(_p, _n) elif ans == 'c': pr(border, 'Please send the g: ') _g = sc() try: _g = int(_g) if _g == g: die(border, 'Kidding me?! Bye :P') except: die(border, 'Some exception occurred! Bye!!') _P, _H = [], [] for i inrange(_n): pr(border, f'Please send the (p_{i}, h4sh(p_{i}, q)): ') pr(border, f'Note that the variable of p_{i} should be x. ') _ph = sc().strip() try: _p, _h = [_.decode() for _ in _ph.split(b',')] _R = PolynomialRing(F, 'x') _p, _h = _R(_p), F(_h) if _p.degree() > _d: raise Exception() _P.append(_p) _H.append(_h) except: die(border, 'Some exception occurred! Bye!!') j = 0 for i inrange(_n): if i == 0: if _P[i](0) + _P[i](1) != _g or h4sh(_P[i], q) != _H[i]: break else: if _P[i](0) + _P[i](1) != _P[i-1](_H[i-1]) or h4sh(_P[i], q) != _H[i]: break j += 1 if j < _n or p(_H) != _P[_n-1](_H[_n-1]): die(border, 'Oops, verifier believes that the polynomial is not valid! Bye!!') die(border, f'Congrats, here the flag: {flag}') elif ans == 'q': die(border, 'Quitting...') else: die(border, 'You should select valid choice!')
from Pwn4Sage.pwn import * from Crypto.Util.number import * from itertools import product
defslowsum(p, n): g = 0 perms = list(product([0, 1], repeat = n)) for _prm in perms: g += p(_prm) return g
q = 2**61 - 1# Mersenne prime F = GF(q) n = 5 d = 3 R = PolynomialRing(F, n, 'x') x = R.gens() p = "x0^3" _p = R(p) g = slowsum(_p, n)
sh = remote("node4.anna.nssctf.cn",28301)
sh.recvuntil(b"[Q]uit") sh.sendline(b"d") sh.recvuntil(b"desired polynomial:") sh.sendline(b"5,3") sh.recvuntil(b"polynomial as p: ") sh.sendline(p.encode())
sh.recvuntil(b"[Q]uit") sh.sendline(b"c") sh.recvuntil(b"Please send the g: ") sh.sendline(b"0") for i inrange(n): sh.recvuntil(b"should be x. ") sh.sendline(b"0,0") sh.recvuntil(b"here the flag:") print(sh.recvline())
from Crypto.Util.number import * from flag import flag
defbase(n, l): D = [] while n > 0: n, r = divmod(n, l) D.append(r) return''.join(str(d) for d inreversed(D)) or'0'
defasiv_prng(seed): l = len(seed) _seed = base(bytes_to_long(seed), 3) _l = len(_seed) R = [[getRandomRange(0, 3) for _ inrange(_l)] for _ inrange(_l**2)] S = [] for r in R: s = 0 for _ inrange(_l): b = ((int(r[_]) + int(_seed[_])) % 3) % 2 s = s ^ b S.append(s) print(len(S)) return R, S
seed = flag.lstrip(b'CCTF{').rstrip(b'}') R, S = asiv_prng(seed)
f = open('output.txt', 'w') f.write(f'R = {R}\nS = {S}') f.close()
withopen(r'E:\vscode\output.txt') as f: exec(f.read())
n = len(R[0]) A = [] b = []
for i inrange(3 * n): Aline = [] bline = S[i] for j inrange(n): if (R[i][j] == 0): Aline.extend([0, 1, 0]) elif (R[i][j] == 1): Aline.extend([1, 0, 0]) elif (R[i][j] == 2): Aline.extend([0, 0, 1]) A.append(Aline) b.append(bline)
A = matrix(GF(2), A) b = vector(GF(2), b) x = A.solve_right(b) #print(x)
ans = [] for i inrange(n): if (x[3*i] == 1) and (x[3*i+1] == 0) and (x[3*i+2] == 0): ans.append(0) elif (x[3*i] == 0) and (x[3*i+1] == 1) and (x[3*i+2] == 0): ans.append(1) elif (x[3*i] == 0) and (x[3*i+1] == 0) and (x[3*i+2] == 1): ans.append(2) elif (x[3*i] == 1) and (x[3*i+1] == 1) and (x[3*i+2] == 0): ans.append(2)
from Crypto.Util.number import * ans = ''.join(str(x) for x in ans) ans = long_to_bytes(int(ans, 3)) print(ans)