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), )
def sign_proof_of_possession(deposit_data: DepositData, privkey: int) -> BLSSignature: return bls.sign( message_hash=deposit_data.signing_root, privkey=privkey, domain=compute_domain(SignatureDomain.DOMAIN_DEPOSIT), )
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
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)
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 deposit signature (proof of possession) for new validators. # Note: The deposit contract does not check signatures. # Note: Deposits are valid across forks, thus the deposit domain # is retrieved directly from `compute_domain`. is_valid_proof_of_possession = bls.verify( message_hash=deposit.data.signing_root, pubkey=pubkey, signature=deposit.data.signature, domain=compute_domain( SignatureDomain.DOMAIN_DEPOSIT, ), ) if not is_valid_proof_of_possession: 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, )
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)
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)
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)
def _randao_provider_of_epoch_signature(public_key: BLSPubkey, epoch: Epoch) -> BLSSignature: privkey = private_key_provider(public_key) domain = compute_domain(SignatureDomain.DOMAIN_RANDAO) signing_root = compute_signing_root(SerializableUint64(epoch), domain) return bls.sign(privkey, signing_root)
def sign_proof_of_possession(deposit_message: DepositMessage, privkey: int) -> BLSSignature: domain = compute_domain(SignatureDomain.DOMAIN_DEPOSIT) signing_root = compute_signing_root(deposit_message, domain) return bls.sign(privkey, signing_root)