Exemple #1
0
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
Exemple #2
0
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
Exemple #6
0
#!/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))
Exemple #7
0
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'
Exemple #8
0
def genValidSignature(message, sk, pk, g):
    sig = bls.sign(sk, message)
    assert bls.verify(pk, message, sig, g)
    return sig
Exemple #9
0
def test_signing():
    sk, bls_pk = bls.keygen()
    msg = 'test message'
    sig = bls.sign(sk, msg)
    assert bls.verify(bls_pk, msg, sig)
Exemple #10
0
 def verify(self, pub):
     zig = self.sig
     self.sig = [0, 0]
     o = verify(serialize(self), pub, tuple(zig))
     self.sig = zig
     return o
Exemple #11
0
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