crypto.py (2322B)
1#!/usr/bin/env python3 2 3import random 4from hashlib import sha256 5 6from Crypto.Util import number 7from Crypto.Util.number import bytes_to_long, getPrime, inverse, long_to_bytes 8from gmpy2 import is_prime 9 10L = 1024 11N = 160 12 13def H(x): 14 if type(x) == int: 15 x = long_to_bytes(x) 16 return bytes_to_long(sha256(x).digest()) 17 18 19class DSAKey: 20 def __init__(self, p, q, g, x, y): 21 self.p = p 22 self.q = q 23 self.g = g 24 self.x = x 25 self.y = y 26 27 def vals(self): 28 return (self.p, self.q, self.g, self.x, self.y) 29 30 def dict(self): 31 return { 32 "p": self.p, 33 "q": self.q, 34 "g": self.g, 35 "x": self.x, 36 "y": self.y 37 } 38 39 def gen(L=L, N=N): 40 q = getPrime(N) 41 low = (1 << (L-1)) // q + 1 42 up = (1 << L) // q 43 while True: 44 factor = number.getRandomRange(low, up + 1) 45 p = factor * q + 1 46 if is_prime(p): break 47 while True: 48 g = pow(number.getRandomRange(2, p), factor, p) 49 if g != 1: 50 break 51 x = random.randint(1, q - 1) 52 y = pow(g, x, p) 53 return DSAKey(p, q, g, x, y) 54 55 def pubkey(self): 56 return DSAPubKey(self.p, self.q, self.g, self.y) 57 58 def sign(self, msg): 59 k = H(self.y) 60 r = pow(self.g, k, self.p) % self.q 61 s = inverse(k, self.q) * (H(msg) + r * self.x) % self.q 62 return r, s 63 64 65class DSAPubKey: 66 def __init__(self, p, q, g, y): 67 self.p = p 68 self.q = q 69 self.g = g 70 self.y = y 71 72 def vals(self): 73 return (self.p, self.q, self.g, self.y) 74 75 def dict(self): 76 return { 77 "p": self.p, 78 "q": self.q, 79 "g": self.g, 80 "y": self.y 81 } 82 83 def verify(self, msg, signature): 84 r, s = signature 85 w = inverse(s, self.q) 86 u1 = H(msg) * w % self.q 87 u2 = r * w % self.q 88 v = (pow(self.g, u1, self.p) * pow(self.y, u2, self.p) % self.p) % self.q 89 return v == r 90 91def gen_challenge(): 92 return bytes_to_long(random.randbytes(16)) 93 94if __name__ == "__main__": 95 msg = b"flag{test}" 96 97 privkey = DSAKey.gen() 98 signature = privkey.sign(msg) 99 100 pubkey = privkey.pubkey() 101 assert pubkey.verify(msg, signature)