1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
| import itertools a = 3591518680290719943596137190796366296374484536382380061852237064647969442581391967815457547858969187198898670115651116598727939742165753798804458359397101 c = 6996824752943994631802515921125382520044917095172009220000813718617441355767447428067985103926211738826304567400243131010272198095205381950589038817395833 p = 7386537185240346459857715381835501419533088465984777861268951891482072249822526223542514664598394978163933836402581547418821954407062640385756448408431347 ans = (50712831100361370819145886978385347931029768, 9089234402520025586415667640120652372860183) high = [67523583999102391286646648674827012089888650576715333147417362919706349137337570430286202361838682309142789833, 70007105679729967877791601360700732661124470473944792680253826569739619391572400148455527621676313801799318422]
def small_roots(f, bounds, m=1, d=None): if not 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 in range(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) B, monomials = G.coefficient_matrix() monomials = vector(monomials) factors = [monomial(*bounds) for monomial in monomials] for i, factor in enumerate(factors): B.rescale_col(i, factor) B = B.dense_matrix().LLL() B = B.change_ring(QQ) for i, factor in enumerate(factors): B.rescale_col(i, 1/factor) H = Sequence([], f.parent().change_ring(QQ)) for h in filter(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 []
R.<x1,x2> = PolynomialRing(Zmod(p)) f = a*(high[0]*(2^146)+x1)^2 + c - (high[1]*2^146+x2) print(small_roots(f,[2^146, 2^146],m =4,d = 4))
import gmpy2 from Crypto.Util.number import * import hashlib
def Legendre(a, p): return pow(a, (p-1)//2, p)
def Tonelli_Shanks(a, p): assert Legendre(a, p) == 1 if(p % 4 == 3): return pow(a, (p+1)//4, p) s, q = 0, p-1 while q & 1 == 0: q >>= 1 s += 1 for z in range(2, p): if Legendre(z, p) == p-1: c = pow(z, q, p) break r, t, m = pow(a, (q+1)//2, p), pow(a, q, p), s temp, i = 1, 0 while t % p != 1: i += 1 temp = pow(t, 2**i, p) if temp % p == 1: b = pow(c, 2**(m-1-i), p) r = r * b % p c = b * b % p t = t * c % p m = i i = 0 return r
a = 3591518680290719943596137190796366296374484536382380061852237064647969442581391967815457547858969187198898670115651116598727939742165753798804458359397101 c = 6996824752943994631802515921125382520044917095172009220000813718617441355767447428067985103926211738826304567400243131010272198095205381950589038817395833 p = 7386537185240346459857715381835501419533088465984777861268951891482072249822526223542514664598394978163933836402581547418821954407062640385756448408431347 ans = (50712831100361370819145886978385347931029768, 9089234402520025586415667640120652372860183) high = [67523583999102391286646648674827012089888650576715333147417362919706349137337570430286202361838682309142789833, 70007105679729967877791601360700732661124470473944792680253826569739619391572400148455527621676313801799318422] enc = 6176615302812247165125832378994890837952704874849571780971393318502417187945089718911116370840334873574762045429920150244413817389304969294624001945527125 data = (high[0]<<146) + ans[0] secret = (data - c) * gmpy2.invert(a, p) % p secret = Tonelli_Shanks(secret, p) print(secret) flag = bytes_to_long(hashlib.sha512(b'%d'%(secret)).digest())^enc print(long_to_bytes(flag))
|