Example #1
0
def verify_slashable_attestation_signature(
        state: 'BeaconState', slashable_attestation: 'SlashableAttestation',
        epoch_length: int) -> bool:
    """
    Ensure we have a valid aggregate signature for the ``slashable_attestation``.
    """
    pubkeys = generate_aggregate_pubkeys(state.validator_registry,
                                         slashable_attestation)

    messages = slashable_attestation.messages

    signature = slashable_attestation.aggregate_signature

    domain = get_domain(
        state.fork,
        slot_to_epoch(slashable_attestation.data.slot, epoch_length),
        SignatureDomain.DOMAIN_ATTESTATION,
    )

    return bls.verify_multiple(
        pubkeys=pubkeys,
        messages=messages,
        signature=signature,
        domain=domain,
    )
Example #2
0
def verify_slashable_attestation_signature(
        state: 'BeaconState', slashable_attestation: 'SlashableAttestation',
        slots_per_epoch: int) -> bool:
    """
    Ensure we have a valid aggregate signature for the ``slashable_attestation``.
    """
    all_indices = slashable_attestation.custody_bit_indices
    pubkeys: Tuple[BLSPubkey, ...] = generate_aggregate_pubkeys_from_indices(
        state.validator_registry,
        *all_indices,
    )
    message_hashes: Tuple[Hash32, ...] = slashable_attestation.message_hashes

    signature = slashable_attestation.aggregate_signature

    domain = get_domain(
        state.fork,
        slot_to_epoch(slashable_attestation.data.slot, slots_per_epoch),
        SignatureDomain.DOMAIN_ATTESTATION,
    )

    # No custody bit 1 indice votes in phase 0, so we only need to process custody bit 0
    # for efficiency.
    # TODO: to be removed in phase 1.
    if len(all_indices[1]) == 0:
        pubkeys = pubkeys[:1]
        message_hashes = message_hashes[:1]

    return bls.verify_multiple(
        pubkeys=pubkeys,
        message_hashes=message_hashes,
        signature=signature,
        domain=domain,
    )
Example #3
0
def verify_slashable_vote_data_signature(
        state: 'BeaconState', vote_data: 'SlashableVoteData') -> bool:
    """
    Ensure we have a valid aggregate signature for the ``vote_data``.
    """
    pubkeys = generate_aggregate_pubkeys(state.validator_registry, vote_data)

    messages = vote_data.messages

    signature = vote_data.aggregate_signature

    domain = get_domain(state.fork, vote_data.data.slot,
                        SignatureDomain.DOMAIN_ATTESTATION)

    return bls.verify_multiple(
        pubkeys=pubkeys,
        messages=messages,
        signature=signature,
        domain=domain,
    )
Example #4
0
def test_multi_aggregation(msg_1, msg_2, privkeys_1, privkeys_2):
    domain = 0

    sigs_1 = [sign(msg_1, k, domain=domain) for k in privkeys_1]
    pubs_1 = [privtopub(k) for k in privkeys_1]
    aggsig_1 = aggregate_signatures(sigs_1)
    aggpub_1 = aggregate_pubkeys(pubs_1)

    sigs_2 = [sign(msg_2, k, domain=domain) for k in privkeys_2]
    pubs_2 = [privtopub(k) for k in privkeys_2]
    aggsig_2 = aggregate_signatures(sigs_2)
    aggpub_2 = aggregate_pubkeys(pubs_2)

    msgs = [msg_1, msg_2]
    pubs = [aggpub_1, aggpub_2]
    aggsig = aggregate_signatures([aggsig_1, aggsig_2])

    assert verify_multiple(
        pubkeys=pubs,
        messages=msgs,
        signature=aggsig,
        domain=domain,
    )
Example #5
0
def validate_attestation_aggregate_signature(
        state: BeaconState, attestation: Attestation,
        committee_config: CommitteeConfig) -> None:
    """
    Validate ``aggregate_signature`` field of ``attestation``.
    Raise ``ValidationError`` if it's invalid.

    Note: This is the phase 0 version of `aggregate_signature`` validation.
    All proof of custody bits are assumed to be 0 within the signed data.
    This will change to reflect real proof of custody bits in the Phase 1.
    """
    _validate_custody_bitfield(attestation.custody_bitfield)

    _validate_aggregation_bitfield(attestation.aggregation_bitfield)

    committee = get_crosslink_committee_for_attestation(
        state=state,
        attestation_data=attestation.data,
        committee_config=committee_config,
    )

    _validate_custody_bitfield_from_aggregation_bitfield(
        len(committee),
        attestation.aggregation_bitfield,
        attestation.custody_bitfield,
    )

    participants = get_members_from_bitfield(committee,
                                             attestation.aggregation_bitfield)
    custody_bit_1_participants = get_members_from_bitfield(
        committee, attestation.custody_bitfield)
    custody_bit_0_participants = (i for i in participants
                                  if i not in custody_bit_1_participants)

    pubkeys = generate_aggregate_pubkeys_from_indices(
        state.validator_registry,
        custody_bit_0_participants,
        custody_bit_1_participants,
    )

    # TODO: change to tree hashing (hash_tree_root) when we have SSZ
    message_hashes = (
        AttestationDataAndCustodyBit(data=attestation.data,
                                     custody_bit=False).root,
        AttestationDataAndCustodyBit(data=attestation.data,
                                     custody_bit=True).root,
    )

    domain = get_domain(
        fork=state.fork,
        epoch=slot_to_epoch(attestation.data.slot,
                            committee_config.SLOTS_PER_EPOCH),
        domain_type=SignatureDomain.DOMAIN_ATTESTATION,
    )

    is_valid_signature = bls.verify_multiple(
        pubkeys=pubkeys,
        message_hashes=message_hashes,
        signature=attestation.aggregate_signature,
        domain=domain,
    )

    if not is_valid_signature:
        raise ValidationError(
            "Attestation aggregate_signature is invalid. "
            "message_hashes={}, custody_bit_0_participants={}, custody_bit_1_participants={} "
            "domain={}".format(
                message_hashes,
                custody_bit_0_participants,
                custody_bit_1_participants,
                domain,
            ))