def test_verify_decryption_key(): sk1, sk2 = random_scalar(), random_scalar() pk1, pk2 = multiply(G1, sk1), multiply(G1, sk2) shared_key = vss.shared_key(sk1, pk2) chal, resp = vss.shared_key_proof(sk1, pk2) assert vss.dleq_verify(G1, pk1, pk2, shared_key, chal, resp) assert contract.verify_decryption_key(shared_key, [chal, resp], pk1, pk2)
def test_dleq(): sk1 = random_scalar(seed=1) sk2 = random_scalar(seed=2) pk1 = multiply(G1, sk1) pk2 = multiply(G1, sk2) shared_key = multiply(pk2, sk1) assert shared_key == multiply(pk1, sk2) challenge, response = vss.dleq(G1, pk1, pk2, shared_key, alpha=sk1) assert vss.dleq_verify(G1, pk1, pk2, shared_key, challenge, response) response += 1 assert not vss.dleq_verify(G1, pk1, pk2, shared_key, challenge, response)
def dleq(g1: PointG1, h1: PointG1, g2: PointG1, h2: PointG1, alpha: int) -> Tuple[int, int]: """ dleq... discrete logarithm equality proofs that the caller knows alpha such that h1 = g1**alpha and h2 = g2**alpha without revealing alpha """ w = random_scalar() a1 = multiply(g1, w) a2 = multiply(g2, w) c = soliditySha3( # pylint: disable=E1120 abi_types=["uint256"] * 12, # 12, values=[ a1[0], a1[1], a2[0], a2[1], g1[0], g1[1], h1[0], h1[1], g2[0], g2[1], h2[0], h2[1], ], ) c = int.from_bytes(c, "big") r = (w - alpha * c) % CURVE_ORDER return c, r
def test_verification(): n = 5 t = 3 secret = random_scalar() shares, public_coefficients = vss.share(secret, n, t) for id, share in zip(range(1, n + 1), shares): assert vss.verify(id, share, public_coefficients)
def test_sharing(): n = 5 t = 3 secret = random_scalar() shares, _ = vss.share(secret, n, t) indexed_shares = list(zip(range(1, n + 1), shares)) for selected_shares in itertools.combinations(indexed_shares, t): recovered_secret = vss.recover(indexed_shares) assert secret == recovered_secret
def test_sk_knowledge_with_account(): sk = random_scalar() pk = multiply(G1, sk) challenge, response = vss.prove_sk_knowledge( sk, pk, account="0xe3D320ea4AF151Fc309568884C217f634E9c38f5") assert vss.verify_sk_knowledge( pk, challenge, response, account="0xe3D320ea4AF151Fc309568884C217f634E9c38f5")
def keygen(seed=None): """ generated a new bls keypair """ if seed is None: sk = random_scalar() else: sk = hash_to_scalar(seed) # compute the corresponding public key # for bls_pk, we use neg(G2) which flips the sign of the y coordinates to be compatible with the ethereum # implementation of the pairing check bls_pk = multiply(neg(G2), sk) return sk, bls_pk
def test_verify_sk_knowledge(): sk = random_scalar() pk = multiply(G1, sk) addr = w3.eth.accounts[0] proof = vss.prove_sk_knowledge(sk, pk, addr) assert vss.verify_sk_knowledge(pk, proof[0], proof[1], addr) print("sk", sk) print("pk", pk) print("account", addr) print("proof", proof) assert contract.verify_sk_knowledge(pk, proof)
def prove_sk_knowledge(sk: int, pk: PointG1, account: str = None) -> Tuple[int, int]: """ proofs that the caller knows the discreate logarithm of pk to the generator g1 (and that links the proof to an Ethereum account if provided) """ w = random_scalar() t = multiply(G1, w) types = ["uint256"] * 6 values = list(G1 + pk + t) if account is not None: types.append("address") values.append(account) c = soliditySha3(abi_types=types, values=values) c = int.from_bytes(c, "big") r = (w - sk * c) % CURVE_ORDER return c, r
def test_all_to_all_signature_aggregation(): n = 5 t = 3 sks = [crypto.random_scalar() for _ in range(n)] master_sk = sum(sks) % crypto.CURVE_ORDER msg = 'test message' sig = bls.sign(master_sk, msg) agg_sks = [0] * n for sk in sks: sk_shares, _ = vss.share(sk, n, t) for i, sk_share in enumerate(sk_shares): agg_sks[i] += sk_share partial_sigs = [bls.sign(psk, msg) for psk in agg_sks] indexed_partial_sigs = [(i, sig) for i, sig in zip(range(1, n + 1), partial_sigs)] for selected_partial_sigs in itertools.combinations(indexed_partial_sigs, t): aggregated_sig = vss.recover_point(selected_partial_sigs) assert sig == aggregated_sig
def test_sk_knowledge_invalid_response(): sk = random_scalar() pk = multiply(G1, sk) challenge, response = vss.prove_sk_knowledge(sk, pk) response += 1 assert not vss.verify_sk_knowledge(pk, challenge, response)