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 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
| from Crypto.Util.number import * from sage.all import * from pwn import * from hashlib import sha256
def ch(c:int): c = str(c).encode() while 1: a = r.recvline() if b'Exit' in a: break r.sendlineafter(b'Your option:', c)
r = remote('39.106.16.204', 55066)
def solve_(m, x=0, n=True): r.sendlineafter(b"Enter 'e' for encryption or other to exit:", b'e') r.sendlineafter(b'Enter your message:', hex(m)[2:]) r.sendlineafter(b'Where do you want to interfere?', str(x).encode()) c_ = int(r.recvline().decode().split(':')[-1], 16) c = c_ * m if n: return c else: return c_
N = []; E = [] while 1: ch(1) r.recvline() m = 1337; m2 = 1337 ** 2; m3 = 727; m4 = 727 ** 2; m5 = 114514; m6 = 114514 ** 2; m7 = 12345678; m8 = 12345678 ** 2 c = solve_(m); c2 = solve_(m2); c3 = solve_(m3); c4 = solve_(m4); c5 = solve_(m5); c6 = solve_(m6); c7 = solve_(m7); c8 = solve_(m8) n = GCD(c ** 2 - c2, c3 ** 2 - c4) n = GCD(n, c5 ** 2 - c6) n = GCD(n, c7 ** 2 - c8) e_1, x = 1, 0 while (x:= x + 1) and x <= 2048: print(f'x = {x}') c_ = solve_(m, x, n=False) for i in [-1, 1]: c__ = c_ * pow(m, i * 2**x, n) % n if c__ == c % n: e_1 += (i + 1) // 2 << x break if pow(m, e_1, n) == c % n: e = e_1; N.append(n); E.append(e) else: print('error') print(f'len = {len(N)}') r.sendlineafter(b"Enter 'e' for encryption or other to exit:", b'x') if len(N) == 10: break
def solve_d(N, E): M = matrix(len(N)+1) D = 2 ** 1024 M[0, 0] = D for i in range(1, len(N) + 1): M[i, i] = -N[i - 1] M[0, i] = E[i - 1]
mm = M.LLL() d_ = abs(mm[0][0])//D return d_
d = sqrt(sqrt(solve_d(N, E))) print(d)
class ECDSA: def __init__(self, d): self.p = 0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF self.a = 0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC self.b = 0x28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93 self.n = 0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123 self.Gx = 0x32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7 self.Gy = 0xBC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0 self.G = (self.Gx,self.Gy)
self.d = d self.Q = self.mul(self.d,self.G) assert self.is_on_curve(self.Q)
def is_on_curve(self, point): if point is None: return True x, y = point return (y**2 - x**3 - self.a * x - self.b) % self.p == 0
def add(self, p1, p2): if p1 is None or p2 is None: return p1 if p2 is None else p2
x1, y1 = p1 x2, y2 = p2
if x1 == x2 and y1 != y2: return None if x1 == x2: m = (3 * x1 * x1 + self.a) * pow(2 * y1, -1, self.p) % self.p else: m = (y2 - y1) * pow((x2 - x1) % self.p, -1, self.p) % self.p x3 = (m * m - x1 - x2) % self.p y3 = (m * (x1 - x3) - y1) % self.p return (x3, y3)
def mul(self, k:int, P:tuple[int,int]): if P is None: return None R = None while k > 0: if k & 1: R = self.add(R, P) P = self.add(P,P) k >>= 1 return R
def generate_key_pair(self): return self.d,self.Q
def sign(self, message): while True: k = randint(1, self.n - 1) P = self.mul(k, self.G) if P is None: continue r = P[0] % self.n if r == 0: continue
s = (pow(k,-1,self.n) * (int.from_bytes(sha256(message).digest())+ self.d * r)) % self.n if s != 0: return (r, s)
def verify(self, m:bytes, r:int,s:int): if not (1 <= r < self.n and 1 <= s < self.n): return False u1 = (int.from_bytes(sha256(m).digest()) * pow(s,-1,self.n)) % self.n u2 = (r * pow(s,-1,self.n)) % self.n
if u1 == 0 or u2 == 0: return False
P = self.add(self.mul(u1, self.G), self.mul(u2, self.Q)) return P[0] % self.n == r
dsa = ECDSA(int(d)) while 1: for i in range(256): ch(2) msg = f'nctf2024-{hex(i)[2:].zfill(2)}'.encode() rr, ss = dsa.sign(msg) r.sendlineafter(b'Give me your signature:', str(rr).encode() + b' ' + str(ss).encode()) a = r.recvline() if b'Wrong!' not in a: print(a) break print(a)
|