示例#1
0
def test_ec():
    g = generator_Fq(default_ec)

    assert g.is_on_curve()
    assert 2 * g == g + g
    assert (3 * g).is_on_curve()
    assert 3 * g == g + g + g
    P = hash_to_point_Fq(bytes([]))
    assert P.is_on_curve()
    assert P.serialize() == bytes.fromhex(
        "12fc5ad5a2fbe9d4b6eb0bc16d530e5f263b6d59cbaf26c3f2831962924aa588ab84d46cc80d3a433ce064adb307f256"
    )

    g2 = generator_Fq2(default_ec_twist)
    assert g2.x * (2 * g2.y) == 2 * (g2.x * g2.y)
    assert g2.is_on_curve()
    s = g2 + g2
    assert untwist(twist(s)) == s
    assert untwist(5 * twist(s)) == 5 * s
    assert 5 * twist(s) == twist(5 * s)
    assert s.is_on_curve()
    assert g2.is_on_curve()
    assert g2 + g2 == 2 * g2
    assert g2 * 5 == (g2 * 2) + (2 * g2) + g2
    y = y_for_x(g2.x, default_ec_twist, Fq2)
    assert y[0] == g2.y or y[1] == g2.y
    assert hash_to_point_Fq2("chia") == hash_to_point_Fq2("chia")

    g_j = generator_Fq(default_ec_twist).to_jacobian()
    g2_j = generator_Fq2(default_ec_twist).to_jacobian()
    g2_j2 = (generator_Fq2(default_ec_twist) * 2).to_jacobian()
    assert g.to_jacobian().to_affine() == g
    assert (g_j * 2).to_affine() == g * 2
    assert (g2_j + g2_j2).to_affine() == g2 * 3

    assert sw_encode(Fq(default_ec.q, 0)).infinity
    assert sw_encode(Fq(default_ec.q, 1)) == sw_encode(Fq(default_ec.q, -1)).negate()
    assert (
        sw_encode(
            Fq(
                default_ec.q,
                0x019CFABA0C258165D092F6BCA9A081871E62A126C499340DC71C0E9527F923F3B299592A7A9503066CC5362484D96DD7,
            )
        )
        == generator_Fq()
    )
    assert (
        sw_encode(
            Fq(
                default_ec.q,
                0x186417302D5A65347A88B0F999AB2B504614AA5E2EEBDEB1A014C40BCEB7D2306C12A6D436BEFCF94D39C9DB7B263CD4,
            )
        )
        == generator_Fq().negate()
    )
示例#2
0
def test_ec():
    g = generator_Fq(default_ec)

    assert (g.is_on_curve())
    assert (2 * g == g + g)
    assert ((3 * g).is_on_curve())
    assert (3 * g == g + g + g)
    P = hash_to_point_Fq(bytes([]))
    assert (P.is_on_curve())
    assert (P.serialize() == bytes.fromhex(
        "12fc5ad5a2fbe9d4b6eb0bc16d530e5f263b6d59cbaf26c3f2831962924aa588ab84d46cc80d3a433ce064adb307f256"
    ))

    g2 = generator_Fq2(default_ec_twist)
    assert (g2.x * (2 * g2.y) == 2 * (g2.x * g2.y))
    assert (g2.is_on_curve())
    s = g2 + g2
    assert (untwist(twist(s)) == s)
    assert (untwist(5 * twist(s)) == 5 * s)
    assert (5 * twist(s) == twist(5 * s))
    assert (s.is_on_curve())
    assert (g2.is_on_curve())
    assert (g2 + g2 == 2 * g2)
    assert (g2 * 5 == (g2 * 2) + (2 * g2) + g2)
    y = y_for_x(g2.x, default_ec_twist, Fq2)
    assert (y[0] == g2.y or y[1] == g2.y)
    assert (hash_to_point_Fq2("chia") == hash_to_point_Fq2("chia"))

    g_j = generator_Fq(default_ec_twist).to_jacobian()
    g2_j = generator_Fq2(default_ec_twist).to_jacobian()
    g2_j2 = (generator_Fq2(default_ec_twist) * 2).to_jacobian()
    assert (g.to_jacobian().to_affine() == g)
    assert ((g_j * 2).to_affine() == g * 2)
    assert ((g2_j + g2_j2).to_affine() == g2 * 3)

    assert (sw_encode(Fq(default_ec.q, 0)).infinity)
    assert (sw_encode(Fq(default_ec.q, 1)) == sw_encode(Fq(default_ec.q,
                                                           -1)).negate())
    assert (sw_encode(
        Fq(
            default_ec.q,
            0x019cfaba0c258165d092f6bca9a081871e62a126c499340dc71c0e9527f923f3b299592a7a9503066cc5362484d96dd7
        )) == generator_Fq())
    assert (sw_encode(
        Fq(
            default_ec.q,
            0x186417302d5a65347a88b0f999ab2b504614aa5e2eebdeb1a014c40bceb7d2306c12a6d436befcf94d39c9db7b263cd4
        )) == generator_Fq().negate())
示例#3
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
示例#4
0
    def verify_secret_fragment(
        player: int,
        secret_fragment: Fq,
        commitment: List[AffinePoint],
        T: int,
        ec=default_ec,
    ) -> bool:
        """
        You are player, and have received a secret share fragment,
        claimed to be shares[i] = P(player) from a polynomial P
        with the given commitment.

        Return True if the share given to you is correct wrt that commitment.
        """
        assert len(commitment) == T
        assert secret_fragment != 0
        assert player != 0

        g1 = generator_Fq(ec)
        lhs = g1 * secret_fragment
        rhs = commitment[0]
        for k in range(1, len(commitment)):
            rhs += commitment[k] * pow(player, k, ec.n)

        return lhs == rhs
示例#5
0
    def verify(self):
        """
        This implementation of verify has several steps. First, it
        reorganizes the pubkeys and messages into groups, where
        each group corresponds to a message. Then, it checks if the
        siganture has info on how it was aggregated. If so, we
        exponentiate each pk based on the exponent in the AggregationInfo.
        If not, we find public keys that share messages with others,
        and aggregate all of these securely (with exponents.).
        Finally, since each public key now corresponds to a unique
        message (since we grouped them), we can verify using the
        distinct verification procedure.
        """
        message_hashes = self.aggregation_info.message_hashes
        public_keys = self.aggregation_info.public_keys
        assert (len(message_hashes) == len(public_keys))

        hash_to_public_keys = {}
        for i in range(len(message_hashes)):
            if message_hashes[i] in hash_to_public_keys:
                hash_to_public_keys[message_hashes[i]].append(public_keys[i])
            else:
                hash_to_public_keys[message_hashes[i]] = [public_keys[i]]

        final_message_hashes = []
        final_public_keys = []
        ec = public_keys[0].value.ec
        for message_hash, mapped_keys in hash_to_public_keys.items():
            dedup = list(set(mapped_keys))
            public_key_sum = JacobianPoint(Fq.one(ec.q), Fq.one(ec.q),
                                           Fq.zero(ec.q), True, ec)
            for public_key in dedup:
                try:
                    exponent = self.aggregation_info.tree[(message_hash,
                                                           public_key)]
                    public_key_sum += (public_key.value * exponent)
                except KeyError:
                    return False
            final_message_hashes.append(message_hash)
            final_public_keys.append(public_key_sum.to_affine())

        mapped_hashes = [
            hash_to_point_prehashed_Fq2(mh) for mh in final_message_hashes
        ]

        g1 = Fq(default_ec.n, -1) * generator_Fq()
        Ps = [g1] + final_public_keys
        Qs = [self.value.to_affine()] + mapped_hashes
        res = ate_pairing_multi(Ps, Qs, default_ec)
        return res == Fq12.one(default_ec.q)
示例#6
0
    def verify(self, message_hashes, public_keys):
        """
        Verifies messages using the prepend method. It prepends public keys
        to message hashes before verifying.
        """
        assert (len(message_hashes) == len(public_keys))
        mapped_hashes = [
            hash_to_point_prehashed_Fq2(
                hash256(public_keys[i].serialize() + message_hashes[i]))
            for i in range(len(message_hashes))
        ]
        keys = [pk.value.to_affine() for pk in public_keys]

        g1 = Fq(default_ec.n, -1) * generator_Fq()
        Ps = [g1] + keys
        Qs = [self.value.to_affine()] + mapped_hashes
        res = ate_pairing_multi(Ps, Qs, default_ec)
        return res == Fq12.one(default_ec.q)
示例#7
0
 def get_public_key(self):
     return PublicKey.from_g1((self.value * generator_Fq()).to_jacobian())