def signed_deposit(self) -> DepositData: domain = compute_deposit_domain(fork_version=self.fork_version) signing_root = compute_signing_root(self.deposit_message, domain) signed_deposit = DepositData(**self.deposit_message.as_dict(), signature=bls.Sign( self.signing_sk, signing_root)) return signed_deposit
def OpBLS_Sign(arg): op = json.loads(arg) private_key = to_int(op['priv']) if private_key == 0 or private_key >= 52435875175126190479447740508185965837690552500527637822603658699938581184513: return cleartext = bytes.fromhex(op['cleartext']) aug = bytes.fromhex(op['aug']) msg = aug + cleartext signature = bls_pop.Sign(private_key, msg) signature = signature_to_G2(signature) x = signature[0] / signature[2] y = signature[1] / signature[2] signature = [[str(x.coeffs[0]), str(y.coeffs[0])], [str(x.coeffs[1]), str(y.coeffs[1])]] public_key = bls_pop.SkToPk(private_key) point = pubkey_to_G1(public_key) point = [str(point[0]), str(point[1])] j = {} j['signature'] = signature j['pub'] = point r = json.dumps(j) return bytes(r, 'utf-8')
def signed_deposit(self) -> DepositData: domain = compute_deposit_domain( fork_version=self.chain_setting.GENESIS_FORK_VERSION) signing_root = compute_signing_root(self.deposit_message, domain) signed_deposit = DepositData(**self.deposit_message.as_dict(), signature=bls.Sign( self.signing_sk, signing_root)) return signed_deposit
def sign_deposit_data(deposit_data: DepositMessage, sk: int) -> Deposit: ''' Given a DepositMessage, it signs its root and returns a Deposit ''' assert bls.PrivToPub(sk) == deposit_data.pubkey domain = compute_domain() signing_root = compute_signing_root(deposit_data, domain) signed_deposit_data = Deposit(**deposit_data.as_dict(), signature=bls.Sign(sk, signing_root)) return signed_deposit_data
def test_verify_and_deposit_fails_with_incorrect_signature( proxy_contract, deposit_contract, bls_public_key, withdrawal_credentials, signature, deposit_data_root, public_key_witness, signature_witness, deposit_amount, assert_tx_failed, signing_root, bls_private_key, ): 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 ) public_key_witness_repr = _convert_int_to_fp_repr(public_key_witness) another_message = hashlib.sha256(b"not the signing root").digest() assert signing_root != another_message signature = G2ProofOfPossession.Sign(bls_private_key, another_message) group_element = signature_to_G2(signature) normalized_group_element = normalize(group_element) signature_witness = normalized_group_element[1] signature_witness_repr = _convert_int_to_fp2_repr(signature_witness) amount_in_wei = deposit_amount * 10 ** 9 txn = proxy_contract.functions.verifyAndDeposit( bls_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 test_bls_signature_is_valid_fails_with_invalid_signature( proxy_contract, bls_public_key, signing_root, public_key_witness, bls_private_key ): public_key_witness_repr = _convert_int_to_fp_repr(public_key_witness) another_message = hashlib.sha256(b"not the signing root").digest() assert signing_root != another_message signature = G2ProofOfPossession.Sign(bls_private_key, another_message) group_element = signature_to_G2(signature) normalized_group_element = normalize(group_element) signature_witness = normalized_group_element[1] signature_witness_repr = _convert_int_to_fp2_repr(signature_witness) assert not proxy_contract.functions.blsSignatureIsValid( signing_root, bls_public_key, signature, public_key_witness_repr, signature_witness_repr, ).call()
def test_fast_aggregate_verify(SKs, message): PKs = [G2ProofOfPossession.PrivToPub(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)
def Sign(SK: int, message: Hash32) -> BLSSignature: return G2ProofOfPossession.Sign(SK, message)
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),
def sign_all(keys, message): r = [] for key in keys: r.append(py_ecc_bls.Sign(key, message)) return r
@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 ], G2ProofOfPossession.Sign(1, sample_message), sample_message, False),
def Sign(SK, message): return bls.Sign(SK, message)
from py_ecc.bls import G2ProofOfPossession as bls from py_ecc.bls.g2_primatives import signature_to_G2 as _signature_to_G2 # Flag to make BLS active or not. Used for testing, do not ignore BLS in production unless you know what you are doing. bls_active = True STUB_SIGNATURE = b'\x11' * 96 STUB_PUBKEY = b'\x22' * 48 STUB_COORDINATES = _signature_to_G2(bls.Sign(0, b"")) def only_with_bls(alt_return=None): """ Decorator factory to make a function only run when BLS is active. Otherwise return the default. """ def runner(fn): def entry(*args, **kw): if bls_active: return fn(*args, **kw) else: return alt_return return entry return runner @only_with_bls(alt_return=True) def Verify(PK, message, signature): return bls.Verify(PK, message, signature) @only_with_bls(alt_return=True)