Esempio n. 1
0
def _validate_voluntary_exit_signature(
    state: BeaconState,
    signed_voluntary_exit: SignedVoluntaryExit,
    validator: Validator,
    slots_per_epoch: int,
) -> None:
    voluntary_exit = signed_voluntary_exit.message
    domain = get_domain(
        state,
        SignatureDomain.DOMAIN_VOLUNTARY_EXIT,
        slots_per_epoch,
        voluntary_exit.epoch,
    )
    try:
        bls.validate(
            pubkey=validator.pubkey,
            message_hash=voluntary_exit.hash_tree_root,
            signature=signed_voluntary_exit.signature,
            domain=domain,
        )
    except SignatureError as error:
        raise ValidationError(
            f"Invalid VoluntaryExit signature, validator_index={voluntary_exit.validator_index}",
            error,
        )
Esempio n. 2
0
def validate_proposer_signature(state: BeaconState, block: BaseBeaconBlock,
                                committee_config: CommitteeConfig) -> None:
    message_hash = block.signing_root

    # Get the public key of proposer
    beacon_proposer_index = get_beacon_proposer_index(
        state,
        committee_config,
    )
    proposer_pubkey = state.validators[beacon_proposer_index].pubkey
    domain = get_domain(
        state,
        SignatureDomain.DOMAIN_BEACON_PROPOSER,
        committee_config.SLOTS_PER_EPOCH,
    )

    try:
        bls.validate(
            pubkey=proposer_pubkey,
            message_hash=message_hash,
            signature=block.signature,
            domain=domain,
        )
    except SignatureError as error:
        raise ValidationError(
            f"Invalid Proposer Signature on block, beacon_proposer_index={beacon_proposer_index}",
            error,
        )
Esempio n. 3
0
def test_validate(backend):
    bls.use(backend)
    msg = b"\x32" * 32
    privkey = 42
    pubkey = bls.sk_to_pk(privkey)
    sig = bls.sign(privkey, msg)
    bls.validate(msg, sig, pubkey)
Esempio n. 4
0
def test_validate_invalid(backend):
    bls.use(backend)
    msg = b"\x32" * 32
    privkey = 42
    pubkey = bls.sk_to_pk(privkey)
    sig = b"\x42" * 96
    with pytest.raises(SignatureError):
        bls.validate(msg, sig, pubkey)
Esempio n. 5
0
def test_validate_multiple(backend):
    bls.use(backend)
    msg = b"\x32" * 32
    privkey_0 = 42
    privkey_1 = 4242
    pubkey_0 = bls.sk_to_pk(privkey_0)
    pubkey_1 = bls.sk_to_pk(privkey_1)
    aggregate_sig = bls.aggregate(bls.sign(privkey_0, msg), bls.sign(privkey_1, msg))
    bls.validate(msg, aggregate_sig, pubkey_0, pubkey_1)
def validate_indexed_attestation_aggregate_signature(
        state: BeaconState, indexed_attestation: IndexedAttestation,
        slots_per_epoch: int) -> None:
    public_keys = tuple(state.validators[i].pubkey
                        for i in indexed_attestation.attesting_indices)
    domain = get_domain(
        state,
        SignatureDomain.DOMAIN_BEACON_ATTESTER,
        slots_per_epoch,
        indexed_attestation.data.target.epoch,
    )
    signing_root = compute_signing_root(indexed_attestation.data, domain)
    bls.validate(signing_root, indexed_attestation.signature, *public_keys)
Esempio n. 7
0
def test_validate_multiple_one_invalid(backend):
    bls.use(backend)
    msg = b"\x32" * 32
    privkey_0 = 42
    privkey_1 = 4242
    privkey_other = 424242
    pubkey_0 = bls.sk_to_pk(privkey_0)
    pubkey_1 = bls.sk_to_pk(privkey_1)
    aggregate_sig = bls.aggregate(
        bls.sign(privkey_0, msg), bls.sign(privkey_other, msg)
    )
    with pytest.raises(SignatureError):
        bls.validate(msg, aggregate_sig, pubkey_0, pubkey_1)
Esempio n. 8
0
def validate_aggregator_proof(
    state: BeaconState, aggregate_and_proof: AggregateAndProof, config: Eth2Config
) -> None:
    slot = aggregate_and_proof.aggregate.data.slot
    pubkey = state.validators[aggregate_and_proof.aggregator_index].pubkey
    domain = get_domain(
        state,
        SignatureDomain.DOMAIN_BEACON_ATTESTER,
        config.SLOTS_PER_EPOCH,
        message_epoch=compute_epoch_at_slot(slot, config.SLOTS_PER_EPOCH),
    )
    signing_root = compute_signing_root(SerializableUint64(slot), domain)

    bls.validate(signing_root, aggregate_and_proof.selection_proof, pubkey)
Esempio n. 9
0
def _validate_transfer_signature(state: BeaconState, transfer: Transfer,
                                 config: Eth2Config) -> None:
    domain = get_domain(state, SignatureDomain.DOMAIN_TRANSFER,
                        config.SLOTS_PER_EPOCH)
    try:
        bls.validate(
            pubkey=transfer.pubkey,
            message_hash=transfer.signing_root,
            signature=transfer.signature,
            domain=domain,
        )
    except SignatureError as error:
        raise ValidationError(f"Invalid signature for transfer {transfer}",
                              error)
Esempio n. 10
0
def test_aggregate_votes(votes_count, random, privkeys, pubkeys):
    bit_count = 10
    pre_bitfield = get_empty_bitfield(bit_count)
    pre_sigs = ()
    domain = compute_domain(SignatureDomain.DOMAIN_ATTESTATION)

    random_votes = random.sample(range(bit_count), votes_count)
    message_hash = b"\x12" * 32

    # Get votes: (committee_index, sig, public_key)
    votes = [
        (
            committee_index,
            bls.sign(message_hash, privkeys[committee_index], domain),
            pubkeys[committee_index],
        )
        for committee_index in random_votes
    ]

    # Verify
    sigs, committee_indices = verify_votes(message_hash, votes, domain)

    # Aggregate the votes
    bitfield, sigs = aggregate_votes(
        bitfield=pre_bitfield,
        sigs=pre_sigs,
        voting_sigs=sigs,
        attesting_indices=committee_indices,
    )

    try:
        _, _, pubs = zip(*votes)
    except ValueError:
        pubs = ()

    voted_index = [
        committee_index
        for committee_index in random_votes
        if has_voted(bitfield, committee_index)
    ]
    assert len(voted_index) == len(votes)

    aggregated_pubs = bls.aggregate_pubkeys(pubs)

    if votes_count == 0 and bls.backend in (ChiaBackend, MilagroBackend):
        with pytest.raises(ValidationError):
            bls.validate(message_hash, aggregated_pubs, sigs, domain)
    else:
        bls.validate(message_hash, aggregated_pubs, sigs, domain)
Esempio n. 11
0
def validate_block_header_signature(state: BeaconState,
                                    header: BeaconBlockHeader,
                                    pubkey: BLSPubkey,
                                    slots_per_epoch: int) -> None:
    try:
        bls.validate(pubkey=pubkey,
                     message_hash=header.signing_root,
                     signature=header.signature,
                     domain=get_domain(
                         state,
                         SignatureDomain.DOMAIN_BEACON_PROPOSER,
                         slots_per_epoch,
                         slot_to_epoch(header.slot, slots_per_epoch),
                     ))
    except SignatureError as error:
        raise ValidationError("Header signature is invalid", error)
Esempio n. 12
0
def process_deposit(state: BeaconState, deposit: Deposit,
                    config: Eth2Config) -> BeaconState:
    """
    Process a deposit from Ethereum 1.0.
    """
    validate_deposit_proof(state, deposit, DEPOSIT_CONTRACT_TREE_DEPTH)

    # Increment the next deposit index we are expecting. Note that this
    # needs to be done here because while the deposit contract will never
    # create an invalid Merkle branch, it may admit an invalid deposit
    # object, and we need to be able to skip over it
    state = state.copy(eth1_deposit_index=state.eth1_deposit_index + 1, )

    pubkey = deposit.data.pubkey
    amount = deposit.data.amount
    validator_pubkeys = tuple(v.pubkey for v in state.validators)
    if pubkey not in validator_pubkeys:
        # Verify the proof of possession
        try:
            bls.validate(
                pubkey=pubkey,
                message_hash=deposit.data.signing_root,
                signature=deposit.data.signature,
                domain=bls_domain(SignatureDomain.DOMAIN_DEPOSIT, ),
            )
        except SignatureError:
            return state

        withdrawal_credentials = deposit.data.withdrawal_credentials
        validator = Validator.create_pending_validator(
            pubkey,
            withdrawal_credentials,
            amount,
            config,
        )

        return state.copy(
            validators=state.validators + (validator, ),
            balances=state.balances + (amount, ),
        )
    else:
        index = ValidatorIndex(validator_pubkeys.index(pubkey))
        return increase_balance(
            state,
            index,
            amount,
        )
Esempio n. 13
0
def validate_randao_reveal(state: BeaconState, proposer_index: int,
                           epoch: Epoch, randao_reveal: Hash32,
                           slots_per_epoch: int) -> None:
    proposer = state.validators[proposer_index]
    proposer_pubkey = proposer.pubkey
    message_hash = ssz.hash_tree_root(epoch, sedes=ssz.sedes.uint64)
    domain = get_domain(state, SignatureDomain.DOMAIN_RANDAO, slots_per_epoch)

    try:
        bls.validate(
            pubkey=proposer_pubkey,
            message_hash=message_hash,
            signature=cast(BLSSignature, randao_reveal),
            domain=domain,
        )
    except SignatureError as error:
        raise ValidationError("RANDAO reveal is invalid", error)
Esempio n. 14
0
def validate_block_header_signature(
    state: BeaconState,
    header: SignedBeaconBlockHeader,
    pubkey: BLSPubkey,
    slots_per_epoch: int,
) -> None:
    domain = get_domain(
        state,
        SignatureDomain.DOMAIN_BEACON_PROPOSER,
        slots_per_epoch,
        compute_epoch_at_slot(header.message.slot, slots_per_epoch),
    )
    signing_root = compute_signing_root(header.message, domain)

    try:
        bls.validate(signing_root, header.signature, pubkey)
    except SignatureError as error:
        raise ValidationError("Header signature is invalid:", error)
Esempio n. 15
0
def validate_proposer_signature(
    state: BeaconState, signed_block: BaseSignedBeaconBlock, config: Eth2Config
) -> None:
    # Get the public key of proposer
    beacon_proposer_index = get_beacon_proposer_index(state, config)
    proposer_pubkey = state.validators[beacon_proposer_index].pubkey
    domain = get_domain(
        state, SignatureDomain.DOMAIN_BEACON_PROPOSER, config.SLOTS_PER_EPOCH
    )
    signing_root = compute_signing_root(signed_block.message, domain)

    try:
        bls.validate(signing_root, signed_block.signature, proposer_pubkey)
    except SignatureError as error:
        raise ValidationError(
            f"Invalid Proposer Signature on block, beacon_proposer_index={beacon_proposer_index}",
            error,
        )
Esempio n. 16
0
def test_aggregate_votes(votes_count, random, privkeys, pubkeys):
    bit_count = 10
    pre_bitfield = get_empty_bitfield(bit_count)
    pre_sigs = ()
    domain = 0

    random_votes = random.sample(range(bit_count), votes_count)
    message_hash = b'\x12' * 32

    # Get votes: (committee_index, sig, public_key)
    votes = [(
        committee_index,
        bls.sign(message_hash, privkeys[committee_index], domain),
        pubkeys[committee_index],
    ) for committee_index in random_votes]

    # Verify
    sigs, committee_indices = verify_votes(message_hash, votes, domain)

    # Aggregate the votes
    bitfield, sigs = aggregate_votes(bitfield=pre_bitfield,
                                     sigs=pre_sigs,
                                     voting_sigs=sigs,
                                     attesting_indices=committee_indices)

    try:
        _, _, pubs = zip(*votes)
    except ValueError:
        pubs = ()

    voted_index = [
        committee_index for committee_index in random_votes
        if has_voted(bitfield, committee_index)
    ]
    assert len(voted_index) == len(votes)

    aggregated_pubs = bls.aggregate_pubkeys(pubs)

    if votes_count != 0:
        bls.validate(message_hash, aggregated_pubs, sigs, domain)
    else:
        # EMPTY_SIGNATURE is considered invalid
        with pytest.raises(ValueError):
            bls.validate(message_hash, aggregated_pubs, sigs, domain)
Esempio n. 17
0
def validate_aggregator_proof(state: BeaconState,
                              aggregate_and_proof: AggregateAndProof,
                              config: Eth2Config) -> None:
    slot = aggregate_and_proof.aggregate.data.slot
    pubkey = state.validators[aggregate_and_proof.aggregator_index].pubkey
    domain = get_domain(
        state,
        SignatureDomain.DOMAIN_BEACON_ATTESTER,
        config.SLOTS_PER_EPOCH,
        message_epoch=compute_epoch_at_slot(slot, config.SLOTS_PER_EPOCH),
    )
    message_hash = get_hash_tree_root(slot, sedes=uint64)

    bls.validate(
        message_hash=message_hash,
        pubkey=pubkey,
        signature=aggregate_and_proof.selection_proof,
        domain=domain,
    )
Esempio n. 18
0
def test_aggregate_votes(votes_count, random, privkeys, pubkeys):
    bit_count = 10
    pre_bitfield = get_empty_bitfield(bit_count)
    pre_sigs = ()

    random_votes = random.sample(range(bit_count), votes_count)
    message_hash = b"\x12" * 32

    # Get votes: (committee_index, sig, public_key)
    votes = [(
        committee_index,
        bls.sign(privkeys[committee_index], message_hash),
        pubkeys[committee_index],
    ) for committee_index in random_votes]

    # Verify
    sigs, committee_indices = verify_votes(message_hash, votes)

    # Aggregate the votes
    bitfield, sigs = aggregate_votes(
        bitfield=pre_bitfield,
        sigs=pre_sigs,
        voting_sigs=sigs,
        attesting_indices=committee_indices,
    )

    try:
        _, _, pubs = zip(*votes)
    except ValueError:
        pubs = ()

    voted_index = [
        committee_index for committee_index in random_votes
        if has_voted(bitfield, committee_index)
    ]
    assert len(voted_index) == len(votes)

    if votes_count == 0:
        with pytest.raises(ValidationError):
            bls.validate(message_hash, sigs, *pubs)
    else:
        bls.validate(message_hash, sigs, *pubs)
Esempio n. 19
0
def validate_randao_reveal(
    state: BeaconState,
    proposer_index: int,
    epoch: Epoch,
    randao_reveal: BLSSignature,
    slots_per_epoch: int,
) -> None:
    proposer = state.validators[proposer_index]
    proposer_pubkey = proposer.pubkey
    domain = get_domain(state, SignatureDomain.DOMAIN_RANDAO, slots_per_epoch)

    signing_root = compute_signing_root(SerializableUint64(epoch), domain)

    try:
        bls.validate(signing_root, randao_reveal, proposer_pubkey)
    except SignatureError as error:
        raise ValidationError(
            f"RANDAO reveal is invalid for proposer index {proposer_index} at slot {state.slot}",
            error,
        )
Esempio n. 20
0
def validate_indexed_attestation_aggregate_signature(
        state: BeaconState, indexed_attestation: IndexedAttestation,
        slots_per_epoch: int) -> None:
    attesting_indices = indexed_attestation.attesting_indices
    pubkey = bls.aggregate_pubkeys(
        tuple(state.validators[i].pubkey for i in attesting_indices))

    message_hash = indexed_attestation.data.hash_tree_root
    domain = get_domain(
        state,
        SignatureDomain.DOMAIN_BEACON_ATTESTER,
        slots_per_epoch,
        indexed_attestation.data.target.epoch,
    )
    bls.validate(
        pubkey=pubkey,
        message_hash=message_hash,
        signature=indexed_attestation.signature,
        domain=domain,
    )
Esempio n. 21
0
def test_validate_invalid_lengths(backend):
    msg = b"\x32" * 32
    with pytest.raises(SignatureError):
        bls.validate(msg, b"\x00", b"\x00" * 48)
    with pytest.raises(SignatureError):
        bls.validate(msg, b"\x00" * 96, b"\x00")
Esempio n. 22
0
 def validate():
     bls.validate(b"\x11" * 32, EMPTY_PUBKEY, EMPTY_SIGNATURE, domain)
Esempio n. 23
0
def test_validate_empty(backend):
    bls.use(backend)
    msg = b"\x32" * 32
    sig = b"\x42" * 96
    with pytest.raises(SignatureError):
        bls.validate(msg, sig)