Beispiel #1
0
def test_invalid_private_key(backend, privkey, domain):
    bls.use(backend)
    msg = str(privkey).encode("utf-8")
    with pytest.raises(ValueError):
        bls.privtopub(privkey)
    with pytest.raises(ValueError):
        bls.sign(msg, privkey, domain=domain)
Beispiel #2
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)
Beispiel #3
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)
Beispiel #4
0
    def run_with(
        _cls, inputs: SignatureData, _config: Optional[Eth2Config]
    ) -> BLSSignature:
        # BLS override
        bls.use(MilagroBackend)

        return bls.sign(inputs["privkey"], inputs["message"])
def test_randao_reveal_validation(
    is_valid,
    epoch,
    expected_epoch,
    proposer_key_index,
    expected_proposer_key_index,
    privkeys,
    pubkeys,
    sample_fork_params,
    genesis_state,
    config,
):
    state = genesis_state.set(
        "slot", compute_start_slot_at_epoch(epoch, config.SLOTS_PER_EPOCH))
    slots_per_epoch = config.SLOTS_PER_EPOCH
    domain = get_domain(state, SignatureDomain.DOMAIN_RANDAO, slots_per_epoch)
    signing_root = compute_signing_root(SerializableUint64(epoch), domain)

    proposer_privkey = privkeys[proposer_key_index]
    randao_reveal = bls.sign(proposer_privkey, signing_root)

    try:
        validate_randao_reveal(
            state=state,
            proposer_index=expected_proposer_key_index,
            epoch=expected_epoch,
            randao_reveal=randao_reveal,
            slots_per_epoch=slots_per_epoch,
        )
    except ValidationError:
        if is_valid:
            raise
    else:
        if not is_valid:
            pytest.fail("Did not raise")
Beispiel #6
0
def sign_proof_of_possession(deposit_data: DepositData,
                             privkey: int) -> BLSSignature:
    return bls.sign(
        message_hash=deposit_data.signing_root,
        privkey=privkey,
        domain=bls_domain(SignatureDomain.DOMAIN_DEPOSIT),
    )
Beispiel #7
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)
Beispiel #8
0
def test_bls_core_succeed(backend, privkey):
    bls.use(backend)
    domain = 0
    msg = str(privkey).encode('utf-8')
    sig = bls.sign(msg, privkey, domain=domain)
    pub = bls.privtopub(privkey)
    assert bls.verify(msg, pub, sig, domain=domain)
Beispiel #9
0
def sign_proof_of_possession(deposit_message: DepositMessage,
                             privkey: int) -> BLSSignature:
    return bls.sign(
        message_hash=deposit_message.hash_tree_root,
        privkey=privkey,
        domain=compute_domain(SignatureDomain.DOMAIN_DEPOSIT),
    )
Beispiel #10
0
def test_signature_aggregation(backend, msg, privkeys, domain):
    bls.use(backend)
    sigs = [bls.sign(msg, k, domain=domain) for k in privkeys]
    pubs = [bls.privtopub(k) for k in privkeys]
    aggsig = bls.aggregate_signatures(sigs)
    aggpub = bls.aggregate_pubkeys(pubs)
    assert bls.verify(msg, aggpub, aggsig, domain=domain)
def test_randao_processing_validates_randao_reveal(
    sample_beacon_block_params,
    sample_beacon_block_body_params,
    sample_beacon_state_params,
    sample_fork_params,
    keymap,
    config,
):
    proposer_pubkey, proposer_privkey = first(keymap.items())
    state = SerenityBeaconState.create(**sample_beacon_state_params).mset(
        "validators",
        tuple(
            create_mock_validator(proposer_pubkey, config)
            for _ in range(config.TARGET_COMMITTEE_SIZE)),
        "balances",
        (config.MAX_EFFECTIVE_BALANCE, ) * config.TARGET_COMMITTEE_SIZE,
        "randao_mixes",
        tuple(ZERO_HASH32 for _ in range(config.EPOCHS_PER_HISTORICAL_VECTOR)),
    )

    epoch = state.current_epoch(config.SLOTS_PER_EPOCH)
    message_hash = (epoch + 1).to_bytes(32, byteorder="little")
    domain = get_domain(state, SignatureDomain.DOMAIN_RANDAO,
                        config.SLOTS_PER_EPOCH)
    randao_reveal = bls.sign(message_hash, proposer_privkey, domain)

    block_body = BeaconBlockBody.create(**sample_beacon_block_body_params).set(
        "randao_reveal", randao_reveal)

    block = SerenityBeaconBlock.create(**sample_beacon_block_params).set(
        "body", block_body)

    with pytest.raises(ValidationError):
        process_randao(state, block, config)
Beispiel #12
0
 def _randao_provider_of_epoch_signature(public_key: BLSPubkey,
                                         epoch: Epoch) -> BLSSignature:
     private_key = private_key_provider(public_key)
     # TODO: fix how we get the signing root
     message = ssz.get_hash_tree_root(epoch, sedes=ssz.sedes.uint64)
     domain = compute_domain(SignatureDomain.DOMAIN_RANDAO)
     sig = bls.sign(message, private_key, domain)
     return sig
Beispiel #13
0
def sign(duty: Duty, operation: Operation,
         private_key_provider: PrivateKeyProvider) -> BLSSignature:
    message = operation.hash_tree_root
    private_key = private_key_provider(duty.validator_public_key)
    # TODO use correct ``domain`` value
    # NOTE currently only uses part of the domain value
    # need to get fork from the state and compute the full domain value locally
    domain = Domain(b"\x00" * 4 +
                    signature_domain_to_domain_type(duty.signature_domain))
    return bls.sign(message, private_key, domain)
Beispiel #14
0
def test_sanity(backend):
    bls.use(backend)
    msg_0 = b"\x32" * 32
    domain = 123

    # Test: Verify the basic sign/verify process
    privkey_0 = 5566
    sig_0 = bls.sign(msg_0, privkey_0, domain)
    assert_signature(sig_0)
    pubkey_0 = bls.privtopub(privkey_0)
    assert_pubkey(pubkey_0)
    assert bls.verify(msg_0, pubkey_0, sig_0, domain)

    privkey_1 = 5567
    sig_1 = bls.sign(msg_0, privkey_1, domain)
    pubkey_1 = bls.privtopub(privkey_1)
    assert bls.verify(msg_0, pubkey_1, sig_1, domain)

    # Test: Verify signatures are correctly aggregated
    aggregated_signature = bls.aggregate_signatures([sig_0, sig_1])
    assert_signature(aggregated_signature)

    # Test: Verify pubkeys are correctly aggregated
    aggregated_pubkey = bls.aggregate_pubkeys([pubkey_0, pubkey_1])
    assert_pubkey(aggregated_pubkey)

    # Test: Verify with `aggregated_signature` and `aggregated_pubkey`
    assert bls.verify(msg_0, aggregated_pubkey, aggregated_signature, domain)

    # Test: `verify_multiple`
    msg_1 = b"x22" * 32
    privkey_2 = 55688
    sig_2 = bls.sign(msg_1, privkey_2, domain)
    assert_signature(sig_2)
    pubkey_2 = bls.privtopub(privkey_2)
    assert_pubkey(pubkey_2)
    sig_1_2 = bls.aggregate_signatures([sig_1, sig_2])
    assert bls.verify_multiple(
        pubkeys=[pubkey_1, pubkey_2],
        message_hashes=[msg_0, msg_1],
        signature=sig_1_2,
        domain=domain,
    )
Beispiel #15
0
def sign_transaction(*, message_hash: Hash32, privkey: int, state: BeaconState,
                     slot: Slot, signature_domain: SignatureDomain,
                     slots_per_epoch: int) -> BLSSignature:
    domain = get_domain(
        state,
        signature_domain,
        slots_per_epoch,
        message_epoch=compute_epoch_at_slot(slot, slots_per_epoch),
    )
    return bls.sign(message_hash=message_hash, privkey=privkey, domain=domain)
Beispiel #16
0
def sign(duty: Duty, operation: Operation,
         private_key_provider: PrivateKeyProvider) -> BLSSignature:
    privkey = private_key_provider(duty.validator_public_key)
    # TODO use correct ``domain`` value
    # NOTE currently only uses part of the domain value
    # need to get fork from the state and compute the full domain value locally
    domain = compute_domain(duty.signature_domain)
    signing_root = compute_signing_root(operation, domain)

    return bls.sign(privkey, signing_root)
Beispiel #17
0
    def run_with(_cls, inputs: SignatureDescriptor,
                 _config: Optional[Eth2Config]) -> BLSSignature:
        # BLS override
        bls.use(MilagroBackend)

        return bls.sign(
            cast(Hash32, inputs["message_hash"]),
            int(inputs["privkey"]),
            cast(Domain, (inputs["domain"])),
        )
Beispiel #18
0
 def _randao_provider_of_epoch_signature(
     public_key: BLSPubkey, epoch: Epoch
 ) -> BLSSignature:
     private_key = private_key_provider(public_key)
     # TODO: fix how we get the signing root
     message = Hash32(epoch.to_bytes(32, byteorder="big"))
     domain = Domain(
         b"\x00" * 4 + signature_domain_to_domain_type(SignatureDomain.DOMAIN_RANDAO)
     )
     sig = bls.sign(message, private_key, domain)
     return sig
Beispiel #19
0
def get_slot_signature(state: BeaconState, slot: Slot, privkey: int,
                       config: Eth2Config) -> BLSSignature:
    """
    Sign on ``slot`` and return the signature.
    """
    domain = get_domain(
        state,
        SignatureDomain.DOMAIN_BEACON_ATTESTER,
        config.SLOTS_PER_EPOCH,
        message_epoch=compute_epoch_at_slot(slot, config.SLOTS_PER_EPOCH),
    )
    return bls.sign(get_hash_tree_root(slot, sedes=uint64), privkey, domain)
Beispiel #20
0
def get_block_signature(state: BeaconState, block: BeaconBlock,
                        private_key: int,
                        slots_per_epoch: int) -> BLSSignature:
    epoch = compute_epoch_at_slot(block.slot, slots_per_epoch)
    domain = get_domain(
        state,
        SignatureDomain.DOMAIN_BEACON_PROPOSER,
        slots_per_epoch,
        message_epoch=epoch,
    )
    signing_root = compute_signing_root(block, domain)
    return bls.sign(private_key, signing_root)
Beispiel #21
0
def test_multi_aggregation(backend, msg_1, msg_2, privkeys_1, privkeys_2,
                           domain):
    bls.use(backend)

    sigs_1 = [bls.sign(msg_1, k, domain=domain)
              for k in privkeys_1]  # signatures to msg_1
    pubs_1 = [bls.privtopub(k) for k in privkeys_1]
    aggpub_1 = bls.aggregate_pubkeys(pubs_1)  # sig_1 to msg_1

    sigs_2 = [bls.sign(msg_2, k, domain=domain)
              for k in privkeys_2]  # signatures to msg_2
    pubs_2 = [bls.privtopub(k) for k in privkeys_2]
    aggpub_2 = bls.aggregate_pubkeys(pubs_2)  # sig_2 to msg_2

    message_hashes = [msg_1, msg_2]
    pubs = [aggpub_1, aggpub_2]
    aggsig = bls.aggregate_signatures(sigs_1 + sigs_2)

    assert bls.verify_multiple(pubkeys=pubs,
                               message_hashes=message_hashes,
                               signature=aggsig,
                               domain=domain)
Beispiel #22
0
def get_slot_signature(
    state: BeaconState, slot: Slot, privkey: int, config: Eth2Config
) -> BLSSignature:
    """
    Sign on ``slot`` and return the signature.
    """
    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)
    return bls.sign(privkey, signing_root)
Beispiel #23
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)
Beispiel #24
0
def test_validate_proposer_signature(
        slots_per_epoch,
        shard_count,
        proposer_privkey,
        proposer_pubkey,
        is_valid_signature,
        sample_beacon_block_params,
        sample_beacon_state_params,
        target_committee_size,
        max_effective_balance,
        config):

    state = BeaconState(**sample_beacon_state_params).copy(
        validators=tuple(
            create_mock_validator(proposer_pubkey, config)
            for _ in range(10)
        ),
        balances=(max_effective_balance,) * 10,
    )

    block = BeaconBlock(**sample_beacon_block_params)
    header = block.header

    proposed_block = block.copy(
        signature=bls.sign(
            message_hash=header.signing_root,
            privkey=proposer_privkey,
            domain=get_domain(
                state,
                SignatureDomain.DOMAIN_BEACON_PROPOSER,
                slots_per_epoch,
            ),
        ),
    )

    if is_valid_signature:
        validate_proposer_signature(
            state,
            proposed_block,
            CommitteeConfig(config),
        )
    else:
        with pytest.raises(ValidationError):
            validate_proposer_signature(
                state,
                proposed_block,
                CommitteeConfig(config),
            )
def _get_indices_and_signatures(validator_count, state, config, attestation,
                                privkeys):
    num_indices = 5
    assert validator_count >= num_indices
    indices = random.sample(range(validator_count), num_indices)
    indices.sort()

    privkeys = [privkeys[i] for i in indices]
    domain = get_domain(
        state=state,
        signature_domain=SignatureDomain.DOMAIN_BEACON_ATTESTER,
        slots_per_epoch=config.SLOTS_PER_EPOCH,
    )
    signing_root = compute_signing_root(attestation.data, domain)

    signatures = tuple(map(lambda key: bls.sign(key, signing_root), privkeys))
    return (indices, signatures)
Beispiel #26
0
def sign(duty: Duty, operation: Operation,
         private_key_provider: PrivateKeyProvider) -> BLSSignature:
    privkey = private_key_provider(duty.validator_public_key)
    # TODO use correct ``domain`` value
    # NOTE currently only uses part of the domain value
    # need to get fork from the state and compute the full domain value locally
    # NOTE: hardcoded for testing, based on generating the minimal set of validators
    genesis_validators_root = Root(
        Hash32(
            bytes.fromhex(
                "83431ec7fcf92cfc44947fc0418e831c25e1d0806590231c439830db7ad54fda"
            )))
    domain = compute_domain(duty.signature_domain,
                            genesis_validators_root=genesis_validators_root)
    signing_root = compute_signing_root(operation, domain)

    return bls.sign(privkey, signing_root)
Beispiel #27
0
def _get_indices_and_signatures(validator_count, state, config, message_hash,
                                privkeys):
    num_indices = 5
    assert validator_count >= num_indices
    indices = random.sample(range(validator_count), num_indices)
    indices.sort()

    privkeys = [privkeys[i] for i in indices]
    signature_domain = SignatureDomain.DOMAIN_ATTESTATION
    domain = get_domain(
        state=state,
        signature_domain=signature_domain,
        slots_per_epoch=config.SLOTS_PER_EPOCH,
    )
    signatures = tuple(
        map(lambda key: bls.sign(message_hash, key, domain), privkeys))
    return (indices, signatures)
Beispiel #28
0
def sign_transaction(
    *,
    object: ssz.Serializable,
    privkey: int,
    state: BeaconState,
    slot: Slot,
    signature_domain: SignatureDomain,
    slots_per_epoch: int,
) -> BLSSignature:
    domain = get_domain(
        state,
        signature_domain,
        slots_per_epoch,
        message_epoch=compute_epoch_at_slot(slot, slots_per_epoch),
    )
    signing_root = compute_signing_root(object, domain)

    return bls.sign(privkey, signing_root)
Beispiel #29
0
 def _randao_provider_of_epoch_signature(
     public_key: BLSPubkey, epoch: Epoch
 ) -> BLSSignature:
     privkey = private_key_provider(public_key)
     # NOTE: hardcoded for testing, based on generating the minimal set of validators
     genesis_validators_root = Root(
         Hash32(
             bytes.fromhex(
                 "83431ec7fcf92cfc44947fc0418e831c25e1d0806590231c439830db7ad54fda"
             )
         )
     )
     domain = compute_domain(
         SignatureDomain.DOMAIN_RANDAO,
         genesis_validators_root=genesis_validators_root,
     )
     signing_root = compute_signing_root(SerializableUint64(epoch), domain)
     return bls.sign(privkey, signing_root)
Beispiel #30
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)