def update_ffg_and_crosslink_progress(crystallized_state, crosslinks, ffg_voter_bitmask, votes): # Verify the attestations of crosslink hashes crosslink_votes = {vote.shard_block_hash + vote.shard_id.to_bytes(2, 'big'): vote.voter_bitmask for vote in crosslinks} new_ffg_bitmask = bytearray(ffg_voter_bitmask) total_voters = 0 for vote in votes: attestation = get_crosslink_aggvote_msg(vote.shard_id, vote.shard_block_hash, crystallized_state) indices = get_shard_attesters(crystallized_state, vote.shard_id) votekey = vote.shard_block_hash + vote.shard_id.to_bytes(2, 'big') if votekey not in crosslink_votes: crosslink_votes[votekey] = bytearray((len(indices) + 7) // 8) bitmask = crosslink_votes[votekey] pubs = [] for i, index in enumerate(indices): if vote.signer_bitmask[i//8] & (128>>(i%8)): pubs.append(crystallized_state.active_validators[index].pubkey) if new_ffg_bitmask[index//8] & (128>>(index%8)) == 0: new_ffg_bitmask[index//8] ^= 128>>(index%8) bitmask[i//8] ^= 128>>(i%8) total_voters += 1 assert verify(attestation, aggregate_pubs(pubs), vote.aggregate_sig) crosslink_votes[votekey] = bitmask print('Verified aggregate vote') new_crosslinks = [PartialCrosslinkRecord(shard_id=int.from_bytes(h[32:], 'big'), shard_block_hash=h[:32], voter_bitmask=crosslink_votes[h]) for h in sorted(crosslink_votes.keys())] return new_crosslinks, new_ffg_bitmask, total_voters
def process_attestations(validator_set, attestation_indices, attestation_bitmask, msg, aggregate_sig): # Verify the attestations of the parent pubs = [] balance_deltas = [] assert len(attestation_bitmask) == (len(attestation_indices) + 7) // 8 for i, index in enumerate(attestation_indices): if attestation_bitmask[i//8] & (128>>(i%8)): pubs.append(validator_set[index].pubkey) balance_deltas.append((index << 24) + 1) assert len(balance_deltas) <= 128 assert verify(msg, aggregate_pubs(pubs), aggregate_sig) print('Verified aggregate sig') return balance_deltas
def test_group_signature(): nodes = setup_and_register(n=3) for receiver, issuer in itertools.product(nodes, repeat=2): if receiver != issuer: receiver.load_shares(issuer.id, issuer.encrypted_shares, issuer.public_coefficients) for node in nodes: node.load_dispute_infos(disputed_node_ids={1}) node.derive_group_keys() master_bls_pk = nodes[1].master_bls_pk msg = 'test group signing' partial_sigs = [(node.id, node.sign(msg)) for node in nodes] group_sig = bls.aggregate( partial_sigs[1:]) # only use the last t signatures assert bls.verify(master_bls_pk, msg, group_sig)
def test_verification_of_aggregate_signature(): # generates and verfies a signature under the master key derived for contract # 0x64eB9cbc8AAc7723A7A94b178b7Ac4c18D7E6269 # see ../evaluation/testnet-execution for the transscripts master_pk = ( 16185756129160603637125524807239031401829819645832054270709340132395400777397, 8519501919971397775891715048167089286600326398415030764834336433929153469650, 18597752777763136713734159587276505878060020022295659236248459536349704859281, 451510684427994150648572847494629298315616628846799867117722216880750483787 ) msg = 'test message' msg_hash = hashlib.sha3_256(msg.encode()).digest() # ids for the 3 correct nodes A, B, C (assigned durign registration) id_A, id_B, id_C = 3, 2, 1 # group secret keys for the 3 correct nodes A, B and C gsk_A = ( 19063102076674778359749742475275688996157982969842615782345982391516317582432 ) gsk_B = ( 25409986690480885131491958594328734819629294462429970027081157236075400972958 ) gsk_C = ( 48802012483270245949082675044770005030925758437990233282811259804203609665090 ) sig_A = bls.sign(gsk_A, msg_hash) sig_B = bls.sign(gsk_B, msg_hash) sig_C = bls.sign(gsk_C, msg_hash) # three signature shares are sufficient to generate a signature which successfully verifies under the master pk sig = bls.aggregate([(id_A, sig_A), (id_B, sig_B), (id_C, sig_C)]) assert bls.verify(master_pk, msg_hash, sig) # verify that the signature can also be verified in the smart contract contract = utils.deploy_contract('DKG') assert contract.verify_signature(master_pk, msg_hash, sig)
def genValidSignature(message, sk, pk, g): sig = bls.sign(sk, message) assert bls.verify(pk, message, sig, g) return sig
#!/usr/bin/env python3 from charm.toolbox.pairinggroup import PairingGroup, ZR, G1, G2, GT, pair from bls import step_1 as verify from utils import jencode, jdecode if __name__ == "__main__": # Read {g, pk} v = jdecode(input("pub: ")) v.update(jdecode(input("m: "))) v.update(jdecode(input("sign: "))) print(verify(v))
from simpleserialize import serialize, deserialize, eq from full_pos import ActiveState, CheckpointRecord for x in (1, 5, 124, 735, 127409812145, 90768492698215092512159, 0): print('Testing with privkey %d' % x) p1 = multiply(G1, x) p2 = multiply(G2, x) msg = str(x).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, x) pub = privtopub(x) assert verify(msg, pub, sig) print('Testing signature aggregation') msg = b'cow' keys = [1, 5, 124, 735, 127409812145, 90768492698215092512159, 0] sigs = [sign(msg, k) for k in keys] pubs = [privtopub(k) for k in keys] aggsig = aggregate_sigs(sigs) aggpub = aggregate_pubs(pubs) assert verify(msg, aggpub, aggsig) print('Testing basic serialization') assert serialize(5, 'int8') == b'\x05' assert deserialize(b'\x05', 'int8') == 5 assert serialize(2**32 - 3, 'int40') == b'\x00\xff\xff\xff\xfd'
def genValidSignature(message, sk, pk, g): sig = bls.sign(sk, message) assert bls.verify(pk, message, sig, g) return sig
def test_signing(): sk, bls_pk = bls.keygen() msg = 'test message' sig = bls.sign(sk, msg) assert bls.verify(bls_pk, msg, sig)
def verify(self, pub): zig = self.sig self.sig = [0, 0] o = verify(serialize(self), pub, tuple(zig)) self.sig = zig return o
def compute_state_transition(parent_state, parent_block, block, verify_sig=True): crystallized_state, active_state = parent_state # Initialize a new epoch if needed if active_state.height % SHARD_COUNT == 0: print('Processing epoch transition') # Process rewards from FFG/crosslink votes new_validator_records = deepcopy(crystallized_state.active_validators) # Who voted in the last epoch ffg_voter_bitmask = bytearray(active_state.ffg_voter_bitmask) # Total deposit size total_deposits = crystallized_state.total_deposits # Old total deposit size td = total_deposits # Number of epochs since last finality finality_distance = crystallized_state.current_epoch - crystallized_state.last_finalized_epoch online_reward = 6 if finality_distance <= 2 else 0 offline_penalty = 3 * finality_distance total_vote_count = 0 total_vote_deposits = 0 total_validators = len(crystallized_state.active_validators) for i in range(total_validators): if ffg_voter_bitmask[i // 8] & (128 >> (i % 8)): total_vote_deposits += new_validator_records[i].balance new_validator_records[i].balance += online_reward total_vote_count += 1 else: new_validator_records[i].balance -= offline_penalty print( 'Total voted: %d of %d validators (%.2f%%), %d of %d deposits (%.2f%%)' % (total_vote_count, total_validators, total_vote_count * 100 / total_validators, total_vote_deposits, total_deposits, total_vote_deposits * 100 / total_deposits)) print('FFG online reward: %d, offline penalty: %d' % (online_reward, offline_penalty)) total_deposits += total_vote_count * online_reward - \ (total_validators - total_vote_count) * offline_penalty print('Total deposit change from FFG: %d' % (total_deposits - td)) td = total_deposits # Find the most popular crosslink in each shard main_crosslink = {} for c in active_state.checkpoints: vote_count = 0 mask = bytearray(c.voter_bitmask) for byte in mask: for j in range(8): vote_count += (byte >> j) % 2 if vote_count > main_crosslink.get(c.shard_id, (b'', 0, b''))[1]: main_crosslink[c.shard_id] = (c.checkpoint_hash, vote_count, mask) # Adjust crosslinks new_crosslink_records = deepcopy(crystallized_state.crosslink_records) for shard in range(SHARD_COUNT): print('Processing crosslink data for shard %d' % shard) indices = get_shard_attesters(crystallized_state, shard) h, votes, mask = main_crosslink.get( shard, (b'', 0, bytearray((len(indices) + 7) // 8))) crosslink_distance = crystallized_state.current_epoch - crystallized_state.crosslink_records[ shard].epoch print('Last crosslink from this shard was from epoch %d' % crystallized_state.crosslink_records[shard].epoch) online_reward = 3 if crosslink_distance <= 2 else 0 offline_penalty = crosslink_distance * 2 for i, index in enumerate(indices): if mask[i // 8] & (1 << (i % 8)): new_validator_records[index].balance += online_reward else: new_validator_records[index].balance -= offline_penalty total_deposits += votes * online_reward - (len(indices) - votes) * offline_penalty print('Total voters: %d of %d (%.2f%%)' % (votes, len(indices), votes * 100 / len(indices))) print('Crosslink online reward: %d, offline penalty: %d' % (online_reward, offline_penalty)) # New checkpoint last crosslinked record if votes * 3 >= len(indices) * 2: new_crosslink_records[shard] = CrosslinkRecord( hash=h, epoch=crystallized_state.current_epoch) print('Finalized checkpoint: %s' % hex(int.from_bytes(h, 'big'))) print('Total deposit change from crosslinks: %d' % (total_deposits - td)) td = total_deposits # Process other balance deltas for i in active_state.balance_deltas: if i % 256 <= 128: new_validator_records[i >> 8].balance += i % 256 total_deposits += i % 256 else: new_validator_records[i >> 8].balance += (i % 256) - 256 total_deposits += (i % 256) - 256 print('Total deposit change from deltas: %d' % (total_deposits - td)) print('New total deposits: %d' % total_deposits) # Process finality and validator set changes justify, finalize = False, False if total_vote_deposits * 3 >= total_deposits * 2: justify = True print('Justifying last epoch') if crystallized_state.last_justified_epoch == crystallized_state.current_epoch - 1: finalize = True print('Finalizing last epoch') if finalize: new_active_validators = [ v for v in crystallized_state.active_validators ] new_exited_validators = [ v for v in crystallized_state.exited_validators ] i = 0 while i < len(new_active_validators): if new_validator_records[i].balance <= DEFAULT_BALANCE // 2: new_exited_validators.append(new_validator_records.pop(i)) elif new_validator_records[ i].switch_dynasty == crystallized_state.dynasty + 1: new_exited_validators.append(new_validator_records.pop(i)) else: i += 1 induct = min(len(crystallized_state.queued_validators), len(crystallized_state.active_validators) // 30 + 1) for i in range(induct): if crystallized_state.queued_validators[ i].switch_dynasty > crystallized_state.dynasty + 1: induct = i break new_active_validators.append( crystallized_state.queued_validators[i]) new_queued_validators = crystallized_state.queued_validators[ induct:] else: new_queued_validators = crystallized_state.queued_validators new_active_validators = crystallized_state.active_validators new_exited_validators = crystallized_state.exited_validators crystallized_state = CrystallizedState( queued_validators=new_queued_validators, active_validators=new_active_validators, exited_validators=new_exited_validators, current_shuffling=get_shuffling(active_state.randao, len(new_active_validators)), last_justified_epoch=crystallized_state.current_epoch if justify else crystallized_state.last_justified_epoch, last_finalized_epoch=crystallized_state.current_epoch - 1 if finalize else crystallized_state.last_finalized_epoch, dynasty=crystallized_state.dynasty + (1 if finalize else 0), next_shard=0, current_epoch=crystallized_state.current_epoch + 1, crosslink_records=new_crosslink_records, total_deposits=total_deposits) # Reset the active state active_state = ActiveState( height=active_state.height, randao=active_state.randao, ffg_voter_bitmask=bytearray( (len(crystallized_state.active_validators) + 7) // 8), balance_deltas=[], checkpoints=[], total_skip_count=active_state.total_skip_count) # Process the block-by-block stuff # Verify the attestations of the parent attestation_indices, main_signer = \ get_attesters_and_signer(crystallized_state, active_state, block.skip_count) pubs = [] balance_deltas = [] assert len( block.attestation_bitmask) == (len(attestation_indices) + 7) // 8 for i, index in enumerate(attestation_indices): if block.attestation_bitmask[i // 8] & (128 >> (i % 8)): pubs.append(crystallized_state.active_validators[index].pubkey) balance_deltas.append((index << 8) + 1) assert len(balance_deltas) <= 128 balance_deltas.append((main_signer << 8) + len(balance_deltas)) assert verify(parent_block.hash, aggregate_pubs(pubs), block.attestation_aggregate_sig) print('Verified aggregate sig') # Verify the attestations of checkpoint hashes checkpoint_votes = { vote.checkpoint_hash + vote.shard_id.to_bytes(2, 'big'): vote.voter_bitmask for vote in active_state.checkpoints } new_ffg_bitmask = bytearray(active_state.ffg_voter_bitmask) for vote in block.shard_aggregate_votes: attestation = get_checkpoint_aggvote_msg(vote.shard_id, vote.checkpoint_hash, crystallized_state) indices = get_shard_attesters(crystallized_state, vote.shard_id) votekey = vote.checkpoint_hash + vote.shard_id.to_bytes(2, 'big') if votekey not in checkpoint_votes: checkpoint_votes[votekey] = bytearray((len(indices) + 7) // 8) bitmask = checkpoint_votes[votekey] pubs = [] voters = 0 for i, index in enumerate(indices): if vote.signer_bitmask[i // 8] & (128 >> (i % 8)): pubs.append(crystallized_state.active_validators[index].pubkey) if new_ffg_bitmask[index // 8] & (128 >> (index % 8)) == 0: new_ffg_bitmask[index // 8] ^= 128 >> (index % 8) bitmask[i // 8] ^= 128 >> (i % 8) voters += 1 assert verify(attestation, aggregate_pubs(pubs), vote.aggregate_sig) balance_deltas.append((main_signer << 8) + (voters * 16 // len(indices))) checkpoint_votes[votekey] = bitmask print('Verified aggregate vote') o = ActiveState( height=active_state.height + 1, randao=(int.from_bytes(active_state.randao, 'big') ^ int.from_bytes(block.randao_reveal, 'big')).to_bytes( 32, 'big'), total_skip_count=active_state.total_skip_count + block.skip_count, checkpoints=[ CheckpointRecord(shard_id=int.from_bytes(h[32:], 'big'), checkpoint_hash=h[:32], voter_bitmask=checkpoint_votes[h]) for h in sorted(checkpoint_votes.keys()) ], ffg_voter_bitmask=new_ffg_bitmask, balance_deltas=active_state.balance_deltas + balance_deltas) if verify_sig: assert block.verify( crystallized_state.active_validators[main_signer].pubkey) print('Verified main sig') return crystallized_state, o