def mock_make_child(parent_state, parent, skips, attester_share=0.8, crosslink_shards=[]): crystallized_state, active_state = parent_state parent_attestation = serialize(parent) indices, main_signer = get_attesters_and_signer(crystallized_state, active_state, skips) print('Selected indices: %r' % indices) print('Selected main signer: %d' % main_signer) # Randomly pick indices to include bitfield = [1 if random.random() < attester_share else 0 for i in indices] # Attestations sigs = [bls.sign(parent_attestation, keymap[crystallized_state.active_validators[indices[i]].pubkey]) for i in range(len(indices)) if bitfield[i]] attestation_aggregate_sig = bls.aggregate_sigs(sigs) print('Aggregated sig') attestation_bitmask = bytearray((len(bitfield)-1) // 8 + 1) for i, b in enumerate(bitfield): attestation_bitmask[i//8] ^= (128 >> (i % 8)) * b print('Aggregate bitmask:', bin(int.from_bytes(attestation_bitmask, 'big'))) # Randomly pick indices to include for crosslinks shard_aggregate_votes = [] for shard, crosslinker_share in crosslink_shards: print('Making crosslink in shard %d' % shard) indices = get_shard_attesters(crystallized_state, shard) print('Indices: %r' % indices) bitfield = [1 if random.random() < crosslinker_share else 0 for i in indices] bitmask = bytearray((len(bitfield)+7) // 8) for i, b in enumerate(bitfield): bitmask[i//8] ^= (128 >> (i % 8)) * b print('Bitmask:', bin(int.from_bytes(bitmask, 'big'))) shard_block_hash = blake(bytes([shard])) crosslink_attestation_hash = get_crosslink_aggvote_msg(shard, shard_block_hash, crystallized_state) sigs = [bls.sign(crosslink_attestation_hash, keymap[crystallized_state.active_validators[indices[i]].pubkey]) for i in range(len(indices)) if bitfield[i]] v = AggregateVote(shard_id=shard, shard_block_hash=shard_block_hash, signer_bitmask=bitmask, aggregate_sig=list(bls.aggregate_sigs(sigs))) shard_aggregate_votes.append(v) print('Added %d shard aggregate votes' % len(crosslink_shards)) # State calculations o = Block(parent_hash=blake(parent_attestation), skip_count=skips, randao_reveal=blake(str(random.random()).encode('utf-8')), attestation_bitmask=attestation_bitmask, attestation_aggregate_sig=list(attestation_aggregate_sig), shard_aggregate_votes=shard_aggregate_votes, main_chain_ref=b'\x00'*32, state_hash=b'\x00'*64) print('Generated preliminary block header') new_crystallized_state, new_active_state = \ compute_state_transition((crystallized_state, active_state), parent, o, verify_sig=False) print('Calculated state transition') if crystallized_state == new_crystallized_state: o.state_hash = blake(parent.state_hash[:32] + blake(serialize(new_active_state))) else: o.state_hash = blake(blake(serialize(new_crystallized_state)) + blake(serialize(new_active_state))) # Main signature o.sign(keymap[crystallized_state.active_validators[main_signer].pubkey]) print('Signed') return o, new_crystallized_state, new_active_state
def mock_make_attestations(parent_state, block, attester_share=0.8): crystallized_state, active_state = parent_state cycle_length = config['cycle_length'] in_cycle_slot_height = block.slot_number % cycle_length indices = crystallized_state.indices_for_slots[cycle_length + in_cycle_slot_height] print("Generating attestations for shards: %s" % len(indices)) attestations = [] for shard_and_committee in indices: shard_id = shard_and_committee.shard_id committee_indices = shard_and_committee.committee print("Generating attestation for shard %s" % shard_id) print("Committee size %s" % len(committee_indices)) # Create attestation attestation = AttestationRecord( slot=block.slot_number, shard_id=shard_and_committee.shard_id, oblique_parent_hashes=[], shard_block_hash=blake(bytes(str(shard_id), 'utf-8')), attester_bitfield=get_empty_bitfield(len(committee_indices))) # Randomly pick indices to include is_attesting = [ random.random() < attester_share for _ in range(len(committee_indices)) ] # Proposer always attests is_attesting[0] = True # Generating signatures and aggregating result parent_hashes = get_hashes_to_sign(active_state, block, config) message = blake( attestation.slot.to_bytes(8, byteorder='big') + b''.join(parent_hashes) + shard_id.to_bytes(2, byteorder='big') + attestation.shard_block_hash) sigs = [ bls.sign(message, keymap[crystallized_state.validators[indice].pubkey]) for i, indice in enumerate(committee_indices) if is_attesting[i] ] attestation.aggregate_sig = bls.aggregate_sigs(sigs) print('Aggregated sig') attestation_bitfield = get_empty_bitfield(len(committee_indices)) for i, attesting in enumerate(is_attesting): if attesting: attestation_bitfield = set_voted(attestation_bitfield, i) attestation.attester_bitfield = attestation_bitfield print('Aggregate bitfield:', bin(int.from_bytes(attestation_bitfield, 'big'))) attestations.append(attestation) return attestations
def test_bls_core(privkey): p1 = multiply(G1, privkey) p2 = multiply(G2, privkey) msg = str(privkey).encode('utf-8') msghash = hash_to_G2(msg) assert normalize(decompress_G1(compress_G1(p1))) == normalize(p1) assert normalize(decompress_G2(compress_G2(p2))) == normalize(p2) assert normalize(decompress_G2(compress_G2(msghash))) == normalize(msghash) sig = sign(msg, privkey) pub = privtopub(privkey) assert verify(msg, pub, sig)
def sign(self, key): self.sig = [0, 0] self.sig = list(sign(serialize(self), key))
def mock_make_attestations(parent_state, block, attester_share=0.8): crystallized_state, active_state = parent_state cycle_length = config['cycle_length'] in_cycle_slot_height = block.slot_number % cycle_length indices = crystallized_state.shard_and_committee_for_slots[ cycle_length + in_cycle_slot_height] print("Generating attestations for shards: %s" % len(indices)) proposer_index_in_committee, proposer_shard_id = get_proposer_position( block, crystallized_state, config=config, ) attestations = [] for shard_and_committee in indices: shard_id = shard_and_committee.shard_id committee_indices = shard_and_committee.committee print("Generating attestation for shard %s" % shard_id) print("Committee size %s" % len(committee_indices)) justified_slot = crystallized_state.last_justified_slot justified_block_hash = active_state.chain.get_block_by_slot_number( justified_slot).hash # Create attestation attestation = AttestationRecord( slot=block.slot_number, shard_id=shard_and_committee.shard_id, oblique_parent_hashes=[], shard_block_hash=blake(bytes(str(shard_id), 'utf-8')), attester_bitfield=get_empty_bitfield(len(committee_indices)), justified_slot=justified_slot, justified_block_hash=justified_block_hash, ) # fill with roughly attester share fraction of voters is_attesting = [ i < attester_share * len(committee_indices) for i in range(len(committee_indices)) ] # Proposer always attests if shard_id == proposer_shard_id: is_attesting[proposer_index_in_committee] = True # Generating signatures and aggregating result parent_hashes = get_hashes_to_sign(active_state, block, config) message = blake( attestation.slot.to_bytes(8, byteorder='big') + b''.join(parent_hashes) + shard_id.to_bytes(2, byteorder='big') + attestation.shard_block_hash + attestation.justified_slot.to_bytes(8, byteorder='big')) sigs = [ bls.sign(message, keymap[crystallized_state.validators[indice].pubkey]) for i, indice in enumerate(committee_indices) if is_attesting[i] ] attestation.aggregate_sig = bls.aggregate_sigs(sigs) print('Aggregated sig') attestation_bitfield = get_empty_bitfield(len(committee_indices)) for i, attesting in enumerate(is_attesting): if attesting: attestation_bitfield = set_voted(attestation_bitfield, i) attestation.attester_bitfield = attestation_bitfield print('Aggregate bitfield:', bin(int.from_bytes(attestation_bitfield, 'big'))) attestations.append(attestation) return attestations
def make_unfinished_block(parent_state, parent, skips, attester_share=0.8, crosslink_shards_and_shares=None): if crosslink_shards_and_shares is None: crosslink_shards_and_shares = [] crystallized_state, active_state = parent_state parent_attestation = serialize(parent) indices, proposer = get_attesters_and_proposer( crystallized_state, active_state, skips, config ) print('Selected indices: %r' % indices) print('Selected block proposer: %d' % proposer) # Randomly pick indices to include is_attesting = [random.random() < attester_share for _ in indices] # Attestations sigs = [ bls.sign( parent_attestation, keymap[crystallized_state.active_validators[indices[i]].pubkey] ) for i, attesting in enumerate(is_attesting) if attesting ] attestation_aggregate_sig = bls.aggregate_sigs(sigs) print('Aggregated sig') attestation_bitfield = get_empty_bitfield(len(indices)) for i, attesting in enumerate(is_attesting): if attesting: attestation_bitfield = set_voted(attestation_bitfield, i) print('Aggregate bitfield:', bin(int.from_bytes(attestation_bitfield, 'big'))) # Randomly pick indices to include for crosslinks shard_aggregate_votes = [] # The shards that are selected to be crosslinking crosslink_shards = get_crosslink_shards(crystallized_state, config=config) for shard, crosslinker_share in crosslink_shards_and_shares: # Check if this shard is in the crosslink shards list assert shard in crosslink_shards print('Making crosslink in shard %d' % shard) indices = get_crosslink_notaries(crystallized_state, shard, crosslink_shards=crosslink_shards, config=config) print('Indices: %r' % indices) is_notarizing = [random.random() < attester_share for _ in indices] notary_bitfield = get_empty_bitfield(len(indices)) for i, notarizing in enumerate(is_notarizing): if notarizing: notary_bitfield = set_voted(notary_bitfield, i) print('Bitfield:', bin(int.from_bytes(notary_bitfield, 'big'))) shard_block_hash = blake(bytes([shard])) crosslink_attestation_hash = get_crosslink_aggvote_msg( shard, shard_block_hash, crystallized_state ) sigs = [ bls.sign( crosslink_attestation_hash, keymap[crystallized_state.active_validators[indices[i]].pubkey] ) for i, notarizing in enumerate(is_notarizing) if notarizing ] v = AggregateVote( shard_id=shard, shard_block_hash=shard_block_hash, notary_bitfield=notary_bitfield, aggregate_sig=list(bls.aggregate_sigs(sigs)) ) shard_aggregate_votes.append(v) print('Added %d shard aggregate votes' % len(crosslink_shards_and_shares)) block = Block( parent_hash=blake(parent_attestation), skip_count=skips, randao_reveal=blake(str(random.random()).encode('utf-8')), attestation_bitfield=attestation_bitfield, attestation_aggregate_sig=list(attestation_aggregate_sig), shard_aggregate_votes=shard_aggregate_votes, main_chain_ref=b'\x00'*32, state_hash=b'\x00'*64 ) return block, proposer
def make_unfinished_block(parent_state, parent, skips, attester_share=0.8, crosslink_shards_and_shares=None): if crosslink_shards_and_shares is None: crosslink_shards_and_shares = [] crystallized_state, active_state = parent_state parent_attestation = serialize(parent) indices, proposer = get_attesters_and_proposer(crystallized_state, active_state, skips, config) print('Selected indices: %r' % indices) print('Selected block proposer: %d' % proposer) # Randomly pick indices to include bitfield = [ 1 if random.random() < attester_share else 0 for i in indices ] # Attestations sigs = [ bls.sign( parent_attestation, keymap[ crystallized_state.active_validators[indices[i]].pubkey]) for i in range(len(indices)) if bitfield[i] ] attestation_aggregate_sig = bls.aggregate_sigs(sigs) print('Aggregated sig') attestation_bitfield = bytearray((len(bitfield) - 1) // 8 + 1) for i, b in enumerate(bitfield): attestation_bitfield[i // 8] ^= (128 >> (i % 8)) * b print('Aggregate bitfield:', bin(int.from_bytes(attestation_bitfield, 'big'))) # Randomly pick indices to include for crosslinks shard_aggregate_votes = [] # The shards that are selected to be crosslinking crosslink_shards = get_crosslink_shards(crystallized_state, config=config) for shard, crosslinker_share in crosslink_shards_and_shares: # Check if this shard is in the crosslink shards list assert shard in crosslink_shards print('Making crosslink in shard %d' % shard) indices = get_crosslink_notaries(crystallized_state, shard, crosslink_shards=crosslink_shards, config=config) print('Indices: %r' % indices) bitfield = [ 1 if random.random() < crosslinker_share else 0 for i in indices ] bitmask = bytearray((len(bitfield) + 7) // 8) for i, b in enumerate(bitfield): bitmask[i // 8] ^= (128 >> (i % 8)) * b print('Bitmask:', bin(int.from_bytes(bitmask, 'big'))) shard_block_hash = blake(bytes([shard])) crosslink_attestation_hash = get_crosslink_aggvote_msg( shard, shard_block_hash, crystallized_state) sigs = [ bls.sign( crosslink_attestation_hash, keymap[crystallized_state.active_validators[ indices[i]].pubkey]) for i in range(len(indices)) if bitfield[i] ] v = AggregateVote(shard_id=shard, shard_block_hash=shard_block_hash, signer_bitmask=bitmask, aggregate_sig=list(bls.aggregate_sigs(sigs))) shard_aggregate_votes.append(v) print('Added %d shard aggregate votes' % len(crosslink_shards_and_shares)) block = Block( parent_hash=blake(parent_attestation), skip_count=skips, randao_reveal=blake(str(random.random()).encode('utf-8')), attestation_bitfield=attestation_bitfield, attestation_aggregate_sig=list(attestation_aggregate_sig), shard_aggregate_votes=shard_aggregate_votes, main_chain_ref=b'\x00' * 32, state_hash=b'\x00' * 64) return block, proposer
def test_signature_aggregation(msg, privkeys): sigs = [sign(msg, k) for k in privkeys] pubs = [privtopub(k) for k in privkeys] aggsig = aggregate_sigs(sigs) aggpub = aggregate_pubs(pubs) assert verify(msg, aggpub, aggsig)