def validate_public_key(qk): '''Check whether public key qk is valid''' bits, q = qk x, y = q bits, cn, n, cp, cq, g = get_curve(bits) return q and 0 < x < cn and 0 < y < cn and \ element(q, cp, cq, cn) and (mulp(cp, cq, cn, q, n) == None)
def match_keys(qk, dk): '''Check whether dk is the private key belonging to qk''' bits, d = dk bitz, q = qk if bits == bitz: bits, cn, n, cp, cq, g = get_curve(bits) return mulp(cp, cq, cn, g, d) == q else: return False
def decrypt(message, kg, dk, decrypter=Rabbit): '''Decrypt a message using temp. public key kg and private key dk''' bits, d = dk try: bits, cn, n, cp, cq, g = get_curve(bits) except KeyError: raise ValueError("Key size %s not implemented" % bits) sg = mulp(cp, cq, cn, kg, d) # shared secret d*(k*G) = k*d*G return decrypter(enc_long(sg[0])).decrypt(message)
def keypair(bits): '''Generate a new keypair (qk, dk) with dk = private and qk = public key''' try: bits, cn, n, cp, cq, g = get_curve(bits) except KeyError: raise ValueError("Key size %s not implemented" % bits) if n > 0: d = randkey(bits, n) q = mulp(cp, cq, cn, g, d) return (bits, q), (bits, d) else: raise ValueError("Key size %s not suitable for signing" % bits)
def sign(h, dk): '''Sign the numeric value h using private key dk''' bits, d = dk bits, cn, n, cp, cq, g = get_curve(bits) h = truncate(h, cn) r = s = 0 while r == 0 or s == 0: k = randkey(bits, cn) kinv = inv(k, n) kg = mulp(cp, cq, cn, g, k) r = kg[0] % n if r == 0: continue s = (kinv * (h + r * d)) % n return r, s
def encrypt(message, qk, encrypter=Rabbit): '''Encrypt a message using public key qk => (ciphertext, temp. pubkey)''' bits, q = qk try: bits, cn, n, cp, cq, g = get_curve(bits) if not n: raise ValueError("Key size %s not suitable for encryption" % bits) except KeyError: raise ValueError("Key size %s not implemented" % bits) k = random.randint(1, n - 1) # temporary private key k kg = mulp(cp, cq, cn, g, k) # temporary public key k*G sg = mulp(cp, cq, cn, q, k) # shared secret k*Q = k*d*G return encrypter(enc_long(sg[0])).encrypt(message), kg
def verify(h, sig, qk): '''Verify that 'sig' is a valid signature of h using public key qk''' bits, q = qk try: bits, cn, n, cp, cq, g = get_curve(bits) except KeyError: return False h = truncate(h, cn) r, s = sig if 0 < r < n and 0 < s < n: w = inv(s, n) u1 = (h * w) % n u2 = (r * w) % n x, y = muladdp(cp, cq, cn, g, u1, q, u2) return r % n == x % n return False
def test_perf(bits, rounds=50): '''-> (key generations, signatures, verifications) / second''' h = 0x0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF d = get_curve(bits) t = time.time() for i in xrange(rounds): qk, dk = keypair(bits) tgen = time.time() - t t = time.time() for i in xrange(rounds): s = sign(0, dk) tsign = time.time() - t t = time.time() for i in xrange(rounds): verify(0, s, qk) tver = time.time() - t return rounds / tgen, rounds / tsign, rounds / tver
def validate_private_key(dk): '''Check whether private key dk is valid''' bits, d = dk bits, cn, n, cp, cq, g = get_curve(bits) return 0 < d < cn
def __init__(self): bits, self.c_n, n, self.c_p, self.c_q, (x, y) = get_curve(256)