bambi6-service-postit

Simple Note-Taking A/D Service for BambiCTF6 in 2021
git clone https://git.sinitax.com/sinitax/bambi6-service-postit
Log | Files | Refs | README | LICENSE | sfeed.txt

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