def test_verify_and_deposit_fails_with_incorrect_public_key( proxy_contract, deposit_contract, withdrawal_credentials, signature, deposit_data_root, public_key_witness, signature_witness, deposit_amount, assert_tx_failed, seed, ): assert ( int.from_bytes( deposit_contract.functions.get_deposit_count().call(), byteorder="little" ) == 0 ) assert ( deposit_contract.functions.get_deposit_root().call().hex() == EMPTY_DEPOSIT_ROOT ) another_seed = "another-secret".encode() assert seed != another_seed another_private_key = G2ProofOfPossession.KeyGen(another_seed) public_key = G2ProofOfPossession.SkToPk(another_private_key) group_element = pubkey_to_G1(public_key) normalized_group_element = normalize(group_element) public_key_witness = normalized_group_element[1] public_key_witness_repr = _convert_int_to_fp_repr(public_key_witness) signature_witness_repr = _convert_int_to_fp2_repr(signature_witness) amount_in_wei = deposit_amount * 10 ** 9 txn = proxy_contract.functions.verifyAndDeposit( public_key, withdrawal_credentials, signature, deposit_data_root, public_key_witness_repr, signature_witness_repr, ) assert_tx_failed(lambda: txn.transact({"value": amount_in_wei})) assert ( int.from_bytes( deposit_contract.functions.get_deposit_count().call(), byteorder="little" ) == 0 )
def encrypt(cls, *, secret: bytes, password: str, path: str='', kdf_salt: bytes=randbits(256).to_bytes(32, 'big'), aes_iv: bytes=randbits(128).to_bytes(16, 'big')) -> 'Keystore': """ Encrypt a secret (BLS SK) as an EIP 2335 Keystore. """ keystore = cls() keystore.uuid = str(uuid4()) keystore.crypto.kdf.params['salt'] = kdf_salt decryption_key = keystore.kdf( password=cls._process_password(password), **keystore.crypto.kdf.params ) keystore.crypto.cipher.params['iv'] = aes_iv cipher = AES_128_CTR(key=decryption_key[:16], **keystore.crypto.cipher.params) keystore.crypto.cipher.message = cipher.encrypt(secret) keystore.crypto.checksum.message = SHA256(decryption_key[16:32] + keystore.crypto.cipher.message) keystore.pubkey = bls.SkToPk(int.from_bytes(secret, 'big')).hex() keystore.path = path return keystore
def OpBLS_PrivateToPublic(arg): op = json.loads(arg) private_key = to_int(op['priv']) if private_key > 115792089237316195423570985008687907853269984665640564039457584007913129639935: point = ['0', '0'] r = json.dumps(point) return bytes(r, 'utf-8') private_key %= 52435875175126190479447740508185965837690552500527637822603658699938581184513 if private_key == 0: point = ['0', '0'] r = json.dumps(point) return bytes(r, 'utf-8') public_key = bls_pop.SkToPk(private_key) point = pubkey_to_G1(public_key) point = [str(point[0]), str(point[1])] r = json.dumps(point) return bytes(r, 'utf-8')
def test_bls_signature_is_valid_fails_with_invalid_public_key( proxy_contract, seed, signing_root, signature, signature_witness ): another_seed = "another-secret".encode() assert seed != another_seed another_private_key = G2ProofOfPossession.KeyGen(another_seed) public_key = G2ProofOfPossession.SkToPk(another_private_key) group_element = pubkey_to_G1(public_key) normalized_group_element = normalize(group_element) public_key_witness = normalized_group_element[1] public_key_witness_repr = _convert_int_to_fp_repr(public_key_witness) signature_witness_repr = _convert_int_to_fp2_repr(signature_witness) assert not proxy_contract.functions.blsSignatureIsValid( signing_root, public_key, signature, public_key_witness_repr, signature_witness_repr, ).call()
def withdrawal_pk(self) -> bytes: return bls.SkToPk(self.withdrawal_sk)
def signing_pk(self) -> bytes: return bls.SkToPk(self.signing_sk)
from py_ecc.bls import G2ProofOfPossession as bls # Enough keys for 256 validators per slot in worst-case epoch length privkeys = [i + 1 for i in range(32 * 256)] pubkeys = [bls.SkToPk(privkey) for privkey in privkeys] pubkey_to_privkey = { pubkey: privkey for privkey, pubkey in zip(privkeys, pubkeys) }
def SkToPk(SK: int) -> BLSPubkey: return G2ProofOfPossession.SkToPk(SK)
def test_pop(sk): pk = G2ProofOfPossession.SkToPk(sk) proof = G2ProofOfPossession.PopProve(sk) assert G2ProofOfPossession.PopVerify(pk, proof)
def compute_aggregate_signature(SKs, message): PKs = [G2ProofOfPossession.SkToPk(sk) for sk in SKs] signatures = [G2ProofOfPossession.Sign(sk, message) for sk in SKs] aggregate_signature = G2ProofOfPossession.Aggregate(signatures) return (PKs, aggregate_signature)
'signature_points,result_point', [ ([multiply(G1, 2), multiply(G1, 3)], multiply(G1, 2 + 3)), ([multiply(G1, 42), multiply(G1, 69)], multiply(G1, 42 + 69)), ] ) 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 @pytest.mark.parametrize( 'PK, message, signature, result', [ (G2ProofOfPossession.SkToPk(1), sample_message, G2ProofOfPossession.Sign(1, sample_message), True), (None, sample_message, Z2_SIGNATURE, False), # wrong type (Z1_PUBKEY, sample_message, Z2_SIGNATURE, False), ] ) def test_verify(PK, message, signature, result): assert G2ProofOfPossession.Verify(PK, message, signature) == result @pytest.mark.parametrize( 'PKs, aggregate_signature, message, result', [ (*compute_aggregate_signature(SKs=[1], message=sample_message), sample_message, True), (*compute_aggregate_signature(SKs=tuple(range(1, 5)), message=sample_message), sample_message, True), ([], Z2_SIGNATURE, sample_message, False), ([G2ProofOfPossession.SkToPk(1), Z1_PUBKEY], G2ProofOfPossession.Sign(1, sample_message), sample_message, False),
@pytest.mark.parametrize('signature_points,result_point', [ ([multiply(G1, 2), multiply(G1, 3)], multiply(G1, 2 + 3)), ([multiply(G1, 42), multiply(G1, 69)], multiply(G1, 42 + 69)), ]) 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 @pytest.mark.parametrize( 'PK, message, signature, result', [ (G2ProofOfPossession.SkToPk(1), sample_message, G2ProofOfPossession.Sign(1, sample_message), True), (None, sample_message, Z2_SIGNATURE, False), # wrong type (Z1_PUBKEY, sample_message, Z2_SIGNATURE, False), ]) def test_verify(PK, message, signature, result): assert G2ProofOfPossession.Verify(PK, message, signature) == result @pytest.mark.parametrize('PKs, aggregate_signature, message, result', [ (*compute_aggregate_signature(SKs=[1], message=sample_message), sample_message, True), (*compute_aggregate_signature( SKs=tuple(range(1, 5)), message=sample_message), sample_message, True), ([], Z2_SIGNATURE, sample_message, False), ([G2ProofOfPossession.SkToPk(1), Z1_PUBKEY
def test_fast_aggregate_verify(SKs, message): PKs = [G2ProofOfPossession.SkToPk(sk) for sk in SKs] signatures = [G2ProofOfPossession.Sign(sk, message) for sk in SKs] aggregate_signature = G2ProofOfPossession.Aggregate(signatures) assert G2ProofOfPossession.FastAggregateVerify(PKs, message, aggregate_signature)