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 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 open_point_with_mac(players): n, cp, cq, cn, g = Player.n, Player.cp, Player.cq, Player.cn, Player.g for p in players: p.temp = p.broadcast p.set_broadcast(p.temp[0]) broadcast(players) for p in players: p.open_point = add(cp, cq, cn, p.broadcast, p.other) p.set_broadcast(mulp(cp,cq, cn, p.open_point, p.alpha)) broadcast(players) for p in players: p.open_left = add(cp,cq,cn, p.broadcast, p.other) p.set_broadcast(mulp(cp,cq,cn, g, p.temp[1])) broadcast(players) for p in players: p.open_right = add(cp,cq,cn,p.broadcast, p.other)
def ecdsa_sign(players,need_check=False): cn,cp,cq,g, n = Player.cn, Player.cp, Player.cq, Player.g, Player.n for p in players: p.private_key = p.share_values.pop() p.k = p.share_values.pop() p.gamma = p.share_values.pop() p.set_multiply_x(p.k) p.set_multiply_y(p.gamma) multiply_beaver(players, need_check) for p in players: p.delta = p.product p.set_multiply_x(p.k) p.set_multiply_y(p.private_key) multiply_beaver(players, need_check) for p in players: p.sigma = p.product p.set_broadcast(p.delta) open_share_with_mac(players) for p in players: p.delta_inv = inv(p.open_value, n) p.k_inv = tuple((p.delta_inv * p.gamma[i])%n for i in range(2)) p.k_inv_point = mulp(cp, cq, cn, g, p.k_inv[0]) p.set_broadcast((p.k_inv_point, p.k_inv[1])) open_point_with_mac(players) for p in players: p.r_open = p.open_point[0] p.s = tuple(p.hash_message * p.k[i] + p.r_open * p.sigma[i] for i in range(2)) p.set_broadcast(tuple(p.s)) open_share_with_mac(players) for p in players: p.sign = (p.r_open, p.open_value)
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 gen_public_key(self): """ Generate a public key. """ self.public_key = ec.mulp( self.params["a"], self.params["b"], self.params["p"], self.basepoint, self.private_key )
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 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 gen_secret(self, other_key): """ Check to make sure the public key is valid, then combine it with the private key to generate a shared secret. """ if self.check_public_key(other_key): self.shared_secret = ec.mulp( self.params["a"], self.params["b"], self.params["p"], other_key, self.private_key ) else: raise Exception("Invalid public key.")
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 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 if n > 0: d = randkey(bits, n) q = mulp(cp, cq, cn, g, d) return (bits, q), (bits, d) else: raise ValueError
def sign(self, h, priv, k=None): while h > self.N: h >>= 1 r = s = 0 while r == 0 or s == 0: if k == None: k = (getrandbits(self.bits) % (self.N - 1)) + 1 kinv = inv(k, self.N) kg = mulp(self.a, self.b, self.p, self.G, k) r = kg[0] % self.N if r == 0: continue s = (kinv * (h + r * priv)) % self.N return self.int2bytes(r) + self.int2bytes(s)
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 public_key_for(self, priv): return mulp(self.a, self.b, self.p, self.G, priv)
def dh_z(self, priv, pub): return self.int2bytes(mulp(self.a, self.b, self.p, pub, priv)[0])
def dh_z(self, priv, pub): return self.int2bytes( mulp(self.a, self.b, self.p, pub, priv)[0] )
def public_key_for(self, priv): return mulp(self.a, self.b, self.p, self.G, priv )
def key_pair(self): priv = (getrandbits(self.bits) % (self.N - 1)) + 1 pub = mulp(self.a, self.b, self.p, self.G, priv) return priv, pub
def publicKeyFor(self, priv): return mulp(self.a, self.b, self.p, self.G, priv)
#!/usr/bin/python# coding=utf-8 ## Elliptic Curve Digital Signature Algorithm (ECDSA)## COPYRIGHT (c) 2010 by Toni Mattis <*****@*****.**># import hashlib from os import urandom from elliptic import inv, mulf, mulp, muladdp, elementfrom curves import get_curve, implemented_keys def randkey(bits, n): '''Generate a random number (mod n) having the specified bit length''' rb = urandom(bits / 8 + 8) # + 64 bits as recommended in FIPS 186-3 c = 0 for r in rb: c = (c << 8) | ord(r) return (c % (n - 1)) + 1 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 supported_keys(): '''Return a list of all key sizes implemented for signing''' return implemented_keys(True) 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 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 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 truncate(h, hmax): '''Truncate a hash to the bit size of hmax''' while h > hmax: h >>= 1 return h 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 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 hash_sign(s, dk, hashfunc='sha256'): h = int(hashlib.new(hashfunc, s).hexdigest(), 16) return (hashfunc,) + sign(h, dk) def hash_verify(s, sig, qk): h = int(hashlib.new(sig[0], s).hexdigest(), 16) return verify(h, sig[1:], qk) if __name__ == '__main__': import time testh1 = 0x0123456789ABCDEF testh2 = 0x0123456789ABCDEE
def publicKeyFor(self, priv): return mulp(self.a, self.b, self.p, self.G, priv )