crypto.py (1281B)
1#!/usr/bin/env python3 2 3import random 4from os import listdir 5from typing import List, Tuple 6 7from gmpy2 import iroot, mpz # type: ignore 8 9from util import bytes2int, int2bytes 10 11keys: List["RSA"] = [] 12 13 14class RSA: 15 def __init__(self, data: Tuple[int, int, int]): 16 self.e = data[0] 17 self.d = data[1] 18 self.n = data[2] 19 20 def encode(self) -> Tuple[str, str, str]: 21 return (str(self.e), str(self.d), str(self.n)) 22 23 @classmethod 24 def decode(cls, params: Tuple[str, str, str]) -> "RSA": 25 return cls((int(params[0]), int(params[1]), int(params[2]))) 26 27 28def load_keys() -> None: 29 for file in listdir("keys"): 30 params = tuple(int(v) for v in open(f"keys/{file}").read().split()) 31 keys.append(RSA((params[0], params[1], params[2]))) 32 assert len(keys) > 0 33 34 35def get_key() -> "RSA": 36 assert len(keys) != 0 37 return random.choice(keys) 38 39 40def sign(m: bytes, rsa: "RSA") -> int: 41 return int(pow(bytes2int(m), rsa.d, rsa.n)) 42 43 44def fake_sign(m: bytes, exp: int, mod: int) -> int: 45 assert exp == 3 46 padm = m + b"\x00" * (1 + 2 * 18) 47 n = mpz(bytes2int(padm)) 48 sig, true_root = iroot(n, 3) 49 if not true_root: 50 sig += 1 51 assert int2bytes(int(pow(sig, exp, mod))).startswith(m + b"\x00") 52 return sig