Ejemplo n.º 1
0
 def to_affine(self) -> AffinePoint:
     if self.infinity:
         return AffinePoint(Fq.zero(self.ec.q), Fq.zero(self.ec.q),
                            self.infinity, self.ec)
     new_x = self.x / (self.z**2)
     new_y = self.y / (self.z**3)
     return AffinePoint(new_x, new_y, self.infinity, self.ec)
Ejemplo n.º 2
0
    def divide_by(self, divisor_signatures):
        """
        Signature division (elliptic curve subtraction). This is useful if
        you have already verified parts of the tree, since verification
        of the resulting quotient signature will be faster (less pairings
        have to be perfomed).

        This function Divides an aggregate signature by other signatures
        in the aggregate trees. A signature can only be divided if it is
        part of the subset, and all message/public key pairs in the
        aggregationInfo for the divisor signature are unique. i.e you cannot
        divide s1 / s2, if s2 is an aggregate signature containing m1,pk1,
        which is also present somewhere else in s1's tree. Note, s2 itself
        does not have to be unique.
        """
        message_hashes_to_remove = []
        pubkeys_to_remove = []
        prod = JacobianPoint(Fq2.one(default_ec.q), Fq2.one(default_ec.q),
                             Fq2.zero(default_ec.q), True, default_ec)
        for divisor_sig in divisor_signatures:
            pks = divisor_sig.aggregation_info.public_keys
            message_hashes = divisor_sig.aggregation_info.message_hashes
            if len(pks) != len(message_hashes):
                raise Exception("Invalid aggregation info")

            for i in range(len(pks)):
                divisor = divisor_sig.aggregation_info.tree[
                        (message_hashes[i], pks[i])]
                try:
                    dividend = self.aggregation_info.tree[
                        (message_hashes[i], pks[i])]
                except KeyError:
                    raise Exception("Signature is not a subset")
                if i == 0:
                    quotient = (Fq(default_ec.n, dividend)
                                / Fq(default_ec.n, divisor))
                else:
                    # Makes sure the quotient is identical for each public
                    # key, which means message/pk pair is unique.
                    new_quotient = (Fq(default_ec.n, dividend)
                                    / Fq(default_ec.n, divisor))
                    if quotient != new_quotient:
                        raise Exception("Cannot divide by aggregate signature,"
                                        + "msg/pk pairs are not unique")
                message_hashes_to_remove.append(message_hashes[i])
                pubkeys_to_remove.append(pks[i])
            prod += (divisor_sig.value * -quotient)
        copy = Signature(deepcopy(self.value + prod),
                            deepcopy(self.aggregation_info))

        for i in range(len(message_hashes_to_remove)):
            a = message_hashes_to_remove[i]
            b = pubkeys_to_remove[i]
            if (a, b) in copy.aggregation_info.tree:
                del copy.aggregation_info.tree[(a, b)]
        sorted_keys = list(copy.aggregation_info.tree.keys())
        sorted_keys.sort()
        copy.aggregation_info.message_hashes = [t[0] for t in sorted_keys]
        copy.aggregation_info.public_keys = [t[1] for t in sorted_keys]
        return copy
Ejemplo n.º 3
0
 def to_affine(self):
     if self.infinity:
         return AffinePoint(Fq.zero(self.ec.q), Fq.zero(self.ec.q),
                            self.infinity, self.ec)
     new_x = self.x / pow(self.z, 2)
     new_y = self.y / pow(self.z, 3)
     return AffinePoint(new_x, new_y, self.infinity, self.ec)
Ejemplo n.º 4
0
def test_ec():
    q = default_ec.q
    g = G1Generator()

    assert g.is_on_curve()
    assert 2 * g == g + g
    assert (3 * g).is_on_curve()
    assert 3 * g == g + g + g

    g2 = G2Generator()
    assert g2.x * (Fq(q, 2) * g2.y) == Fq(q, 2) * (g2.x * g2.y)
    assert g2.is_on_curve()
    s = g2 + g2
    assert untwist(twist(s.to_affine())) == s.to_affine()
    assert untwist(5 * twist(s.to_affine())) == (5 * s).to_affine()
    assert 5 * twist(s.to_affine()) == twist((5 * s).to_affine())
    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 == g2.y or -y == g2.y

    g_j = G1Generator()
    g2_j = G2Generator()
    g2_j2 = G2Generator() * 2
    assert g.to_affine().to_jacobian() == g
    assert (g_j * 2).to_affine() == g.to_affine() * 2
    assert (g2_j + g2_j2).to_affine() == g2.to_affine() * 3
Ejemplo n.º 5
0
def double_point_jacobian(p1: JacobianPoint,
                          ec=default_ec,
                          FE=Fq) -> JacobianPoint:
    """
    Jacobian elliptic curve point doubling
    http://www.hyperelliptic.org/EFD/oldefd/jacobian.html
    """
    X, Y, Z = p1.x, p1.y, p1.z
    if Y == FE.zero(ec.q) or p1.infinity:
        return JacobianPoint(FE.one(ec.q), FE.one(ec.q), FE.zero(ec.q), True,
                             ec)

    # S = 4*X*Y^2
    S = Fq(ec.q, 4) * X * Y * Y

    Z_sq = Z * Z
    Z_4th = Z_sq * Z_sq
    Y_sq = Y * Y
    Y_4th = Y_sq * Y_sq

    # M = 3*X^2 + a*Z^4
    M = Fq(ec.q, 3) * X * X
    M += ec.a * Z_4th

    # X' = M^2 - 2*S
    X_p = M * M - Fq(ec.q, 2) * S
    # Y' = M*(S - X') - 8*Y^4
    Y_p = M * (S - X_p) - Fq(ec.q, 8) * Y_4th
    # Z' = 2*Y*Z
    Z_p = Fq(ec.q, 2) * Y * Z
    return JacobianPoint(X_p, Y_p, Z_p, False, ec)
Ejemplo n.º 6
0
    def lagrange_coeffs_at_zero(X: List[int], ec=default_ec) -> List[Fq]:
        """
        We have k+1 integers X[i], all less than ec.n and non-zero.
        The points (X[i], P(X[i])) interpolate into P(X), a degree k polynomial.
        Returns coefficients L_i such that P(0) = sum L_i * P(X[i]).
        """
        N = len(X)

        # Check all x values are different, less than ec.n, and non-zero.
        assert len(set(X)) == N and all(0 != x < ec.n for x in X)

        def weight(j):
            ans = Fq(ec.n, 1)
            for i in range(N):
                if i != j:
                    ans *= Fq(ec.n, X[j] - X[i])
            return ~ans

        # Using the second barycentric form,
        # P(0) = (sum_j (y_j * w_j / x_j)) / (sum_j w_j/x_j)
        # If desired, the weights can be precomputed.

        ans = []
        denominator = Fq(ec.n, 0)
        for j in range(N):
            shift = weight(j) * ~Fq(ec.n, -X[j])
            ans.append(shift)
            denominator += shift
        denominator = ~denominator
        for i in range(len(ans)):
            ans[i] *= denominator
        return ans
Ejemplo n.º 7
0
def hash_to_point_prehashed_Fq(m, ec=default_ec):
    if type(m) != bytes:
        m = m.encode("utf-8")
    t0 = Fq(ec.q, int.from_bytes(hash512(m + b"G1_0"), "big"))
    t1 = Fq(ec.q, int.from_bytes(hash512(m + b"G1_1"), "big"))

    P = sw_encode(t0, ec, Fq) + sw_encode(t1, ec, Fq)

    return P * ec.h  # Scaling by cofactor
Ejemplo n.º 8
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()
    )
Ejemplo n.º 9
0
def test_edge_case_sign_Fq2():
    q = default_ec.q
    a = Fq(q, 62323)
    test_case_1 = Fq2(q, a, Fq(q, 0))
    test_case_2 = Fq2(q, -a, Fq(q, 0))
    assert sign_Fq2(test_case_1) != sign_Fq2(test_case_2)

    test_case_3 = Fq2(q, Fq(q, 0), a)
    test_case_4 = Fq2(q, Fq(q, 0), -a)

    assert sign_Fq2(test_case_3) != sign_Fq2(test_case_4)
Ejemplo n.º 10
0
def double_point(p1: AffinePoint, ec=default_ec, FE=Fq) -> AffinePoint:
    """
    Basic elliptic curve point doubling
    """
    x, y = p1.x, p1.y
    left = Fq(ec.q, 3) * x * x
    left = left + ec.a
    s = left / (Fq(ec.q, 2) * y)
    new_x = s * s - x - x
    new_y = s * (x - new_x) - y
    return AffinePoint(new_x, new_y, False, ec)
Ejemplo n.º 11
0
    def from_bytes(buffer):
        bit1 = buffer[0] & 0x80
        buffer = bytes([buffer[0] & 0x1f]) + buffer[1:]
        x = Fq(default_ec.q, int.from_bytes(buffer, "big"))
        y_values = y_for_x(Fq(default_ec.q, x))
        y_values.sort()
        y = y_values[0]

        if bit1:
            y = y_values[1]

        return PublicKey(AffinePoint(x, y, False, default_ec).to_jacobian())
Ejemplo n.º 12
0
def double_line_eval(R: AffinePoint, P: AffinePoint, ec=default_ec):
    """
    Creates an equation for a line tangent to R,
    and evaluates this at the point P. f(x) = y - sv - v.
    f(P).
    """
    R12 = untwist(R)

    slope = (Fq(ec.q, 3) * (R12.x**2) + ec.a) / (Fq(ec.q, 2) * R12.y)
    v = R12.y - slope * R12.x

    return P.y - P.x * slope - v
Ejemplo n.º 13
0
    def setUp(self):
        self.a1 = Fq(48, 199)
        self.b1 = Fq(50, 199)
        self.c1 = Fq(62, 199)
        self.A1 = EC.get_point_from_x(self.a1)
        self.B1 = EC.get_point_from_x(self.b1)

        self.a2 = Fq2(self.b1, self.a1)
        self.b2 = Fq2(self.b1, self.c1)
        self.A2 = TwistedEC.get_point_from_x(self.a2)
        self.B2 = TwistedEC.get_point_from_x(self.b2)

        self.g1 = EC.from_affine(g1_x, g1_y)
        self.g2 = TwistedEC.from_affine(g2_x, g2_y)
Ejemplo n.º 14
0
 def test_frobenius_coefficients(self):
     self.assertEqual((Fq(1, q), Fq(-1, q)), FROB_FQ2)
     self.assertEqual(
         tuple(
             Fq2.all_one_poly(q)**(((q**i) - 1) // 3) for i in range(0, 6)),
         FROB_FQ6_C1)
     self.assertEqual(
         tuple(
             Fq2.all_one_poly(q)**(((2 * q**i) - 2) // 3)
             for i in range(0, 6)), FROB_FQ6_C2)
     self.assertEqual(
         tuple(
             Fq2.all_one_poly(q)**(((q**i) - 1) // 6)
             for i in range(0, 12)), FROB_FQ12_C1)
Ejemplo n.º 15
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)
Ejemplo n.º 16
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())
Ejemplo n.º 17
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
Ejemplo n.º 18
0
    def main():
        for Pinf in ((F1_zero, F1_one, F1_zero), (F2_zero, F2_one, F2_zero)):
            test_ell(Pinf)
            sys.stdout.write('.')
            sys.stdout.flush()

        for _ in range(0, 32):
            sys.stdout.write('.')
            sys.stdout.flush()
            test_ell(opt_swu_map(Fq(p, random.getrandbits(380))))
            test_ell(
                opt_swu2_map(
                    Fq2(p, random.getrandbits(380), random.getrandbits(380))))

        for (ell2, invals) in ((False, invalid_inputs_1), (True,
                                                           invalid_inputs_2)):
            curve_name = "E2" if ell2 else "E1"
            for (idx, inval) in enumerate(invals):
                try:
                    deserialize(binascii.unhexlify(inval), ell2)
                except DeserError:
                    sys.stdout.write('*')
                    sys.stdout.flush()
                else:
                    raise DeserError(
                        "expected failed deserialization of #%d on %s" %
                        (idx, curve_name))

        sys.stdout.write('\n')
Ejemplo n.º 19
0
def sw_encode(t, ec=default_ec, FE=Fq):
    if t == 0:  # Maps t=0 to the point at infinity
        return JacobianPoint(FE.one(ec.q), FE.one(ec.q), FE.zero(ec.q), True,
                             ec)
    # Parity will ensure that sw_encode(t) = -sw_encode(-t)
    parity = False
    if FE == Fq:
        if t > -t:
            parity = True
    elif FE == Fq2:
        if t[1] > (-t)[1]:
            parity = True

    # w = t^2 + b + 1
    w = t * t + ec.b + 1

    # Map w=0 to generator and its negation
    if w == 0:
        if FE == Fq:
            ret = generator_Fq(ec)
        else:
            return generator_Fq2(ec)
        if parity:
            ret = ret.negate()
        return ret

    w = ~w * ec.sqrt_n3 * t

    # At least 1 of x1, x2, x3 is guaranteed to be a valid x
    # x1 = -wt + sqrt(-3)
    x1 = -w * t + ec.sqrt_n3m1o2

    # x2 = -x1 - 1
    x2 = FE.from_fq(ec.q, Fq(ec.q, -1)) - x1

    # x3 = 1/w^2 + 1
    x3 = ~(w * w) + 1

    # Constant time algorithm for finding the correct x, from
    # FT paper.
    Xx1 = 1
    Xx2 = 1
    try:
        y_for_x(x1, ec, FE)
    except:  # noqa: E772
        Xx1 = -1
    try:
        y_for_x(x2, ec, FE)
    except:  # noqa: E772
        Xx2 = -1

    index = (((Xx1 - 1) * Xx2) % 3)

    xs = [x1, x2, x3]
    ys = y_for_x(xs[index], ec, FE)
    ret = AffinePoint(xs[index], ys[0], False, ec)
    if ret.lex_gt_neg() is not parity:
        ret = ret.negate()
    return ret
Ejemplo n.º 20
0
    def from_bytes(buffer, aggregation_info=None):
        use_big_y = buffer[0] & 0x80

        buffer = bytes([buffer[0] & 0x1f]) + buffer[1:]

        x0 = int.from_bytes(buffer[:48], "big")
        x1 = int.from_bytes(buffer[48:], "big")
        x = Fq2(default_ec.q, Fq(default_ec.q, x0), Fq(default_ec.q, x1))
        ys = y_for_x(x, default_ec_twist, Fq2)
        y = ys[0]
        if ((use_big_y and ys[1][1] > default_ec.q // 2) or
                (not use_big_y and ys[1][1] < default_ec.q // 2)):
            y = ys[1]

        return Signature(AffinePoint(x, y, False, default_ec_twist)
                            .to_jacobian(),
                            aggregation_info)
Ejemplo n.º 21
0
def _from_bytes_F1(data):
    assert len(data) == 48
    ret = 0
    for d in data:
        ret = ret << 8
        ret += d
    if ret >= p:
        raise DeserError("invalid encoded value: not a residue mod p")
    return Fq(p, ret)
Ejemplo n.º 22
0
class TestFields(unittest.TestCase):
    def setUp(self):
        self.a1 = Fq(3, 11)
        self.b1 = Fq(4, 11)
        self.c1 = Fq(7, 11)
        self.d1 = Fq(12, 11)
        self.e1 = Fq(2, 11)
        self.f1 = Fq(9, 11)
        self.g1 = Fq(6, 11)

        self.a2 = Fq2(self.a1, self.b1)
        self.b2 = Fq2(self.b1, self.c1)
        self.c2 = Fq2(self.c1, self.d1)
        self.d2 = Fq2(self.d1, self.e1)
        self.e2 = Fq2(self.e1, self.f1)
        self.f2 = Fq2(self.f1, self.g1)

        self.a6 = Fq6(self.a2, self.b2, self.c2)
        self.b6 = Fq6(self.b2, self.c2, self.d2)
        self.c6 = Fq6(self.d2, self.e2, self.f2)

        self.a12 = Fq12(self.a6, self.b6)
        self.b12 = Fq12(self.b6, self.c6)

    def test_Fq(self):
        self.assertEqual(self.a1 + self.a1, self.a1 * 2)
        self.assertTrue((self.a1 - self.a1).is_zero())
        self.assertEqual(self.a1 + self.a1 + self.a1 + self.b1 + self.b1,
                         3 * self.a1 + 2 * self.b1)
        self.assertTrue((self.a1 * self.b1 / self.b1 / self.a1).is_one())
        self.assertEqual(self.a1.sqrt().square(), self.a1)
        self.assertEqual(self.a1**3, self.a1 * self.a1 * self.a1)

    def test_Fq2(self):
        self.assertEqual(self.a2 + self.a2, self.a2 * 2)
        self.assertTrue((self.a2 - self.a2).is_zero())
        self.assertEqual(self.a2 + self.a2 + self.a2 + self.b2 + self.b2,
                         3 * self.a2 + 2 * self.b2)
        self.assertTrue((self.a2 * self.b2 / self.b2 / self.a2).is_one())
        self.assertEqual(self.a2.sqrt().square(), self.a2)
        self.assertEqual(self.a2**3, self.a2 * self.a2 * self.a2)

    def test_Fq6(self):
        self.assertEqual(self.a6 + self.a6, self.a6 * 2)
        self.assertTrue((self.a6 - self.a6).is_zero())
        self.assertEqual(self.a6 + self.a6 + self.a6 + self.b6 + self.b6,
                         3 * self.a6 + 2 * self.b6)
        self.assertTrue((self.a6 * self.b6 / self.b6 / self.a6).is_one())
        self.assertEqual(self.a6**3, self.a6 * self.a6 * self.a6)

    def test_Fq12(self):
        self.assertEqual(self.a12 + self.a12, self.a12 * 2)
        self.assertTrue((self.a12 - self.a12).is_zero())
        self.assertEqual(self.a12 + self.a12 + self.a12 + self.b12 + self.b12,
                         3 * self.a12 + 2 * self.b12)
        self.assertTrue((self.a12 * self.b12 / self.b12 / self.a12).is_one())
        self.assertEqual(self.a12**3, self.a12 * self.a12 * self.a12)
Ejemplo n.º 23
0
    def from_bytes(buffer):
        use_big_y = buffer[0] & 0x80
        prepend = buffer[0] & 0x40
        if not prepend:
            raise "Should have prepend bit set"

        buffer = bytes([buffer[0] & 0x1f]) + buffer[1:]

        x0 = int.from_bytes(buffer[:48], "big")
        x1 = int.from_bytes(buffer[48:], "big")
        x = Fq2(default_ec.q, Fq(default_ec.q, x0), Fq(default_ec.q, x1))
        ys = y_for_x(x, default_ec_twist, Fq2)
        y = ys[0]
        if ((use_big_y and ys[1][1] > default_ec.q // 2)
                or (not use_big_y and ys[1][1] < default_ec.q // 2)):
            y = ys[1]

        return PrependSignature(
            AffinePoint(x, y, False, default_ec_twist).to_jacobian())
Ejemplo n.º 24
0
def test_fields():
    a = Fq(17, 30)
    b = Fq(17, -18)
    c = Fq2(17, a, b)
    d = Fq2(17, a + a, -5)
    e = c * d
    f = e * d
    assert f != e
    e_sq = e * e
    e_sqrt = e_sq.modsqrt()
    assert pow(e_sqrt, 2) == e_sq

    a2 = Fq(
        172487123095712930573140951348,
        3012492130751239573498573249085723940848571098237509182375,
    )
    b2 = Fq(172487123095712930573140951348, 3432984572394572309458723045723849)
    c2 = Fq2(172487123095712930573140951348, a2, b2)
    assert b2 != c2

    g = Fq6(17, c, d, d * d * c)
    h = Fq6(17, a + a * c, c * b * a, b * b * d * 21)
    i = Fq12(17, g, h)
    assert ~(~i) == i
    assert (~(i.root)) * i.root == Fq6.one(17)
    x = Fq12(17, Fq6.zero(17), i.root)
    assert (~x) * x == Fq12.one(17)

    j = Fq6(17, a + a * c, Fq2.zero(17), Fq2.zero(17))
    j2 = Fq6(17, a + a * c, Fq2.zero(17), Fq2.one(17))
    assert j == (a + a * c)
    assert j2 != (a + a * c)
    assert j != j2

    # Test frob_coeffs
    one = Fq(default_ec.q, 1)
    two = one + one
    a = Fq2(default_ec.q, two, two)
    b = Fq6(default_ec.q, a, a, a)
    c = Fq12(default_ec.q, b, b)
    for base in (a, b, c):
        for expo in range(1, base.extension):
            assert base.qi_power(expo) == pow(base, pow(default_ec.q, expo))
Ejemplo n.º 25
0
 def interpolate_at_zero(X: List[int], Y: List[Fq], ec=default_ec) -> Fq:
     """
     The k+1 points (X[i], Y[i]) interpolate into P(X),
     a degree k polynomial.
     Returns P(0).
     """
     ans = Fq(ec.n, 0)
     for lamb, y in zip(Threshold.lagrange_coeffs_at_zero(X, ec), Y):
         ans += lamb * y
     return ans
Ejemplo n.º 26
0
    def from_bytes(buffer, aggregation_info=None):
        use_big_y = buffer[0] & 0x80
        prepend = buffer[0] & 0x40
        if prepend:
            raise Exception("Should not have prepend bit set")

        buffer = bytes([buffer[0] & 0x1F]) + buffer[1:]

        x0 = int.from_bytes(buffer[:48], "big")
        x1 = int.from_bytes(buffer[48:], "big")
        x = Fq2(default_ec.q, Fq(default_ec.q, x0), Fq(default_ec.q, x1))
        ys = y_for_x(x, default_ec_twist, Fq2)
        y = ys[0]
        if (use_big_y and ys[1][1] > default_ec.q // 2) or (
                not use_big_y and ys[1][1] < default_ec.q // 2):
            y = ys[1]

        return Signature(
            AffinePoint(x, y, False, default_ec_twist).to_jacobian(),
            aggregation_info)
Ejemplo n.º 27
0
    def aggregate(public_keys, secure):
        """
        Aggregates public keys together
        """
        if len(public_keys) < 1:
            raise Exception("Invalid number of keys")
        public_keys.sort()

        computed_Ts = BLS.hash_pks(len(public_keys), public_keys)

        ec = public_keys[0].value.ec
        sum_keys = JacobianPoint(Fq.one(ec.q), Fq.one(ec.q),
                                 Fq.zero(ec.q), True, ec)
        for i in range(len(public_keys)):
            addend = public_keys[i].value
            if secure:
                addend *= computed_Ts[i]
            sum_keys += addend

        return PublicKey.from_g1(sum_keys)
Ejemplo n.º 28
0
 def run_tests():
     import random
     for _ in range(0, 128):
         t1 = Fq(p, random.getrandbits(380))
         t2 = Fq(p, random.getrandbits(380))
         # test helpers individually
         for t in (t1, t2):
             P = osswu_help(t)
             Pp = from_jacobian(P)
             assert Pp[0]**3 + EllP_a * Pp[0] + EllP_b == Pp[1]**2
             P = iso11(P)
             Pp = from_jacobian(P)
             assert Pp[0]**3 + 4 == Pp[1]**2
             P = clear_h(P)
             Pp = from_jacobian(P)
             assert Pp[0]**3 + 4 == Pp[1]**2
         # now test end-to-end
         P = from_jacobian(opt_swu_map(t1, t2))
         assert P[0]**3 + 4 == P[1]**2
         sys.stdout.write('.')
         sys.stdout.flush()
     sys.stdout.write("\n")
Ejemplo n.º 29
0
def osswu2_help(t):
    assert isinstance(t, Fq2)

    # first, compute X0(t), detecting and handling exceptional case
    num_den_common = xi_2**2 * t**4 + xi_2 * t**2
    x0_num = Ell2p_b * (num_den_common + Fq(q, 1))
    x0_den = -Ell2p_a * num_den_common
    x0_den = Ell2p_a * xi_2 if x0_den == 0 else x0_den

    # compute num and den of g(X0(t))
    gx0_den = pow(x0_den, 3)
    gx0_num = Ell2p_b * gx0_den
    gx0_num += Ell2p_a * x0_num * pow(x0_den, 2)
    gx0_num += pow(x0_num, 3)

    # try taking sqrt of g(X0(t))
    # this uses the trick for combining division and sqrt from Section 5 of
    # Bernstein, Duif, Lange, Schwabe, and Yang, "High-speed high-security signatures."
    # J Crypt Eng 2(2):77--89, Sept. 2012. http://ed25519.cr.yp.to/ed25519-20110926.pdf
    tmp1 = pow(gx0_den, 7)  # v^7
    tmp2 = gx0_num * tmp1  # u v^7
    tmp1 = tmp1 * tmp2 * gx0_den  # u v^15
    sqrt_candidate = tmp2 * pow(tmp1, (q**2 - 9) // 16)

    # check if g(X0(t)) is square and return the sqrt if so
    for root in roots_of_unity:
        y0 = sqrt_candidate * root
        if y0**2 * gx0_den == gx0_num:
            # found sqrt(g(X0(t))). force sign of y to equal sign of t
            if sgn0(y0) != sgn0(t):
                y0 = -y0
            assert sgn0(y0) == sgn0(t)
            return JacobianPoint(x0_num * x0_den, y0 * pow(x0_den, 3), x0_den,
                                 False, default_ec_twist)

    # if we've gotten here, then g(X0(t)) is not square. convert srqt_candidate to sqrt(g(X1(t)))
    (x1_num, x1_den) = (xi_2 * t**2 * x0_num, x0_den)
    (gx1_num, gx1_den) = (xi_2**3 * t**6 * gx0_num, gx0_den)
    sqrt_candidate *= t**3
    for eta in etas:
        y1 = eta * sqrt_candidate
        if y1**2 * gx1_den == gx1_num:
            # found sqrt(g(X1(t))). force sign of y to equal sign of t
            if sgn0(y1) != sgn0(t):
                y1 = -y1
            assert sgn0(y1) == sgn0(t)
            return JacobianPoint(x1_num * x1_den, y1 * pow(x1_den, 3), x1_den,
                                 False, default_ec_twist)

    # if we got here, something is wrong
    raise RuntimeError("osswu2_help failed for unknown reasons")
Ejemplo n.º 30
0
def hash_to_point_prehashed_Fq2(m, ec=default_ec_twist):
    if type(m) != bytes:
        m = m.encode("utf-8")
    t0_0 = Fq(ec.q, int.from_bytes(hash512(m + b"G2_0_c0"), "big"))
    t0_1 = Fq(ec.q, int.from_bytes(hash512(m + b"G2_0_c1"), "big"))
    t1_0 = Fq(ec.q, int.from_bytes(hash512(m + b"G2_1_c0"), "big"))
    t1_1 = Fq(ec.q, int.from_bytes(hash512(m + b"G2_1_c1"), "big"))

    t0 = Fq2(ec.q, t0_0, t0_1)
    t1 = Fq2(ec.q, t1_0, t1_1)

    P = sw_encode(t0, ec, Fq2) + sw_encode(t1, ec, Fq2)

    # This is the cofactor multiplication, done in a more
    # efficient way. See page 11 of "Efficient hash maps
    # to G2 on BLS curves" by Budrioni and Pintore.
    x = -ec.x
    psi2P = psi(psi(2 * P, ec), ec)
    t0 = x * P
    t1 = x * t0
    t2 = (t1 + t0) - P
    t3 = psi((x + 1) * P, ec)
    return t2 - t3 + psi2P