from Crypto.Util.number import * y = [] km = [] possiblem = [] for i in range(4): y.append(x[i+1]-x[i]) for j in range(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 in range(4): y.append(x[i+1]-x[i]) for j in range(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))
def Solve_c(): sqrt_N = int(sqrt(N)) C = sqrt_N//g^2 a = 2 b = pow(a,g,N)
for i in range(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 in range(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
ez-factor
注意到 其中k是512位,r是248位,r远远小于hint
那么我们有 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))