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)
def generate_keys(cls, num: int, network_dir: Path, clients: Tuple[Client, ...]) -> Dict[Any, Any]: logger = cls.get_logger() logger.info("Creating %s validators' keys", num) keys_dir = network_dir / KEYS_DIR keys_dir.mkdir() privkeys = tuple( int.from_bytes(hash_eth2(str(i).encode('utf-8'))[:4], 'big') for i in range(num)) keymap = {bls.privtopub(key): key for key in privkeys} num_of_clients = len(clients) for validator_index, key in enumerate(privkeys): file_name = f"v{validator_index:07d}.privkey" private_key_path = keys_dir / file_name with open(private_key_path, "w") as f: f.write(str(key)) # Distribute keys to clients client = clients[validator_index % num_of_clients] with open(client.validator_keys_dir / file_name, "w") as f: f.write(str(key)) return keymap
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 generate_validator_keypairs(validator_count: int) -> Iterable[Dict]: for index in range(validator_count): privkey = generate_privkey_from_index(index) yield { "privkey": int_to_hex(privkey), "pubkey": encode_hex(bls.privtopub(privkey)), }
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)
def extract_privkeys_from_dir(dir_path: Path) -> Dict[BLSPubkey, int]: validator_keymap = {} # pub -> priv for key_file_name in os.listdir(dir_path): key_file_path = dir_path / key_file_name privkey = _read_privkey(key_file_path) validator_keymap[bls.privtopub(privkey)] = privkey if len(validator_keymap) == 0: raise KeyFileNotFound("No validator key file is provided") return validator_keymap
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, )
def create_key_pairs_for( validator_count: int) -> Iterable[Tuple[BLSPubkey, int]]: """ Generates ``validator_count`` key pairs derived in a deterministic manner based on the validator index in the ``range(validator_count)``. Returns a second map associating a public key with the validator's index in the set. """ for i in range(validator_count): private_key = generate_privkey_from_index(i) public_key = bls.privtopub(private_key) yield public_key, private_key
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)
def extract_privkeys_from_dir(dir_path: Path) -> Dict[BLSPubkey, int]: validator_keymap: Dict[BLSPubkey, int] = {} # pub -> priv try: key_files = os.listdir(dir_path) except FileNotFoundError: logger.debug('Could not find key directory: %s', str(dir_path)) return validator_keymap for key_file_name in key_files: key_file_path = dir_path / key_file_name privkey = _read_privkey(key_file_path) pubkey = bls.privtopub(privkey) validator_keymap[pubkey] = privkey logger.debug('imported public key: %s', humanize_hash(Hash32(pubkey))) if len(validator_keymap) == 0: pass return validator_keymap
from eth2.beacon.tools.builder.initializer import create_mock_genesis from eth2.beacon.tools.misc.ssz_vector import override_lengths from eth2.beacon.typing import Timestamp from eth2.configs import Eth2GenesisConfig NUM_VALIDATORS = 8 privkeys = tuple( int.from_bytes(hash_eth2(str(i).encode("utf-8"))[:4], "big") for i in range(NUM_VALIDATORS) ) index_to_pubkey = {} keymap = {} # pub -> priv for i, k in enumerate(privkeys): pubkey = bls.privtopub(k) index_to_pubkey[i] = pubkey keymap[pubkey] = k override_lengths(XIAO_LONG_BAO_CONFIG) genesis_state, genesis_block = create_mock_genesis( config=XIAO_LONG_BAO_CONFIG, pubkeys=tuple(keymap.keys()), keymap=keymap, genesis_block_class=SerenityBeaconBlock, genesis_time=Timestamp(int(time.time())), ) class BeaconChainFactory(factory.Factory):
def sample_bls_public_key(sample_bls_private_key): return bls.privtopub(sample_bls_private_key)
def run_with(_cls, inputs: int, _config: Optional[Eth2Config]) -> BLSPubkey: # BLS override bls.use(MilagroBackend) return bls.privtopub(inputs)
def mk_key_pair_from_seed_index(seed_index: int) -> Tuple[BLSPubkey, int]: privkey = int.from_bytes( hash_eth2(str(seed_index).encode("utf-8"))[:4], "big") pubkey = bls.privtopub(privkey) return (pubkey, privkey)
def _compute_key_pair_from_private_key_bytes( private_key_bytes: bytes) -> KeyPair: private_key = int.from_bytes(private_key_bytes, byteorder="big") return (bls.privtopub(private_key), private_key)
def _generate_pubkey(self, privkey): """ NOTE: this is currently our expensive function """ return bls.privtopub(privkey)
) block = BeaconBlock(**sample_beacon_block_params).copy( slot=block_slot, ) if isinstance(expected, Exception): with pytest.raises(ValidationError): validate_block_slot(state, block) else: validate_block_slot(state, block) @pytest.mark.parametrize( 'slots_per_epoch, shard_count,' 'proposer_privkey, proposer_pubkey, is_valid_signature', ( (5, 5, 56, bls.privtopub(56), True, ), (5, 5, 56, bls.privtopub(56)[1:] + b'\x01', False), (5, 5, 123, bls.privtopub(123), True), (5, 5, 123, bls.privtopub(123)[1:] + b'\x01', False), ) ) 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,
expected, ): state = BeaconState(**sample_beacon_state_params).copy(slot=state_slot) block = BeaconBlock(**sample_beacon_block_params).copy(slot=block_slot) if isinstance(expected, Exception): with pytest.raises(ValidationError): validate_block_slot(state, block) else: validate_block_slot(state, block) @pytest.mark.parametrize( "slots_per_epoch, max_committees_per_slot," "proposer_privkey, proposer_pubkey, is_valid_signature", ( (5, 5, 56, bls.privtopub(56), True), (5, 5, 56, bls.privtopub(56)[1:] + b"\x01", False), (5, 5, 123, bls.privtopub(123), True), (5, 5, 123, bls.privtopub(123)[1:] + b"\x01", False), ), ) def test_validate_proposer_signature( slots_per_epoch, max_committees_per_slot, proposer_privkey, proposer_pubkey, is_valid_signature, sample_beacon_block_params, sample_beacon_state_params, target_committee_size, max_effective_balance,
def _compute_key_pair_from_private_key_bytes( private_key_bytes: bytes) -> Tuple[BLSPubkey, BLSPrivateKey]: private_key = _deserialize_private_key(private_key_bytes) return (bls.privtopub(private_key), private_key)
def _mk_random_key_pair(index: int) -> KeyPair: private_key = _random_private_key(index) public_key = bls.privtopub(private_key) return (public_key, private_key)