Пример #1
0
def test_generate_aggregate_pubkeys(activated_genesis_validators,
                                    sample_slashable_vote_data_params,
                                    data):
    max_value_for_list = len(activated_genesis_validators) - 1
    (indices, some_index) = _list_and_index(
        data,
        elements=st.integers(
            min_value=0,
            max_value=max_value_for_list,
        )
    )
    custody_bit_0_indices = indices[:some_index]
    custody_bit_1_indices = indices[some_index:]

    key = "custody_bit_0_indices"
    sample_slashable_vote_data_params[key] = custody_bit_0_indices
    key = "custody_bit_1_indices"
    sample_slashable_vote_data_params[key] = custody_bit_1_indices

    votes = SlashableVoteData(**sample_slashable_vote_data_params)

    keys = generate_aggregate_pubkeys(activated_genesis_validators, votes)
    assert len(keys) == 2

    (poc_0_key, poc_1_key) = keys

    poc_0_keys = get_pubkey_for_indices(activated_genesis_validators, custody_bit_0_indices)
    poc_1_keys = get_pubkey_for_indices(activated_genesis_validators, custody_bit_1_indices)

    assert bls.aggregate_pubkeys(poc_0_keys) == poc_0_key
    assert bls.aggregate_pubkeys(poc_1_keys) == poc_1_key
Пример #2
0
def test_signature_aggregation(msg, privkeys):
    domain = 0
    sigs = [sign(msg, k, domain=domain) for k in privkeys]
    pubs = [privtopub(k) for k in privkeys]
    aggsig = aggregate_signatures(sigs)
    aggpub = aggregate_pubkeys(pubs)
    assert verify(msg, aggpub, aggsig, domain=domain)
Пример #3
0
def test_generate_aggregate_pubkeys(activated_genesis_validators,
                                    sample_slashable_attestation_params, data):
    max_value_for_list = len(activated_genesis_validators) - 1
    (validator_indices,
     some_index) = _list_and_index(data,
                                   elements=st.integers(
                                       min_value=0,
                                       max_value=max_value_for_list,
                                   ))

    key = "validator_indices"
    sample_slashable_attestation_params[key] = validator_indices

    custody_bitfield = get_empty_bitfield(len(validator_indices))
    for index in range(some_index):
        custody_bitfield = set_voted(custody_bitfield, index)

    key = "custody_bitfield"
    sample_slashable_attestation_params[key] = custody_bitfield

    slashable_attestation = SlashableAttestation(
        **sample_slashable_attestation_params)
    custody_bit_0_indices, custody_bit_1_indices = slashable_attestation.custody_bit_indices
    assert len(
        set(custody_bit_0_indices).intersection(
            set(custody_bit_1_indices))) == 0

    keys = generate_aggregate_pubkeys_from_indices(
        activated_genesis_validators,
        *slashable_attestation.custody_bit_indices,
    )
    assert len(keys) == 2

    (poc_0_key, poc_1_key) = keys

    poc_0_keys = get_pubkey_for_indices(activated_genesis_validators,
                                        custody_bit_0_indices)
    poc_1_keys = get_pubkey_for_indices(activated_genesis_validators,
                                        custody_bit_1_indices)

    assert bls.aggregate_pubkeys(poc_0_keys) == poc_0_key
    assert bls.aggregate_pubkeys(poc_1_keys) == poc_1_key
Пример #4
0
def validate_attestation_aggregate_signature(state: BeaconState,
                                             attestation: Attestation,
                                             genesis_epoch: EpochNumber,
                                             epoch_length: int,
                                             target_committee_size: int,
                                             shard_count: int) -> 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.
    """
    participant_indices = get_attestation_participants(
        state=state,
        attestation_data=attestation.data,
        bitfield=attestation.aggregation_bitfield,
        genesis_epoch=genesis_epoch,
        epoch_length=epoch_length,
        target_committee_size=target_committee_size,
        shard_count=shard_count,
    )
    pubkeys = tuple(
        state.validator_registry[validator_index].pubkey
        for validator_index in participant_indices
    )
    group_public_key = bls.aggregate_pubkeys(pubkeys)
    # TODO: change to tree hashing when we have SSZ
    message = AttestationDataAndCustodyBit.create_attestation_message(attestation.data)
    domain = get_domain(
        fork=state.fork,
        epoch=slot_to_epoch(attestation.data.slot, epoch_length),
        domain_type=SignatureDomain.DOMAIN_ATTESTATION,
    )

    is_valid_signature = bls.verify(
        message=message,
        pubkey=group_public_key,
        signature=attestation.aggregate_signature,
        domain=domain,
    )

    if not is_valid_signature:
        raise ValidationError(
            "Attestation aggregate_signature is invalid. "
            "message={}, participant_indices={} "
            "domain={}".format(
                message,
                participant_indices,
                domain,
            )
        )
Пример #5
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,
    )
Пример #6
0
def validate_serenity_attestation_aggregate_signature(
        state: BeaconState, attestation: Attestation,
        epoch_length: int) -> 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.
    """
    participant_indices = get_attestation_participants(
        state=state,
        slot=attestation.data.slot,
        shard=attestation.data.shard,
        participation_bitfield=attestation.participation_bitfield,
        epoch_length=epoch_length,
    )

    pubkeys = tuple(state.validator_registry[validator_index].pubkey
                    for validator_index in participant_indices)
    group_public_key = bls.aggregate_pubkeys(pubkeys)

    # TODO: change to tree hashing when we have SSZ
    # TODO: Replace with AttestationAndCustodyBit data structure
    message = hash_eth2(rlp.encode(attestation.data) + (0).to_bytes(1, "big"))

    is_valid_signature = bls.verify(
        message=message,
        pubkey=group_public_key,
        signature=attestation.aggregate_signature,
        domain=get_domain(
            fork_data=state.fork_data,
            slot=attestation.data.slot,
            domain_type=SignatureDomain.DOMAIN_ATTESTATION,
        ),
    )
    if not is_valid_signature:
        raise ValidationError(
            "Attestation ``aggregate_signature`` is invalid.")
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,
        voting_committee_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)
    assert bls.verify(message_hash, aggregated_pubs, sigs, domain)