def open_point_with_mac(players): global elliptic_time 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) t0 = time.time() for p in players: p.open_point = add(cp, cq, cn, p.broadcast, p.other) p.open_left = mulp(cp, cq, cn, p.open_point, p.alpha) p.open_right = mulp(cp, cq, cn, g, p.temp[1]) p.set_broadcast((p.open_left, p.open_right)) t1 = time.time() elliptic_time += t1 - t0 broadcast(players) t0 = time.time() for p in players: p.open_left = add(cp, cq, cn, p.broadcast[0], p.other[0]) p.open_right = add(cp, cq, cn, p.broadcast[1], p.other[1]) assert p.open_left == p.open_right #print(p.open_left == p.open_right) t1 = time.time() elliptic_time += t1 - t0
def validate(sign, hash_message, overall_public_key): cn, cp, cq, g, n = Player.cn, Player.cp, Player.cq, Player.g, Player.n r, s = sign s_inv = inv(s, n) p1 = mulp(cp, cq, cn, g, (s_inv * hash_message) % n) p2 = mulp(cp, cq, cn, overall_public_key, (s_inv * r) % n) p = add(cp, cq, cn, p1, p2) assert p[0] == r
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 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 ecdsa_sign_parallel(players, need_check=False): global elliptic_time cn, cp, cq, g, n = Player.cn, Player.cp, Player.cq, Player.g, Player.n for p in players: p.k = p.share_values.pop() p.gamma = p.share_values.pop() p.set_multiply_x([p.k, p.k]) p.set_multiply_y([p.gamma, p.private_key]) multiply_beaver_parallel(players, 2, need_check) for p in players: p.delta = p.list_product[0] p.sigma = p.list_product[1] 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)) t0 = time.time() for p in players: p.k_inv_point = mulp(cp, cq, cn, g, p.k_inv[0]) p.set_broadcast((p.k_inv_point, p.k_inv[1])) t1 = time.time() elliptic_time += t1 - t0 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) validate(players[0].sign, players[0].hash_message, players[0].overall_public_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 ecdsa_keygen(players): 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.public_key = mulp(cp, cq, cn, g, p.private_key[0]) p.set_broadcast(p.public_key) broadcast(players) for p in players: p.overall_public_key = add(cp, cq, cn, p.broadcast, p.other)
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 {} not implemented".format(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 {} not suitable for signing".format(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