示例#1
0
def test_vectors4():
    sk1 = PrivateKey.from_seed(bytes([1, 2, 3, 4, 5]))
    sk2 = PrivateKey.from_seed(bytes([1, 2, 3, 4, 5, 6]))

    pk1 = sk1.get_public_key()
    pk2 = sk2.get_public_key()

    m1 = bytes([7, 8, 9])
    m2 = bytes([10, 11, 12])

    sig9 = sk1.sign_prepend(m1)
    sig10 = sk2.sign_prepend(m2)

    assert (sig9.serialize() == bytes.fromhex(
        "d2135ad358405d9f2d4e68dc253d64b6049a821797817cffa5aa804086a8fb7b135175bb7183750e3aa19513db1552180f0b0ffd513c322f1c0c30a0a9c179f6e275e0109d4db7fa3e09694190947b17d890f3d58fe0b1866ec4d4f5a59b16ed"
    ))
    assert (sig10.serialize() == bytes.fromhex(
        "cc58c982f9ee5817d4fbf22d529cfc6792b0fdcf2d2a8001686755868e10eb32b40e464e7fbfe30175a962f1972026f2087f0495ba6e293ac3cf271762cd6979b9413adc0ba7df153cf1f3faab6b893404c2e6d63351e48cd54e06e449965f08"
    ))

    agg_sig = PrependSignature.aggregate([sig9, sig9, sig10])
    message_hashes = [hash256(m1), hash256(m1), hash256(m2)]
    pks = [pk1, pk1, pk2]
    assert (agg_sig.serialize() == bytes.fromhex(
        "c37077684e735e62e3f1fd17772a236b4115d4b581387733d3b97cab08b90918c7e91c23380c93e54be345544026f93505d41e6000392b82ab3c8af1b2e3954b0ef3f62c52fc89f99e646ff546881120396c449856428e672178e5e0e14ec894"
    ))
    assert (agg_sig.verify(message_hashes, pks))
示例#2
0
class PrivateKeyTests(unittest.TestCase):
    def setUp(self):
        bits = b"\x0c(\xfc\xa3\x86\xc7\xa2'`\x0b/\xe5\x0b|\xae\x11\xec\x86\xd3\xbf\x1f\xbeG\x1b\xe8\x98'\xe1\x9dr\xaa\x1d"
        self.key = PrivateKey(bits)

    def test_key_initialization(self):

        with self.assertRaises(KeyError):
            PrivateKey('toto')

        with self.assertRaises(KeyError):
            PrivateKey(b'\x01')

        with self.assertRaises(KeyError):
            PrivateKey(
                b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
            )

        with self.assertRaises(KeyError):
            PrivateKey(
                b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xBA\xAE\xDC\xE6\xAF\x48\xA0\x3B\xBF\xD2\x5E\x8C\xD0\x36\x41\x42'
            )

        PrivateKey(
            b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xBA\xAE\xDC\xE6\xAF\x48\xA0\x3B\xBF\xD2\x5E\x8C\xD0\x36\x41\x41'
        )
        self.assertTrue(True)

    def test_get_random_key(self):
        key = get_random_key()
        self.assertTrue(isinstance(key, PrivateKey))

    def test_get_key_from_hex(self):
        hexa = '0C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D'
        key = get_key_from_hex(hexa)
        self.assertEqual(
            key.as_hex(),
            '0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d')

    def test_as_hex(self):
        self.assertEqual(
            self.key.as_hex(),
            '0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d')

    def test_as_wif(self):
        self.assertEqual(
            self.key.as_wif(),
            '5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ')

    def test_get_public_key(self):
        pubkey = self.key.get_public_key()

        key = b'\x04\xd0\xde\x0a\xae\xae\xfa\xd0\x2b\x8b\xdc\x8a\x01\xa1\xb8\xb1\x1c\x69\x6b\xd3\xd6\x6a\x2c\x5f\x10\x78\x0d\x95\xb7\xdf\x42\x64\x5c\xd8\x52\x28\xa6\xfb\x29\x94\x0e\x85\x8e\x7e\x55\x84\x2a\xe2\xbd\x11\x5d\x1e\xd7\xcc\x0e\x82\xd9\x34\xe9\x29\xc9\x76\x48\xcb\x0a'
        self.assertEqual(pubkey, key)

    def test_get_address(self):
        address = self.key.get_address()
        self.assertEqual('1GAehh7TsJAHuUAeKZcXf5CnwuGuGgyX2S', address)
示例#3
0
def test_vectors2():
    m1 = bytes([1, 2, 3, 40])
    m2 = bytes([5, 6, 70, 201])
    m3 = bytes([9, 10, 11, 12, 13])
    m4 = bytes([15, 63, 244, 92, 0, 1])

    sk1 = PrivateKey.from_seed(bytes([1, 2, 3, 4, 5]))
    sk2 = PrivateKey.from_seed(bytes([1, 2, 3, 4, 5, 6]))

    sig1 = sk1.sign(m1)
    sig2 = sk2.sign(m2)
    sig3 = sk2.sign(m1)
    sig4 = sk1.sign(m3)
    sig5 = sk1.sign(m1)
    sig6 = sk1.sign(m4)

    sig_L = Signature.aggregate([sig1, sig2])
    sig_R = Signature.aggregate([sig3, sig4, sig5])
    assert (sig_L.verify())
    assert (sig_R.verify())

    sig_final = Signature.aggregate([sig_L, sig_R, sig6])
    assert (sig_final.serialize() == bytes.fromhex(
        "07969958fbf82e65bd13ba0749990764cac81cf10d923af9fdd2723f1e3910c3fdb874a67f9d511bb7e4920f8c01232b12e2fb5e64a7c2d177a475dab5c3729ca1f580301ccdef809c57a8846890265d195b694fa414a2a3aa55c32837fddd80"
    ))
    assert (sig_final.verify())
    quotient = sig_final.divide_by([sig2, sig5, sig6])
    assert (quotient.verify())
    assert (sig_final.verify())
    assert (quotient.serialize() == bytes.fromhex(
        "8ebc8a73a2291e689ce51769ff87e517be6089fd0627b2ce3cd2f0ee1ce134b39c4da40928954175014e9bbe623d845d0bdba8bfd2a85af9507ddf145579480132b676f027381314d983a63842fcc7bf5c8c088461e3ebb04dcf86b431d6238f"
    ))
    assert (quotient.divide_by([]) == quotient)
    try:
        quotient.divide_by([sig6])
        assert (False)  # Should fail due to not subset
    except:
        pass
    sig_final.divide_by([sig1])  # Should not throw
    try:
        sig_final.divide_by([sig_L])  # Should throw due to not unique
        assert (False)  # Should fail due to not unique
    except:
        pass

    # Divide by aggregate
    sig7 = sk2.sign(m3)
    sig8 = sk2.sign(m4)
    sig_R2 = Signature.aggregate([sig7, sig8])
    sig_final2 = Signature.aggregate([sig_final, sig_R2])
    quotient2 = sig_final2.divide_by([sig_R2])
    assert (quotient2.verify())
    assert (quotient2.serialize() == bytes.fromhex(
        "06af6930bd06838f2e4b00b62911fb290245cce503ccf5bfc2901459897731dd08fc4c56dbde75a11677ccfbfa61ab8b14735fddc66a02b7aeebb54ab9a41488f89f641d83d4515c4dd20dfcf28cbbccb1472c327f0780be3a90c005c58a47d3"
    ))
示例#4
0
    def create(T, N):
        """
        Create a new private key with associated data suitable for
        T of N threshold signatures under a Joint-Feldman scheme.

        After the dealing phase, one needs cooperation of T players
        out of N in order to sign a message with the master key pair.

        Return:
          - poly[0] - your share of the master secret key
          - commitments to your polynomial P
          - secret_fragments[j] = P(j), to be sent to player j
            (All N secret_fragments[j] can be combined to make a secret share.)
        """
        assert 1 <= T <= N
        g1 = generator_Fq()
        poly = [
            Fq(default_ec.n, RNG.randint(1, default_ec.n - 1))
            for _ in range(T)
        ]
        commitments = [g1 * c for c in poly]
        secret_fragments = [
            sum(c * pow(x, i, default_ec.n) for i, c in enumerate(poly))
            for x in range(1, N + 1)
        ]

        return PrivateKey(poly[0]), commitments, secret_fragments
示例#5
0
    def aggregate_priv_keys(private_keys, public_keys, secure):
        """
        Aggregates private keys together
        """
        if not secure:
            sum_keys = sum(pk.value for pk in private_keys) % default_ec.n

        else:
            if not public_keys:
                raise Exception(
                    "Must include public keys in secure aggregation")
            if len(private_keys) != len(public_keys):
                raise Exception("Invalid number of keys")

            priv_pub_keys = zip(public_keys, private_keys)
            priv_pub_keys.sort()
            computed_Ts = hash_pks(len(private_keys), public_keys)
            n = public_keys[0].value.ec.n

            sum_keys = 0
            for i, (_, privkey) in enumerate(priv_pub_keys):
                sum_keys += privkey.value * computed_Ts[i]
                sum_keys %= n

        return PrivateKey.from_bytes(sum_keys.to_bytes(32, "big"))
示例#6
0
def test_vectors():
    sk1 = PrivateKey.from_seed(bytes([1, 2, 3, 4, 5]))
    pk1 = sk1.get_public_key()
    sig1 = sk1.sign(bytes([7, 8, 9]))

    sk2 = PrivateKey.from_seed(bytes([1, 2, 3, 4, 5, 6]))
    pk2 = sk2.get_public_key()
    sig2 = sk2.sign(bytes([7, 8, 9]))
    assert (sk1.serialize() == bytes.fromhex(
        "022fb42c08c12de3a6af053880199806532e79515f94e83461612101f9412f9e"))
    assert (pk1.get_fingerprint() == 0x26d53247)
    assert (pk2.get_fingerprint() == 0x289bb56e)
    assert (sig1.serialize() == bytes.fromhex(
        "93eb2e1cb5efcfb31f2c08b235e8203a67265bc6a13d9f0ab77727293b74a357ff0459ac210dc851fcb8a60cb7d393a419915cfcf83908ddbeac32039aaa3e8fea82efcb3ba4f740f20c76df5e97109b57370ae32d9b70d256a98942e5806065"
    ))
    assert (sig2.serialize() == bytes.fromhex(
        "975b5daa64b915be19b5ac6d47bc1c2fc832d2fb8ca3e95c4805d8216f95cf2bdbb36cc23645f52040e381550727db420b523b57d494959e0e8c0c6060c46cf173872897f14d43b2ac2aec52fc7b46c02c5699ff7a10beba24d3ced4e89c821e"
    ))

    agg_sig = Signature.aggregate([sig1, sig2])
    agg_pk = PublicKey.aggregate([pk1, pk2], True)
    agg_sk = PrivateKey.aggregate([sk1, sk2], [pk1, pk2], True)
    assert (agg_sig.serialize() == bytes.fromhex(
        "0a638495c1403b25be391ed44c0ab013390026b5892c796a85ede46310ff7d0e0671f86ebe0e8f56bee80f28eb6d999c0a418c5fc52debac8fc338784cd32b76338d629dc2b4045a5833a357809795ef55ee3e9bee532edfc1d9c443bf5bc658"
    ))
    assert (agg_sk.sign(bytes([7, 8, 9])).serialize() == agg_sig.serialize())

    assert (sig1.verify())
    assert (agg_sig.verify())

    agg_sig.set_aggregation_info(
        AggregationInfo.from_msg(agg_pk, bytes([7, 8, 9])))
    assert (agg_sig.verify())

    sig1.set_aggregation_info(sig2.aggregation_info)
    assert (not sig1.verify())

    sig3 = sk1.sign(bytes([1, 2, 3]))
    sig4 = sk1.sign(bytes([1, 2, 3, 4]))
    sig5 = sk2.sign(bytes([1, 2]))

    agg_sig2 = Signature.aggregate([sig3, sig4, sig5])
    assert (agg_sig2.verify())
    assert (agg_sig2.serialize() == bytes.fromhex(
        "8b11daf73cd05f2fe27809b74a7b4c65b1bb79cc1066bdf839d96b97e073c1a635d2ec048e0801b4a208118fdbbb63a516bab8755cc8d850862eeaa099540cd83621ff9db97b4ada857ef54c50715486217bd2ecb4517e05ab49380c041e159b"
    ))
示例#7
0
def test2():
    seed = bytes([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
    seed2 = bytes([1, 20, 102, 229, 1, 157])

    sk = PrivateKey.from_seed(seed)
    sk_cp = PrivateKey.from_seed(seed)
    sk2 = PrivateKey.from_seed(seed2)
    pk = sk.get_public_key()
    pk2 = sk2.get_public_key()
    assert (sk == sk_cp)
    assert (sk != sk2)
    assert (pk.get_fingerprint() == 0xddad59bb)

    sk2_ser = sk2.serialize()
    pk2_ser = pk2.serialize()
    pk2_copy = PublicKey.from_bytes(pk2_ser)
    assert (pk2 == pk2_copy)
    assert (pk != pk2)
    assert (len(pk2_ser) == 48)
    assert (len(sk2_ser) == 32)

    message = bytes("this is the message", "utf-8")
    sig = sk.sign(message)
    sig_ser = sig.serialize()
    sig_cp = Signature.from_bytes(sig_ser)
    a1 = AggregationInfo.from_msg(pk, message)
    sig_cp.set_aggregation_info(a1)
    a2 = sig_cp.get_aggregation_info()
    assert (a1 == a2)
    sig2 = sk2.sign(message)

    assert (len(sig_ser) == 96)
    assert (sig != sig2)
    assert (sig == sig_cp)

    sig_agg = Signature.aggregate([sig, sig2])

    result = sig_cp.verify()
    result2 = sig2.verify()
    result3 = sig_agg.verify()
    assert (result)
    assert (result2)
    assert (result3)
    sk2 = sk
示例#8
0
    def test_key_initialization(self):

        with self.assertRaises(KeyError):
            PrivateKey('toto')

        with self.assertRaises(KeyError):
            PrivateKey(b'\x01')

        with self.assertRaises(KeyError):
            PrivateKey(
                b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
            )

        with self.assertRaises(KeyError):
            PrivateKey(
                b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xBA\xAE\xDC\xE6\xAF\x48\xA0\x3B\xBF\xD2\x5E\x8C\xD0\x36\x41\x42'
            )

        PrivateKey(
            b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xBA\xAE\xDC\xE6\xAF\x48\xA0\x3B\xBF\xD2\x5E\x8C\xD0\x36\x41\x41'
        )
        self.assertTrue(True)
示例#9
0
    def aggregate_priv_keys(private_keys, public_keys, secure):
        """
        Aggregates private keys together
        """
        if secure and len(private_keys) != len(public_keys):
            raise Exception("Invalid number of keys")

        priv_pub_keys = [(public_keys[i], private_keys[i])
                         for i in range(len(private_keys))]
        # Sort by public keys
        priv_pub_keys.sort()

        computed_Ts = hash_pks(len(private_keys), public_keys)

        n = public_keys[0].value.ec.n
        sum_keys = 0
        for i in range(len(priv_pub_keys)):
            addend = priv_pub_keys[i][1].value
            if (secure):
                addend *= computed_Ts[i]
            sum_keys = (sum_keys + addend) % n

        return PrivateKey.from_bytes(sum_keys.to_bytes(32, "big"))
示例#10
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
示例#11
0
def test1():
    seed = bytes([
        0, 50, 6, 244, 24, 199, 1, 25, 52, 88, 192, 19, 18, 12, 89, 6, 220, 18,
        102, 58, 209, 82, 12, 62, 89, 110, 182, 9, 44, 20, 254, 22
    ])
    sk = PrivateKey.from_seed(seed)
    pk = sk.get_public_key()

    msg = bytes([100, 2, 254, 88, 90, 45, 23])

    sig = sk.sign(msg)

    sk_bytes = sk.serialize()
    pk_bytes = pk.serialize()
    sig_bytes = sig.serialize()

    sk = PrivateKey.from_bytes(sk_bytes)
    pk = PublicKey.from_bytes(pk_bytes)
    sig = Signature.from_bytes(sig_bytes)

    sig.set_aggregation_info(AggregationInfo.from_msg(pk, msg))
    ok = sig.verify()
    assert (ok)

    seed = bytes([1]) + seed[1:]
    sk1 = PrivateKey.from_seed(seed)
    seed = bytes([2]) + seed[1:]
    sk2 = PrivateKey.from_seed(seed)

    pk1 = sk1.get_public_key()
    sig1 = sk1.sign(msg)

    pk2 = sk2.get_public_key()
    sig2 = sk2.sign(msg)

    agg_sig = Signature.aggregate([sig1, sig2])
    agg_pubkey = PublicKey.aggregate([pk1, pk2])

    agg_sig.set_aggregation_info(AggregationInfo.from_msg(agg_pubkey, msg))
    assert (agg_sig.verify())

    seed = bytes([3]) + seed[1:]
    sk3 = PrivateKey.from_seed(seed)
    pk3 = sk3.get_public_key()
    msg2 = bytes([100, 2, 254, 88, 90, 45, 23])

    sig1 = sk1.sign(msg)
    sig2 = sk2.sign(msg)
    sig3 = sk3.sign(msg2)
    agg_sig_l = Signature.aggregate([sig1, sig2])
    agg_sig_final = Signature.aggregate([agg_sig_l, sig3])

    sig_bytes = agg_sig_final.serialize()

    agg_sig_final = Signature.from_bytes(sig_bytes)
    a1 = AggregationInfo.from_msg(pk1, msg)
    a2 = AggregationInfo.from_msg(pk2, msg)
    a3 = AggregationInfo.from_msg(pk3, msg2)
    a1a2 = AggregationInfo.merge_infos([a1, a2])
    a_final = AggregationInfo.merge_infos([a1a2, a3])
    print(a_final)
    agg_sig_final.set_aggregation_info(a_final)
    ok = agg_sig_final.verify()

    ok = agg_sig_l.verify()
    agg_sig_final = agg_sig_final.divide_by([agg_sig_l])

    ok = agg_sig_final.verify()

    agg_sk = PrivateKey.aggregate([sk1, sk2], [pk1, pk2])
    agg_sk.sign(msg)

    seed = bytes([
        1, 50, 6, 244, 24, 199, 1, 25, 52, 88, 192, 19, 18, 12, 89, 6, 220, 18,
        102, 58, 209, 82, 12, 62, 89, 110, 182, 9, 44, 20, 254, 22
    ])

    esk = ExtendedPrivateKey.from_seed(seed)
    epk = esk.get_extended_public_key()

    sk_child = esk.private_child(0).private_child(5)
    pk_child = epk.public_child(0).public_child(5)

    buffer1 = pk_child.serialize()
    buffer2 = sk_child.serialize()

    print(len(buffer1), buffer1)
    print(len(buffer2), buffer2)
    assert (sk_child.get_extended_public_key() == pk_child)
示例#12
0
 def setUp(self):
     bits = b"\x0c(\xfc\xa3\x86\xc7\xa2'`\x0b/\xe5\x0b|\xae\x11\xec\x86\xd3\xbf\x1f\xbeG\x1b\xe8\x98'\xe1\x9dr\xaa\x1d"
     self.key = PrivateKey(bits)