import hashlib import ecdsa from Crypto.Cipher import AES from Crypto.Util.Padding import pad from Crypto.Util.number import *
g = ecdsa.NIST256p.generator order = g.order()
E = g.curve() p = Integer(E.p()) F = GF(p) E = EllipticCurve(F, [E.a(), E.b()]) G = E([g.x(), g.y()]) q = Integer(order)
s = 98064531907276862129345013436610988187051831712632166876574510656675679745081 r = 9821122129422509893435671316433203251343263825232865092134497361752993786340 cipher = b'\xf3#\xff\x17\xdf\xbb\xc0\xc6v\x1bg\xc7\x8a6\xf2\xdf~\x12\xd8]\xc5\x02Ot\x99\x9f\xf7\xf3\x98\xbc\x045\x08\xfb\xce1@e\xbcg[I\xd1\xbf\xf8\xea\n-'
msg = b'welcome to n1ctf2023!' hm = bytes_to_long(hashlib.sha256(msg).digest()) R = E.lift_x(r) Pk = r.inverse_mod(q) * (s * R - hm * G)
load('./copper.sage') A = (hm - 2^128 * s * (hm>>128)) B = 2^128 * r - s C = r R_ = Integers(q) P.<dh, dl> = PolynomialRing(R_) f = A + B * (2^127+dh) + C * dl # 2^127 -> d is 256 bits (if not work, guess more bits of d...) res = small_roots(f, [2^127, 2^128], m=5, d=3) print(res) dh = Integer(res[0][0]) if dh.nbits() > 127: dh = -dh % q dl = Integer(res[0][1]) if dl.nbits() > 128: dl = -dl % q print(dh, dl) d = 2^128 * (2^127+dh) + dl k = 2^128 * (hm>>128) + (2^127+dh) assert d * G == Pk assert k * G == R
aes = AES.new(long_to_bytes(d), mode=AES.MODE_ECB) flag = aes.decrypt(cipher) print(flag)
defV(k, N, A=5): M = matrix(Zmod(N), [ [A, -1], [1, 0] ]) v = vector(Zmod(N), [A, 2]) vk = M^k * v return Integer(vk[1])
deffactorN(N): A = 5 whileTrue: v2n = V(2*N, N, A) g = gcd(v2n-2, N) print('[Log] %d - %d' % (A, g)) if g.nbits() >= 256and is_prime(g): r = g q = (r+1) // 2 p = N // (q * r) if p * q * r == N: return p, q, r A = next_prime(A)
defcheck_order_k(fN, k): p, q, r = fN Ep = EllipticCurve(GF(p), [3, 7]) Eq = EllipticCurve(GF(q), [3, 7]) Er = EllipticCurve(GF(r), [3, 7]) for Ex in (Ep, Eq, Er): if Ex.order() % k != 0: returnFalse returnTrue
defEN_random_element_k(fN, k): p, q, r = fN Ep = EllipticCurve(GF(p), [3, 7]) Eq = EllipticCurve(GF(q), [3, 7]) Er = EllipticCurve(GF(r), [3, 7]) Ps = [(Ex.order() // k) * Ex.random_element() for Ex in (Ep, Eq, Er)] x = crt([Integer(Px.xy()[0]) for Px in Ps], [p, q, r]) y = crt([Integer(Px.xy()[1]) for Px in Ps], [p, q, r]) return x, y
# Sage from Crypto.Cipher import AES from hashlib import md5
withopen('./out', 'r') as f: exec(f.read()) N, q, m = (256, 4197821, 15) PRq.<a> = PolynomialRing(Zmod(q)) Rq = PRq.quotient(a^N + 1, 'x') A = vector(Rq, [Rq(Ai) for Ai in A]) t = Rq(t) w = Rq(w) c = Rq(c) z = vector(Rq, [Rq(zi) for zi in z]) ct = bytes.fromhex(ct)
zm = z[-1] sim = [] for i inrange(m-1): sim += [(z[i] - zm) * c^(-1)] vsim = vector(Rq, sim + [Rq(0)]) sa = sum(list(A)) sm = (t - A * vsim) * sa^(-1)
s = [x + sm for x in sim] + [sm] s = vector(Rq, s)
aes = AES.new(md5(str(s).encode()).digest(), mode=AES.MODE_ECB) flag = aes.decrypt(ct) print(flag)