def test_signature_aggregation(msg, privkeys): domain = (0).to_bytes(8, "little") 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)
def _correct_slashable_attestation_params( slots_per_epoch, num_validators, params, message_hashes, privkeys, fork): valid_params = copy.deepcopy(params) (validator_indices, signatures) = _get_indices_and_signatures( num_validators, message_hashes[0], # custody bit is False privkeys, fork, slot_to_epoch(params["data"].slot, slots_per_epoch), ) valid_params["validator_indices"] = validator_indices valid_params["custody_bitfield"] = get_empty_bitfield(len(validator_indices)) aggregate_signature = bls.aggregate_signatures(signatures) valid_params["aggregate_signature"] = aggregate_signature return valid_params
def case06_aggregate_sigs(): for domain in DOMAINS: for message in MESSAGES: sigs = [bls.sign(message, privkey, domain) for privkey in PRIVKEYS] yield { 'input': ['0x' + sig.hex() for sig in sigs], 'output': '0x' + bls.aggregate_signatures(sigs).hex(), }
def case06_aggregate_sigs(): for domain in DOMAINS: for message in MESSAGES: sigs = [bls.sign(message, privkey, domain) for privkey in PRIVKEYS] yield f'agg_sigs_{encode_hex(message)}_{encode_hex(domain)}', { 'input': [encode_hex(sig) for sig in sigs], 'output': encode_hex(bls.aggregate_signatures(sigs)), }
def test_multi_aggregation(msg_1, msg_2, privkeys_1, privkeys_2): domain = (0).to_bytes(8, "little") 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) message_hashes = [msg_1, msg_2] pubs = [aggpub_1, aggpub_2] aggsig = aggregate_signatures([aggsig_1, aggsig_2]) assert verify_multiple( pubkeys=pubs, message_hashes=message_hashes, signature=aggsig, domain=domain, )
def aggregate_votes( bitfield: Bitfield, sigs: Sequence[BLSSignature], voting_sigs: Sequence[BLSSignature], voting_committee_indices: Sequence[CommitteeIndex] ) -> Tuple[Bitfield, BLSSignature]: """ Aggregate the votes. """ # Update the bitfield and append the signatures sigs = tuple(sigs) + tuple(voting_sigs) bitfield = pipe( bitfield, *(set_voted(index=committee_index) for committee_index in voting_committee_indices)) return bitfield, bls.aggregate_signatures(sigs)
def get_valid_attestation(state, slot=None): if slot is None: slot = state.slot if slot_to_epoch(slot) == get_current_epoch(state): shard = (state.latest_start_shard + slot) % spec.SLOTS_PER_EPOCH else: previous_shard_delta = get_shard_delta(state, get_previous_epoch(state)) shard = (state.latest_start_shard - previous_shard_delta + slot) % spec.SHARD_COUNT attestation_data = build_attestation_data(state, slot, shard) crosslink_committee = get_crosslink_committee_for_attestation(state, attestation_data) committee_size = len(crosslink_committee) bitfield_length = (committee_size + 7) // 8 aggregation_bitfield = b'\xC0' + b'\x00' * (bitfield_length - 1) custody_bitfield = b'\x00' * bitfield_length attestation = Attestation( aggregation_bitfield=aggregation_bitfield, data=attestation_data, custody_bitfield=custody_bitfield, ) participants = get_attesting_indices( state, attestation.data, attestation.aggregation_bitfield, ) assert len(participants) == 2 signatures = [] for validator_index in participants: privkey = privkeys[validator_index] signatures.append( get_attestation_signature( state, attestation.data, privkey ) ) attestation.aggregation_signature = bls.aggregate_signatures(signatures) return attestation
def bls_aggregate_signatures(signatures): return bls.aggregate_signatures(signatures)
def aggregate_signatures( signatures: Sequence[BLSSignature]) -> BLSSignature: # py_ecc use a different EMPTY_SIGNATURE. Return the Trinity one here: if len(signatures) == 0: return EMPTY_SIGNATURE return aggregate_signatures(signatures)
sigs.append(sig) # TODO: case05_verify_messages: Verify messages signed in case04 # It takes too long, empty for now case06_aggregate_sigs = [] for domain in DOMAINS: for message in MESSAGES: sigs = [] for privkey in PRIVKEYS: sig = bls.sign(message, privkey, domain) sigs.append(sig) case06_aggregate_sigs.append({ 'input': ['0x' + sig.hex() for sig in sigs], 'output': '0x' + bls.aggregate_signatures(sigs).hex(), }) case07_aggregate_pubkeys = [{ 'input': pubkeys_serial, 'output': '0x' + bls.aggregate_pubkeys(pubkeys).hex(), }] # TODO # Aggregate verify # TODO # Proof-of-possession