\[
y_{n+2}y_n \equiv ay_ny_{n+1} \equiv y_{n+1}^2 \mod m
\]
a消失了,那么此时,只剩下m这一个未知数
把同余式写成等式
\[
y_{n+1}^2 = y_ny_{n+2} + km
\]
可以求出k1m,k2m,等等
如果两个k没有公因数的话,那么m就是它们的最大公因数
1 2 3 4 5 6 7 8 9 10 11
from Crypto.Util.number import * y = [] km = [] possiblem = [] for i inrange(4): y.append(x[i+1]-x[i]) for j inrange(2): km.append(y[j+1]*y[j+1]-y[j]*y[j+2]) if j >= 1: if isPrime(GCD(km[j],km[j-1])): possiblem.append(GCD(km[j],km[j-1]))
x_1 = (x[0] + inverse(a,m)*(x[0]-x[1])) % m print(long_to_bytes(x_1))
exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
from Crypto.Util.number import * y = [] km = [] possiblem = [] for i inrange(4): y.append(x[i+1]-x[i]) for j inrange(2): km.append(y[j+1]*y[j+1]-y[j]*y[j+2]) if j >= 1: if isPrime(GCD(km[j],km[j-1])): possiblem.append(GCD(km[j],km[j-1])) m = 17685238729089629081000199791073775580173848219782600577303616658328942786376878589055722139055973814631247947507009292556525580971952751595622172013382374577299734041726162411213993858497140178230251563824957482883763872967881950049985507310408962206729214890421322185752340466578359217999838551622613116097987673746844913920603425686103175874552686869764028906518131374266999714020645422015426801070343771422250037085635856203202935123956520415086942807824199018302630540169113637093488756273183240186533936637562954227188102214396705205042491881526862572569275650908415160529650027016717502470758797514488134766043 a = y[1]*inverse(y[0],m) % m print(a) x_1 = (x[0] + inverse(a,m)*(x[0]-x[1])) % m print(long_to_bytes(x_1))
v = h % g defSolve_c(): sqrt_N = int(sqrt(N)) C = sqrt_N//g^2 a = 2 b = pow(a,g,N)
for i inrange(2,C): D = (int(sqrt(C)) + 1) * i final = pow(int(b),int(u),int(N)) tmp = 1 gs = pow(int(b), int(D), N) for r in tqdm(range(D)): for s inrange(D): #if powmod(int(b),int(r*D+s),N) == final: if tmp == final: print("r =",r,"s =",s,"i =",i) return r * D + s tmp = (tmp * int(b)) % N c = Solve_c() A = u - c # x * y = u - c
B = v + c * g # x + y = v + c * g
delta = iroot((B * B - 4 * A), 2)[0]
x = (B + delta) // 2
y = (B - delta) // 2
a = x // 2
b = y // 2
p = 2 * g * a + 1
q = 2 * g * b + 1
d = invert(e, (p - 1) * (q - 1))
m = powmod(C, d, N)
print(long_to_bytes(m))
数据处理
简单的求个离散对数
然后这里数字被替换了
直接遍历一遍所有组合,爆破就行了
exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
from tqdm import * Z = Zmod(2^512) m = 5084057673176634704877325918195984684237263100965172410645544705367004138917087081637515846739933954602106965103289595670550636402101057955537123475521383 c = 2989443482952171039348896269189568991072039347099986172010150242445491605115276953489889364577445582220903996856271544149424805812495293211539024953331399 new_flag=str(discrete_log(Z(c), Z(m))) lowercase = '0123456789' uppercase = '7***4****5' from itertools import permutations for i in tqdm(permutations("0123689")): up = f"7{''.join(i[:3])}4{''.join(i[3:])}5" table = ''.maketrans(up, lowercase) flag = new_flag.translate(table) try: res = (long_to_bytes(int(flag)).decode()) if res.startswith("H&NCTF"): print(res) except: pass
ezfactor
注意到 \[
hint = kp+r
\] 其中k是512位,r是248位,r远远小于hint
那么我们有 \[
hint - r \equiv 0\mod p
\] r是一个小根,使用CopperSmith慢慢调参数即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
R = 2^248# r 的上界 e=0x10001 P.<x> = PolynomialRing(Zmod(N)) f = hint -x f = f.monic() # r = f.small_roots(X=R, beta=0.495, epsilon=0.015)[0] # print("Found r =", r) r = 310384729555967603261671853388867753979360895944109353196595111340924855459 p = gcd(hint - r, N) q = N // p assert p * q == N print("Found p =", p) print("Found q =", q) d = inverse(e,(p-1)*(q-1)) m = pow(c,d,N) print(long_to_bytes(m))
R = 2^252# r 的上界 e=0x10001 P.<x> = PolynomialRing(Zmod(N)) high_bits = 12#爆破高位 X = 2^(rbits - high_bits) - 1
for high in trange(2^high_bits,-1,-1): r_high = high << (rbits - high_bits) # 多项式:hint - (r_high + x) ≡ 0 mod p P.<x> = PolynomialRing(Zmod(N)) f = hint - (r_high + x) f = f.monic() roots = f.small_roots(X, beta=0.495, epsilon=0.03) if roots: r_low = roots[0] r = r_high + r_low print(f"Found r = {r}") break
得到r,后面就没什么了
exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
r = 7166351305785506670352015492214713707534657162937963088592442157834795391917 c = "476922b694c764725338cca99d99c7471ec448d6bf60de797eb7cc6e71253221035eb577075f9658ac7f1a40747778ac261787baad21ee567256872fa9400c37" c = bytes.fromhex(c) leak=N*r p = gcd(hint - r, N) q = N // p r_bytes = long_to_bytes(leak) iv = r_bytes[:16] iflen(r_bytes) >= 16else r_bytes + b'\0'*(16-len(r_bytes)) key = sha256(str(p + q + r).encode()).digest()[:16] crypt_sm4 = CryptSM4() crypt_sm4.set_key(key, SM4_DECRYPT) decrypted = crypt_sm4.crypt_cbc(iv, c) flag = unpad(decrypted, 16) print("Flag:", flag.decode())
Three vertical lines
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
from Crypto.Util.number import * from secret import flag from rsa.prime import getprime while(1): p=getprime(256) q=getprime(256) if isPrime(3*p**5+4*q**5): print(3*p**5+4*q**5) break
e = 65537 print(pow(bytes_to_long(flag), e, p * q)) #72063558451087451183203801132459543552092564094711815404066471440396765744526854383117910805713050240067432476705168314622044706081669935956972031037827580519320550326077291392722314265758802332280697884744792689996718961355845963752788234205565249205191648439412084543163083032775054018324646541875754706761793307667356964825613429368358849530455220484128264690354330356861777561511117 #2864901454060087890623075705953001126417241189889895476561381971868301515757296100356013797346138819690091860054965586977737630238293536281745826901578223
给了一个 \[
3p^5+4q^5=h
\] 对于这种齐次式子,常见的做法就是消元 \[
p = aq \mod h
\] 那么就有 \[
3a^5+4 \equiv 0\mod h
\] 我们求出这个a之后,就可以造格子了因为 \[
\begin{pmatrix} p & a \\ 0 & 1
\end{pmatrix}\begin{pmatrix}k\\q\end{pmatrix}=\begin{pmatrix}p\\q\end{pmatrix}
\]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
from Crypto.Util.number import * h=72063558451087451183203801132459543552092564094711815404066471440396765744526854383117910805713050240067432476705168314622044706081669935956972031037827580519320550326077291392722314265758802332280697884744792689996718961355845963752788234205565249205191648439412084543163083032775054018324646541875754706761793307667356964825613429368358849530455220484128264690354330356861777561511117 P.<x> = PolynomialRing(Zmod(h)) f = 3*x^5+4 a = f.roots()[0][0] # print((Integer(iroot(h,5)[0])).nbits()) L = matrix(ZZ,[[h,0],[a,1]]) res=L.LLL()[0] p,q = res p,q = abs(p),abs(q) n = p*q c=2864901454060087890623075705953001126417241189889895476561381971868301515757296100356013797346138819690091860054965586977737630238293536281745826901578223 e = 65537 phi = (p-1)*(q-1) d= inverse(e,phi) m = pow(c,d,n) print(long_to_bytes(m))