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
|
#!/usr/bin/env python3
import random
from os import listdir
from typing import List, Tuple
from gmpy2 import iroot, mpz # type: ignore
from util import bytes2int, int2bytes
keys: List["RSA"] = []
class RSA:
def __init__(self, data: Tuple[int, int, int]):
self.e = data[0]
self.d = data[1]
self.n = data[2]
def encode(self) -> Tuple[str, str, str]:
return (str(self.e), str(self.d), str(self.n))
@classmethod
def decode(cls, params: Tuple[str, str, str]) -> "RSA":
return cls((int(params[0]), int(params[1]), int(params[2])))
def load_keys() -> None:
for file in listdir("keys"):
params = tuple(int(v) for v in open(f"keys/{file}").read().split())
keys.append(RSA((params[0], params[1], params[2])))
assert len(keys) > 0
def get_key() -> "RSA":
assert len(keys) != 0
return random.choice(keys)
def sign(m: bytes, rsa: "RSA") -> int:
return int(pow(bytes2int(m), rsa.d, rsa.n))
def fake_sign(m: bytes, exp: int, mod: int) -> int:
assert exp == 3
padm = m + b"\x00" * (1 + 2 * 18)
n = mpz(bytes2int(padm))
sig, true_root = iroot(n, 3)
if not true_root:
sig += 1
assert int2bytes(int(pow(sig, exp, mod))).startswith(m + b"\x00")
return sig
|