def get_aggregate_key(keys): r = b.Z1 for i, key in keys.items(): key_point = pubkey_to_G1(key) coef = 1 for j in keys: if j != i: coef = -coef * (j + 1) * prime_field_inv( i - j, b.curve_order) % b.curve_order r = b.add(r, b.multiply(key_point, coef)) return G1_to_pubkey(r)
def test_aggregate_pks(signature_points, result_point): signatures = [G1_to_pubkey(pt) for pt in signature_points] result_signature = G1_to_pubkey(result_point) assert G2ProofOfPossession._AggregatePKs(signatures) == result_signature
def benchmark_dkg(): num_of_part = 100 logging.debug("creating %d participants via DKG", num_of_part) ids = range(1, num_of_part) start = time.time() dkg = crypto.DKG(config.POOL_THRESHOLD, ids) dkg.run() sks = dkg.calculate_participants_sks() logging.debug(" Group sk: %s", dkg.group_sk()) logging.debug(" Group sig: %s", crypto.readable_sig(crypto.sign_with_sk(dkg.group_sk(),config.TEST_EPOCH_MSG)).hex()) end = time.time() logging.debug("dkg: %f sec", (end-start)) logging.debug(" Group pk: %s", crypto.readable_pk(dkg.group_pk()).hex()) logging.debug(" real Group pk: %s", crypto.readable_pk(crypto.pk_from_sk(dkg.group_sk())).hex()) start = time.time() sigs = {} pks = {} for sk in sks: sig = crypto.sign_with_sk(sks[sk], config.TEST_EPOCH_MSG) pk = crypto.pk_from_sk(sks[sk]) sigs[sk] = sig pks[sk] = pk end = time.time() logging.debug("sign and prepare pks: %f sec", (end - start)) # reconstruct sig and pk start=time.time() recon_pk = crypto.reconstruct_pk(pks) recon_sig = crypto.reconstruct_group_sig(sigs) end = time.time() logging.debug("reconstruct sk/pk: %f sec", (end - start)) recon_pk = crypto.readable_pk(recon_pk) logging.debug("pk after reconstruction: %s", recon_pk.hex()) recon_sig = crypto.readable_sig(recon_sig) logging.debug("sig after reconstruction: %s", recon_sig.hex()) ## redistribuite start = time.time() re_distro_shares = {} re_distro_comm = {} for p_indx in sks: sk = sks[p_indx] redistro = crypto.Redistribuition(config.POOL_THRESHOLD -1, sk, ids) # following Shamir's secret sharing, degree is threshold - 1 shares, commitment = redistro.generate_shares() for i in ids: if i not in re_distro_shares: re_distro_shares[i] = {} re_distro_shares[i][p_indx] = shares[i] re_distro_comm[p_indx] = commitment sk_per_id = {} pk_per_id = {} for idx in ids: sk_per_id[idx] = crypto.reconstruct_sk(re_distro_shares[idx]) pk_per_id[idx] = crypto.pk_from_sk(sk_per_id[idx]) group_pk_after_redistro = G1_to_pubkey(crypto.reconstruct_pk(pk_per_id)) logging.debug(" Group pk after redistro: %s", group_pk_after_redistro.hex()) end = time.time() logging.debug("redistro: %f sec", (end - start))
# Alternatively, this can be used to turn an already existing validator into a secret shared validator; # however, if the key was compromised before the split happened, it does not help. from python_ibft.bls_threshold import eval_poly, generate_keys import sys import random import base64 import py_ecc.optimized_bls12_381 as b from py_ecc.bls.g2_primatives import G1_to_pubkey if len(sys.argv) != 2: print("Usage: python privkey_to_threshold.py {privkey_as_hex}") sys.exit(1) privkey = int(sys.argv[1], base=16) printable_pubkey = G1_to_pubkey(b.multiply(b.G1, privkey)).hex() print("Generating threshold keys for validator {0}".format(printable_pubkey)) coefs = [privkey] + [random.randint(0, b.curve_order) for i in range(2)] privkeys = [eval_poly(x, coefs) for x in range(1,5)] printable_pubkeys = [G1_to_pubkey(b.multiply(b.G1, p)).hex() for p in privkeys] printable_privkeys = [base64.encodebytes(p.to_bytes(32, byteorder="big")).decode()[:-1] for p in privkeys] for i, p in enumerate(zip(printable_pubkeys, printable_privkeys)): print("Pubkey {0}:".format(i), p[0]) print("Privkey {0}:".format(i), p[1]) print() print("Copy this into validators.json:")
) from py_ecc.optimized_bls12_381 import ( add, curve_order, final_exponentiate, G1, multiply, neg, pairing, Z1, Z2, ) from py_ecc.bls.ciphersuites import G2ProofOfPossession as bls priv = 100 pub = bls.SkToPk(priv) print(pub.hex()) x = pubkey_to_G1(pub) print(x) x2 = add(x, x) print(x2) agg = G1_to_pubkey(x2) print(agg.hex()) v = pubkey_to_G1(agg) print(v)
def readable_pk(optimized_pk): return G1_to_pubkey(optimized_pk)
def generate_keys(n_parties, t): coefs = [random.randint(0, b.curve_order - 1) for i in range(t + 1)] aggregate_public = G1_to_pubkey(b.multiply(b.G1, coefs[0])) private = [eval_poly(x, coefs) for x in range(1, n_parties + 1)] public = [G1_to_pubkey(b.multiply(b.G1, x)) for x in private] return aggregate_public, public, private
def test_G1_pubkey_encode_decode(): G1_point = multiply(G1, 42) pubkey = G1_to_pubkey(G1_point) assert (normalize(pubkey_to_G1(pubkey)) == normalize(G1_point))