Esempio n. 1
0
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')
Esempio n. 2
0
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_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
    )
Esempio n. 4
0
 def AggregateVerify(
     signature: BLSSignature,
     public_keys: Tuple[BLSPubkey, ...],
     messages: Tuple[Hash32, ...],
 ) -> bool:
     return G2ProofOfPossession.AggregateVerify(public_keys, messages,
                                                signature)
Esempio n. 5
0
def OpBLS_Verify(arg):
    op = json.loads(arg)

    verified = False

    g1_x = to_int(op['g1_x'])
    g1_y = to_int(op['g1_y'])

    g1 = [FQ(g1_x), FQ(g1_y), FQ.one()]

    if is_on_curve(g1, b) == False:
        r = json.dumps(verified)
        return bytes(r, 'utf-8')

    g1 = G1_to_pubkey(g1)

    g2_v = to_int(op['g2_v'])
    g2_w = to_int(op['g2_w'])
    g2_x = to_int(op['g2_x'])
    g2_y = to_int(op['g2_y'])

    g2 = (FQ2((g2_v, g2_x)), FQ2((g2_w, g2_y)), FQ2.one())
    try:
        g2 = G2_to_signature(g2)
    except:
        r = json.dumps(verified)
        return bytes(r, 'utf-8')

    msg = bytes.fromhex(op['cleartext'])

    verified = bls_pop.Verify(g1, msg, g2)

    r = json.dumps(verified)
    return bytes(r, 'utf-8')
Esempio n. 6
0
def verify_deposit(deposit_data_dict: Dict[str, Any]) -> bool:
    '''
    Checks whether a deposit is valid based on the eth2 rules.
    https://github.com/ethereum/eth2.0-specs/blob/dev/specs/phase0/beacon-chain.md#deposits
    '''
    pubkey = BLSPubkey(bytes.fromhex(deposit_data_dict['pubkey']))
    withdrawal_credentials = bytes.fromhex(deposit_data_dict['withdrawal_credentials'])
    amount = deposit_data_dict['amount']
    signature = BLSSignature(bytes.fromhex(deposit_data_dict['signature']))
    deposit_data_root = bytes.fromhex(deposit_data_dict['signed_deposit_data_root'])

    # Verify deposit amount
    if not MIN_DEPOSIT_AMOUNT < amount <= MAX_DEPOSIT_AMOUNT:
        return False

    # Verify deposit signature && pubkey
    deposit_message = DepositMessage(pubkey=pubkey, withdrawal_credentials=withdrawal_credentials, amount=amount)
    domain = compute_domain(domain_type=DOMAIN_DEPOSIT)
    signing_root = compute_signing_root(deposit_message, domain)
    if not bls.Verify(pubkey, signing_root, signature):
        return False

    # Verify Deposit Root
    deposit = Deposit(pubkey=pubkey, withdrawal_credentials=withdrawal_credentials, amount=amount, signature=signature)
    return deposit.hash_tree_root == deposit_data_root
Esempio n. 7
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
Esempio n. 8
0
 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
Esempio n. 9
0
 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
Esempio n. 10
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 = cls()
     keystore.crypto.kdf.params['salt'] = kdf_salt
     decryption_key = keystore.kdf(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.PrivToPub(int.from_bytes(secret, 'big')).hex()
     keystore.path = path
     return keystore
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 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
    )
Esempio n. 13
0
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_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()
Esempio n. 15
0
def test_hkdf_mod_r_key_info(seed: bytes, key_info: bytes) -> None:
    assert bls.KeyGen(seed, key_info) == _HKDF_mod_r(IKM=seed,
                                                     key_info=key_info)
Esempio n. 16
0
def test_hkdf_mod_r(test) -> None:
    seed = bytes.fromhex(test['seed'])
    assert bls.KeyGen(seed) == _HKDF_mod_r(IKM=seed)
Esempio n. 17
0
 def Aggregate(signatures: Sequence[BLSSignature]) -> BLSSignature:
     # py_ecc use a different EMPTY_SIGNATURE. Return the Trinity one here:
     if len(signatures) == 0:
         return EMPTY_SIGNATURE
     return G2ProofOfPossession.Aggregate(signatures)
Esempio n. 18
0
 def SkToPk(SK: int) -> BLSPubkey:
     return G2ProofOfPossession.SkToPk(SK)
Esempio n. 19
0
 def signing_pk(self) -> bytes:
     return bls.SkToPk(self.signing_sk)
Esempio n. 20
0
 def withdrawal_pk(self):
     return bls.PrivToPub(self.withdrawal_sk)
Esempio n. 21
0
 def Sign(SK: int, message: Hash32) -> BLSSignature:
     return G2ProofOfPossession.Sign(SK, message)
Esempio n. 22
0
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)
Esempio n. 23
0
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)
}
Esempio n. 24
0
 def FastAggregateVerify(PKs: Sequence[BLSPubkey], message: Hash32,
                         signature: BLSSignature) -> bool:
     return G2ProofOfPossession.FastAggregateVerify(PKs, message, signature)
Esempio n. 25
0
def test_pop(sk):
    pk = G2ProofOfPossession.PrivToPub(sk)
    proof = G2ProofOfPossession.PopProve(sk)
    assert G2ProofOfPossession.PopVerify(pk, proof)
Esempio n. 26
0
 def withdrawal_pk(self) -> bytes:
     return bls.SkToPk(self.withdrawal_sk)
Esempio n. 27
0
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
Esempio n. 28
0
 def Verify(PK: BLSPubkey, message: Hash32,
            signature: BLSSignature) -> bool:
     return G2ProofOfPossession.Verify(PK, message, signature)
Esempio n. 29
0
def validate_deposit(deposit_data_dict: Dict[str, Any],
                     credential: Credential) -> bool:
    '''
    Checks whether a deposit is valid based on the eth2 rules.
    https://github.com/ethereum/eth2.0-specs/blob/dev/specs/phase0/beacon-chain.md#deposits
    '''
    pubkey = BLSPubkey(bytes.fromhex(deposit_data_dict['pubkey']))
    withdrawal_credentials = bytes.fromhex(
        deposit_data_dict['withdrawal_credentials'])
    amount = deposit_data_dict['amount']
    signature = BLSSignature(bytes.fromhex(deposit_data_dict['signature']))
    deposit_message_root = bytes.fromhex(
        deposit_data_dict['deposit_data_root'])
    fork_version = bytes.fromhex(deposit_data_dict['fork_version'])

    # Verify pubkey
    if len(pubkey) != 48:
        return False
    if pubkey != credential.signing_pk:
        return False

    # Verify withdrawal credential
    if len(withdrawal_credentials) != 32:
        return False
    if withdrawal_credentials[:
                              1] == BLS_WITHDRAWAL_PREFIX == credential.withdrawal_prefix:
        if withdrawal_credentials[1:] != SHA256(credential.withdrawal_pk)[1:]:
            return False
    elif withdrawal_credentials[:
                                1] == ETH1_ADDRESS_WITHDRAWAL_PREFIX == credential.withdrawal_prefix:
        if withdrawal_credentials[1:12] != b'\x00' * 11:
            return False
        if credential.eth1_withdrawal_address is None:
            return False
        if withdrawal_credentials[12:] != credential.eth1_withdrawal_address:
            return False
    else:
        return False

    # Verify deposit amount
    if not MIN_DEPOSIT_AMOUNT < amount <= MAX_DEPOSIT_AMOUNT:
        return False

    # Verify deposit signature && pubkey
    deposit_message = DepositMessage(
        pubkey=pubkey,
        withdrawal_credentials=withdrawal_credentials,
        amount=amount)
    domain = compute_deposit_domain(fork_version)
    signing_root = compute_signing_root(deposit_message, domain)
    if not bls.Verify(pubkey, signing_root, signature):
        return False

    # Verify Deposit Root
    signed_deposit = DepositData(
        pubkey=pubkey,
        withdrawal_credentials=withdrawal_credentials,
        amount=amount,
        signature=signature,
    )
    return signed_deposit.hash_tree_root == deposit_message_root
Esempio n. 30
0
from py_ecc.bls import G2ProofOfPossession as bls
from eth2spec.phase0 import spec

privkeys = [i + 1 for i in range(spec.SLOTS_PER_EPOCH * 16)]
pubkeys = [bls.PrivToPub(privkey) for privkey in privkeys]
pubkey_to_privkey = {
    pubkey: privkey
    for privkey, pubkey in zip(privkeys, pubkeys)
}