Ejemplo n.º 1
0
def test_threshold_instance(T, N):
    commitments = []
    # fragments[i][j] = fragment held by player i,
    #                   received from player j
    fragments = [[None] * N for _ in range(N)]
    secrets = []

    # Step 1 : PrivateKey.new_threshold
    for player in range(N):
        secret_key, commi, frags = PrivateKey.new_threshold(T, N)
        for target, frag in enumerate(frags):
            fragments[target][player] = frag
        commitments.append(commi)
        secrets.append(secret_key)

    # Step 2 : Threshold.verify_secret_fragment
    for player_source in range(1, N + 1):
        for player_target in range(1, N + 1):
            assert Threshold.verify_secret_fragment(
                T, fragments[player_target - 1][player_source - 1],
                player_target, commitments[player_source - 1])

    # Step 3 : master_pubkey = PublicKey.aggregate(...)
    #          secret_share = PrivateKey.aggregate(...)
    master_pubkey = PublicKey.aggregate(
        [PublicKey.from_g1(cpoly[0].to_jacobian()) for cpoly in commitments],
        False)

    secret_shares = [
        PrivateKey.aggregate(map(PrivateKey, row), None, False)
        for row in fragments
    ]

    master_privkey = PrivateKey.aggregate(secrets, None, False)
    msg = 'Test'
    signature_actual = master_privkey.sign(msg)

    # Step 4 : sig_share = secret_share.sign_threshold(...)
    # Check every combination of T players
    for X in combinations(range(1, N + 1), T):
        # X: a list of T indices like [1, 2, 5]

        # Check underlying secret key is correct
        r = Threshold.interpolate_at_zero(
            X, [secret_shares[x - 1].value for x in X])
        secret_cand = PrivateKey(r)
        assert secret_cand == master_privkey

        # Check signatures
        signature_shares = [
            secret_shares[x - 1].sign_threshold(msg, x, X) for x in X
        ]
        signature_cand = Signature.aggregate_sigs_simple(signature_shares)
        assert signature_cand == signature_actual

    # Check that the signature actually verifies the message
    agg_info = AggregationInfo.from_msg(master_pubkey, msg)
    signature_actual.set_aggregation_info(agg_info)
    assert signature_actual.verify()

    # Step 4b : Alternatively, we can add the lagrange coefficients
    # to 'unit' signatures.
    for X in combinations(range(1, N + 1), T):
        # X: a list of T indices like [1, 2, 5]

        # Check signatures
        signature_shares = [secret_shares[x - 1].sign(msg) for x in X]
        signature_cand = Threshold.aggregate_unit_sigs(signature_shares, X, T)
        assert signature_cand == signature_actual