m = '' for i in key[::-1]: if c >= i: m = '1' + m c -= i else: m = '0' + m flag = long_to_bytes(int(m[:-1],2)) # flag = long_to_bytes(int(m+'0'*7,2)) print(flag)
m= [m[i:i + 8] for i inrange(0, len(m), 8)] decoded_string = ''.join(chr(int(''.join(map(str, byte)), 2)) for byte in m) print(decoded_string)
print('n =', n) print('M =', M) print('l =', l) print('c =', c)
''' n = 18339446336492672809908730785358232636383625709800392830207979464962269419140428722248172110017576390002616004691759163126532392634394976712779777822451878822759056304050545622761060245812934467784888422790178920804822224673755691 M = 36208281423355218604990190624029584747447986456188203264389519699277658026754156377638444926063784368328407938562964768329134840563331354924365667733322 l = 56911058350450672322326236658556745353275014753768458552003425206272938093282425278193278997347671093622024933189270932102361261551908054703317369295189 c = 720286366572443009268610917990845759123049408295363966717060100862857351750759651979922104897091176824666482923148635058966589592286465060161271579501861264957611980854954664798904862706450723639237791023808177615189976108231923 '''
n = 18339446336492672809908730785358232636383625709800392830207979464962269419140428722248172110017576390002616004691759163126532392634394976712779777822451878822759056304050545622761060245812934467784888422790178920804822224673755691
for i in trange(2**10): pq = n // (2**240 * 10**79 + 1) - i pq2 = (n - pq*(2**240 * 10**79 + 1)) // (2**120 * 10**39) if (n - pq*(2**240 * 10**79 + 1)) % (2**120 * 10**39) == 0: # 倍数 p, q = sympy.symbols('p q') flag = sympy.solve([pq - p*q,pq2-(p**2+10*q**2)],[p,q]) break
p = abs(flag[0][0]) q = abs(flag[0][1]) print(p,q)
from Crypto.Util.number import long_to_bytes import itertools import sys
defsmall_roots(f, bounds, m=1, d=None): ifnot d: d = f.degree()
R = f.base_ring() N = R.cardinality()
f /= f.coefficients().pop(0) f = f.change_ring(ZZ)
G = Sequence([], f.parent()) for i inrange(m + 1): base = N ^ (m - i) * f ^ i for shifts in itertools.product(range(d), repeat=f.nvariables()): g = base * prod(map(power, f.variables(), shifts)) G.append(g)
factors = [monomial(*bounds) for monomial in monomials] for i, factor inenumerate(factors): B.rescale_col(i, factor)
B = B.dense_matrix().LLL()
B = B.change_ring(QQ) for i, factor inenumerate(factors): B.rescale_col(i, 1 / factor)
H = Sequence([], f.parent().change_ring(QQ)) for h infilter(None, B * monomials): H.append(h) I = H.ideal() if I.dimension() == -1: H.pop() elif I.dimension() == 0: roots = [] for root in I.variety(ring=ZZ): root = tuple(R(root[var]) for var in f.variables()) roots.append(root) return roots return []
n = 18339446336492672809908730785358232636383625709800392830207979464962269419140428722248172110017576390002616004691759163126532392634394976712779777822451878822759056304050545622761060245812934467784888422790178920804822224673755691
lenght = [39,40] for i in lenght: for j in lenght: print((i, j)) R.<x,y> = PolynomialRing(Zmod(n^2)) PQ = x*2^120*10^i + y QP = y*2^120*10^j + x f = n - PQ*QP roots = small_roots(f,(2^130,2^130),m=1,d=4) if roots !=[]: # print(roots) p,q = roots[0] print(p,q) break # 1213149261930568621267125437333569321667 855604426214387476576649090490109822073
from Crypto.Util.number import * from secret import flag
nbit =128 whileTrue: p, q= getPrime(nbit), getPrime(nbit) PQ = int(str(p<<256)+str(q)) QP = int(str(q<<256)+str(p)) if isPrime(PQ) and isPrime(QP): break
e=0x10001 N = PQ * QP n = p * q m=bytes_to_long(flag) c=pow(m,e,n)
print('N =', N) print('c=',c)
''' N = 1085674311530255489464290129824772067886812106070317576328547361171348401864749700142226317981052597718932148985813969001766383466131904811646438034866606166860409715940892963991884944642366896061549360382036310506993659981270186354624380079666262454880589702937061510841107889532190435909694042809685218422473 c= 56930360094664103380901535309475311481122482721421214918816986675606014573458 '''
当时解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
import libnum from xenny.ctf.crypto.modern.asymmetric.rsa import factor
N = 1085674311530255489464290129824772067886812106070317576328547361171348401864749700142226317981052597718932148985813969001766383466131904811646438034866606166860409715940892963991884944642366896061549360382036310506993659981270186354624380079666262454880589702937061510841107889532190435909694042809685218422473 c = 56930360094664103380901535309475311481122482721421214918816986675606014573458 e = 65537
bit = str(bin(N)[2:]) n = int('0b'+bit[1027//4*3:],2)
p,q = factor.attack(n) d=libnum.invmod(e,(p-1)*(q-1)) m = pow(c,d,n) print(libnum.n2s(pow(c,d,n)))
defsmall_roots(f, bounds, m=1, d=None): ifnot d: d = f.degree()
R = f.base_ring() N = R.cardinality()
f /= f.coefficients().pop(0) f = f.change_ring(ZZ)
G = Sequence([], f.parent()) for i inrange(m + 1): base = N ^ (m - i) * f ^ i for shifts in itertools.product(range(d), repeat=f.nvariables()): g = base * prod(map(power, f.variables(), shifts)) G.append(g)
factors = [monomial(*bounds) for monomial in monomials] for i, factor inenumerate(factors): B.rescale_col(i, factor)
B = B.dense_matrix().LLL()
B = B.change_ring(QQ) for i, factor inenumerate(factors): B.rescale_col(i, 1 / factor)
H = Sequence([], f.parent().change_ring(QQ)) for h infilter(None, B * monomials): H.append(h) I = H.ideal() if I.dimension() == -1: H.pop() elif I.dimension() == 0: roots = [] for root in I.variety(ring=ZZ): root = tuple(R(root[var]) for var in f.variables()) roots.append(root) return roots return []
N = 1085674311530255489464290129824772067886812106070317576328547361171348401864749700142226317981052597718932148985813969001766383466131904811646438034866606166860409715940892963991884944642366896061549360382036310506993659981270186354624380079666262454880589702937061510841107889532190435909694042809685218422473 c= 56930360094664103380901535309475311481122482721421214918816986675606014573458
R.<x,y> = PolynomialRing(Zmod(n^2)) PQ = x*2^256*10^39 + y QP = y*2^256*10^39 + x f = N - PQ*QP roots = small_roots(f,(2^130,2^130)) if roots !=[]: # print(roots) p,q = roots[0] print(p,q)
c = 720286366572443009268610917990845759123049408295363966717060100862857351750759651979922104897091176824666482923148635058966589592286465060161271579501861264957611980854954664798904862706450723639237791023808177615189976108231923 e = 3
for mp in GF(PP)(c).nth_root(e, all=True): for mq in GF(QQ)(c).nth_root(e, all=True): m = long_to_bytes(crt([ZZ(mp), ZZ(mq)], [PP, QQ])) ifb'DASCTF'in m: print(m) break
# DASCTF{Ar3_Y0u_Su93_Abt139??}
上面没有用到 M = pow(m,1,l)
由于 m 被填充了,不能被直接开3次方得到,但我们可以 得到 m = M + k*l
k(93*8-505=239)远小于 N (758 bit),用 coppersmith 求 k 就很容易得到了
M = 36208281423355218604990190624029584747447986456188203264389519699277658026754156377638444926063784368328407938562964768329134840563331354924365667733322 l = 56911058350450672322326236658556745353275014753768458552003425206272938093282425278193278997347671093622024933189270932102361261551908054703317369295189 c = 720286366572443009268610917990845759123049408295363966717060100862857351750759651979922104897091176824666482923148635058966589592286465060161271579501861264957611980854954664798904862706450723639237791023808177615189976108231923 p = 1213149261930568621267125437333569321667 q = 855604426214387476576649090490109822073
deffun(data,y,n): returnsum([data[i] * pow(y,i,n) for i inrange(len(data))]) % n
defgen(x, y, z, w, n): data = [randint(n // 4, n) for _ inrange(10)] leak1 = pow(x + pow(y, z, n), w, n) leak2 = fun(data, y, n) return data, leak1, leak2
defencrypt(l,m,n): mm = bin(m)[2:].zfill((m.bit_length() // 8 + 1) * 8) length = len(mm) c = [] s = [] for i inrange(length): a = randint(1, n) s.append(pow(a, length, n)) for j inrange(length): c.append(pow(l,int(mm[j]),n) * s[j] % n) return c
n = 214189098485907407681203562477141616514627803973812423866137712061520397412283304756125615530911730190509122275581663270324067756428063773995710185422014937638013530995658678484408224195008950739065869752467503449898424403807629035201754909341605483646512086652631108980705938767234014655512244203488129210213088484751842078315616338034946509581920246058635374657554442252420460618886159118637553788160140879059706396460523335509806462257352635091258764319929220939182156189941663585022210802535804264016891744621140144859992731921592420695928759275864955373537480452694672023754214092487216273962896544919015905264313446548396379618341043583032673900608611135254563997519445284222602183035105369017270389887769617942348731416370092842162632579589494341854993600540689280924183073089475208340685636482246115054414077320832052204722015428500812923185709772796221129375539131726373252482799298746655947376656143301849009181701495003174228813534439192414768762803822975277797520157025175837722175072241107 l = 138833858362699289505402947409766595473722379891580589518174731439613184249727659678966809301611194545239974736175752769503863392697421092435438747741790652435801956708356186578269272819715592752821497122516109657809748674185639254430403157877064556216401002688452227124543508128414591884297632663910714681207
print(libnum.jacobi(l,n))
# -1
同样,测试发现 l 不符合二次剩余定理
于是,这题就需要用到 n 和 c,利用二次剩余定理解题
exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
import libnum from Crypto.Util.number import *
n = 214189098485907407681203562477141616514627803973812423866137712061520397412283304756125615530911730190509122275581663270324067756428063773995710185422014937638013530995658678484408224195008950739065869752467503449898424403807629035201754909341605483646512086652631108980705938767234014655512244203488129210213088484751842078315616338034946509581920246058635374657554442252420460618886159118637553788160140879059706396460523335509806462257352635091258764319929220939182156189941663585022210802535804264016891744621140144859992731921592420695928759275864955373537480452694672023754214092487216273962896544919015905264313446548396379618341043583032673900608611135254563997519445284222602183035105369017270389887769617942348731416370092842162632579589494341854993600540689280924183073089475208340685636482246115054414077320832052204722015428500812923185709772796221129375539131726373252482799298746655947376656143301849009181701495003174228813534439192414768762803822975277797520157025175837722175072241107
withopen('output.txt','r') as f: c = (f.read().strip().split('c = ')[-1])
c = eval(c)
m = '' for i in c: if (libnum.jacobi(i,n)) == 1: m += '0'# 根据题意 + 0 else: m += '1' print(long_to_bytes(int(m,2)))
withopen('output.txt','r') as f: c = (f.read().strip().split('c = ')[-1]) c = eval(c)
ed = 8238783462304466047370608758999664260116370123313022088538091162770601739116628806460542503654403361322931229200817491683096695046254053538710523477982774850621979868926682997393573131262930645387042545807254462907502249936746101134745335780459335767976492133149192198880107516742633966664923533160167069625322094242414191994000927842976472080411237834215691897822371792754587587715760051582955795834883174474583440371035173351136370107484245425758954400434828144460697864191261513214008084848001467959369934964428291290009392620134215667173457413630882523557102057539902909381706460767916715499306316003286608457624713509816056636249181986636842368337873445101552453774405927824096616431732124001038586048766823358751593885500314021939046991953062562270782883182855487098328026196086288533138907969729187779739950764344200364360079479047132746676799216491472345637845220255139152063453462176656553357596450484408472263570570448409671724853674399060252094955913831086556844240273178815236110565265190938731402297513542863173575371193878977 n = 214189098485907407681203562477141616514627803973812423866137712061520397412283304756125615530911730190509122275581663270324067756428063773995710185422014937638013530995658678484408224195008950739065869752467503449898424403807629035201754909341605483646512086652631108980705938767234014655512244203488129210213088484751842078315616338034946509581920246058635374657554442252420460618886159118637553788160140879059706396460523335509806462257352635091258764319929220939182156189941663585022210802535804264016891744621140144859992731921592420695928759275864955373537480452694672023754214092487216273962896544919015905264313446548396379618341043583032673900608611135254563997519445284222602183035105369017270389887769617942348731416370092842162632579589494341854993600540689280924183073089475208340685636482246115054414077320832052204722015428500812923185709772796221129375539131726373252482799298746655947376656143301849009181701495003174228813534439192414768762803822975277797520157025175837722175072241107
p = GCD(pow(2,ed,n)-2,n) m = '' for i in c: if (libnum.jacobi(i,p)) == 1: m += '0' else: m += '1' print(long_to_bytes(int(m,2)))
deffactor_with_ed(ed,n): p=1 q=1 while p==1and q==1: k = ed -1 g = random.randint(1,n) while k%2==0: k //= 2 x = pow(g,k,n) if x>1and libnum.gcd(x-1,n)>1: p = libnum.gcd(x-1,n) q = n//p return p,q
n = 214189098485907407681203562477141616514627803973812423866137712061520397412283304756125615530911730190509122275581663270324067756428063773995710185422014937638013530995658678484408224195008950739065869752467503449898424403807629035201754909341605483646512086652631108980705938767234014655512244203488129210213088484751842078315616338034946509581920246058635374657554442252420460618886159118637553788160140879059706396460523335509806462257352635091258764319929220939182156189941663585022210802535804264016891744621140144859992731921592420695928759275864955373537480452694672023754214092487216273962896544919015905264313446548396379618341043583032673900608611135254563997519445284222602183035105369017270389887769617942348731416370092842162632579589494341854993600540689280924183073089475208340685636482246115054414077320832052204722015428500812923185709772796221129375539131726373252482799298746655947376656143301849009181701495003174228813534439192414768762803822975277797520157025175837722175072241107 ed = 8238783462304466047370608758999664260116370123313022088538091162770601739116628806460542503654403361322931229200817491683096695046254053538710523477982774850621979868926682997393573131262930645387042545807254462907502249936746101134745335780459335767976492133149192198880107516742633966664923533160167069625322094242414191994000927842976472080411237834215691897822371792754587587715760051582955795834883174474583440371035173351136370107484245425758954400434828144460697864191261513214008084848001467959369934964428291290009392620134215667173457413630882523557102057539902909381706460767916715499306316003286608457624713509816056636249181986636842368337873445101552453774405927824096616431732124001038586048766823358751593885500314021939046991953062562270782883182855487098328026196086288533138907969729187779739950764344200364360079479047132746676799216491472345637845220255139152063453462176656553357596450484408472263570570448409671724853674399060252094955913831086556844240273178815236110565265190938731402297513542863173575371193878977
import os from random import getrandbits from hashlib import sha256, md5 from Crypto.Util.number import * from Crypto.Cipher import AES from Crypto.Util.Padding import pad from secret import flag
classShamir: def__init__(self, pbits, noise_bit, n, m): self.pbits = pbits self.noise_bit = noise_bit self.n = n self.m = m self.p = getPrime(pbits) P.<x> = PolynomialRing(Zmod(self.p)) self.poly = P([bytes_to_long(sha256(os.urandom(32)).digest()) for i inrange(self.n)])
defsample(self): t = getrandbits(self.pbits) y = int(self.poly(t)) noise = getrandbits(noise_bit) return (t, y | noise)
defget_msg(self): res = [] for i inrange(self.m): res.append(self.sample()) return res
pbits = 400 noise_bit = 32 n = 100 m = 75
shamir = Shamir(pbits, noise_bit, n, m) coefficient = shamir.poly() key = "".join([str(i) for i inlist(coefficient)[1:]]) key = md5(key.encode()).digest() aes = AES.new(key = key, mode = AES.MODE_ECB) ct = aes.encrypt(pad(flag, 16))
withopen("data.txt", "w") as f: f.write(str(shamir.p)+'\n') f.write(str(shamir.get_msg())+'\n') f.write(str(bytes_to_long(ct))+'\n')