示例#1
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)
示例#2
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)
示例#3
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')
示例#4
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))
示例#5
0
 def run_tests():
     import random
     from curve_ops import psi
     for _ in range(0, 128):
         t1 = Fq2(p, random.getrandbits(380), random.getrandbits(380))
         t2 = Fq2(p, random.getrandbits(380), random.getrandbits(380))
         # make sure each helper function actually returns a point on the curve
         for t in (t1, t2):
             P = osswu2_help(t)
             Pp = from_jacobian(P)
             assert Pp[0]**3 + Ell2p_a * Pp[0] + Ell2p_b == Pp[1]**2
             P = iso3(P)
             Pp = from_jacobian(P)
             assert Pp[0]**3 + Fq2(p, 4, 4) == Pp[1]**2
             P = psi(P)
             Pp = from_jacobian(P)
             assert Pp[0]**3 + Fq2(p, 4, 4) == Pp[1]**2
             P = clear_h2(P)
             Pp = from_jacobian(P)
             assert Pp[0]**3 + Fq2(p, 4, 4) == Pp[1]**2
         # now test end-to-end
         P = opt_swu2_map(t1, t2)
         Pp = from_jacobian(P)
         assert Pp[0]**3 + Fq2(p, 4, 4) == Pp[1]**2
         sys.stdout.write('.')
         sys.stdout.flush()
     sys.stdout.write("\n")
示例#6
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
示例#7
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)
示例#8
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())
示例#9
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)
示例#10
0
    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)
示例#11
0
import sys

from consts import p, q
from fields import Fq, Fq2

if sys.version_info[0] < 3:
    sys.exit("This script requires Python3 or PyPy3")

###
## generators for BLS signatures
###
# I'd rather have these in consts, but then we'd get an import cycle, consts <-> fields
g1gen = (Fq(p, 0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb),
         Fq(p, 0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1),
         Fq.one(p))
g2gen = (Fq2(p, 0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8,
                0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e),
         Fq2(p, 0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801,
                0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be),
         Fq2.one(p))

###
## Basic curve operations
###
# Jacobian coordinates
def from_jacobian(P):
    z3inv = ~(P[2] ** 3)
    return (P[0] * P[2] * z3inv, P[1] * z3inv)

# point equality or co-z repr
def _point_eq_coz(P, Q, coZ):
    (X1, Y1, Z1) = P
示例#12
0
import random
from fields import Fq1, Fq2
from curve import Curve, Point
from weil import miller_loop, weil_pairing

random.seed(1234)

print("\n\n1. Testing Fq1 and Fq2 inverse", end='')
Fq1.set_q(631)
Fq2.set_q(2**255 - 19)
for i in range(10):
    a1 = Fq1(random.randrange(1, Fq1.Q))
    b1 = Fq1.one() // a1
    assert a1 * b1 == Fq1.one()
    a2 = Fq2(random.randrange(1, Fq2.Q), random.randrange(1, Fq2.Q))
    b2 = Fq2.one() // a2
    res = a2 * b2
    assert a2 * b2 == Fq2.one()
print("...passed\n\n")

Curve.set_a_b(30, 34)
P = Point(x=Fq1(36), y=Fq1(60))
Q = Point(x=Fq1(121), y=Fq1(387))
S = Point(x=Fq1(0), y=Fq1(36))

print("group1 = [", end='')
for i in range(1, 5):
    g = Curve.multiply(P, i)
    print("(Affine {:3} {:3}), ".format(g.x.q, g.y.q), end='')
print("")
示例#13
0
from ec import JacobianPoint, default_ec_twist, eval_iso
from fields import Fq, Fq2, roots_of_unity
from hash_to_field import Hp2


def sgn0(x: Fq2) -> int:
    # https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-07#section-4.1

    sign_0: int = x[0].value % 2
    zero_0: bool = x[0] == 0
    sign_1: int = x[1].value % 2
    return sign_0 or (zero_0 and sign_1)


# distinguished non-square in Fp2 for SWU map
xi_2 = Fq2(q, -2, -1)

# 3-isogenous curve parameters
Ell2p_a = Fq2(q, 0, 240)
Ell2p_b = Fq2(q, 1012, 1012)

# eta values, used for computing sqrt(g(X1(t)))
# For details on how to compute, see ../sage-impl/opt_sswu_g2.sage
ev1 = 0x699BE3B8C6870965E5BF892AD5D2CC7B0E85A117402DFD83B7F4A947E02D978498255A2AAEC0AC627B5AFBDF1BF1C90
ev2 = 0x8157CD83046453F5DD0972B6E3949E4288020B5B8A9CC99CA07E27089A2CE2436D965026ADAD3EF7BABA37F2183E9B5
ev3 = 0xAB1C2FFDD6C253CA155231EB3E71BA044FD562F6F72BC5BAD5EC46A0B7A3B0247CF08CE6C6317F40EDBC653A72DEE17
ev4 = 0xAA404866706722864480885D68AD0CCAC1967C7544B447873CC37E0181271E006DF72162A3D3E0287BF597FBF7F8FC1
etas = (Fq2(q, ev1, ev2), Fq2(q, q - ev2, ev1), Fq2(q, ev3,
                                                    ev4), Fq2(q, q - ev4, ev3))
del ev1, ev2, ev3, ev4
示例#14
0
def decompress(point):
    greatest = point >> 2 * q_bits
    x_c0 = Fq(point & (2**q_bits - 1), q)
    x_c1 = Fq((point >> q_bits) & (2**q_bits - 1), q)
    x = Fq2(x_c0, x_c1)
    return TwistedEC.get_point_from_x(x, greatest)
示例#15
0
def g2_map(alpha: bytes, dst=None):
    return opt_swu2_map(*(Fq2(q, *hh) for hh in Hp2(alpha, 2, dst)))
示例#16
0
def map2curve_osswu2(alpha, dst=None):
    t1 = Fq2(p, *Hp2(alpha, 0, dst))
    t2 = Fq2(p, *Hp2(alpha, 1, dst))
    return opt_swu2_map(t1, t2)
示例#17
0
def qi_x(x):
    return Fq2(p, k_qi_x * x[0], p - k_qi_x * x[1])
示例#18
0
def map2curve_osswu2(alpha, dst=None):
    return opt_swu2_map(*(Fq2(p, *hh) for hh in Hp2(alpha, 2, dst)))
示例#19
0
def _from_bytes_F2(data):
    assert len(data) == 96
    return Fq2(p, _from_bytes_F1(data[48:]), _from_bytes_F1(data[:48]))
示例#20
0
def _gx2(x):
    return pow(x, 3) + Fq2(p, 4, 4)
示例#21
0
def qi_y(y):
    return Fq2(p, k_qi_y * (y[0] + y[1]), k_qi_y * (y[0] - y[1]))
示例#22
0
from fields import Fq, Fq2

# BLS parameter used to generate the other parameters
# Spec is found here: https://github.com/zkcrypto/pairing/tree/master/src/bls12_381
x = -0xD201000000010000

# 381 bit prime
# Also see fields:bls12381_q
q = 0x1A0111EA397FE69A4B1BA7B6434BACD764774B84F38512BF6730D2A0F6B0F6241EABFFFEB153FFFFB9FEFFFFFFFFAAAB

# a,b and a2, b2, define the elliptic curve and twisted curve.
# y^2 = x^3 + 4
# y^2 = x^3 + 4(u + 1)
a = Fq(q, 0)
b = Fq(q, 4)
a_twist = Fq2(q, 0, 0)
b_twist = Fq2(q, 4, 4)

# The generators for g1 and g2
gx = Fq(
    q,
    0x17F1D3A73197D7942695638C4FA9AC0FC3688C4F9774B905A14E3A3F171BAC586C55E83FF97A1AEFFB3AF00ADB22C6BB,
)
gy = Fq(
    q,
    0x08B3F481E3AAA0F1A09E30ED741D8AE4FCF5E095D5D00AF600DB18CB2C04B3EDD03CC744A2888AE40CAA232946C5E7E1,
)

g2x = Fq2(
    q,
    352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160,
示例#23
0
    q)

# G2
g2_x0 = Fq(
    352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160,
    q)
g2_x1 = Fq(
    3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758,
    q)
g2_y0 = Fq(
    1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905,
    q)
g2_y1 = Fq(
    927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582,
    q)
g2_x = Fq2(g2_x0, g2_x1)
g2_y = Fq2(g2_y0, g2_y1)

# BLS Params
BLS_x = 0xd201000000010000
BLS_negative = True

# Frobenius map coefficients
# Fq(-1)**(((q**0) - 1) // 2), Fq(-1)**(((q**1) - 1) // 2)
FROB_FQ2 = (
    Fq(1, q),
    Fq(
        4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559786,
        q))
# tuple(Fq2.all_one_poly(q) ** (((q ** i) - 1) // 3) for i in range(0, 6))
FROB_FQ6_C1 = (
示例#24
0
            Q = point_double(Q)
    return Q


###
## Fast cofactor clearing using the untwist-Frobenius-twist Endomorphism
###
# We use the version given in section 4.1 of
#    Budroni and Pintore, "Efficient hash maps to G2 on BLS curves,"
#    ePrint 2017/419 https://eprint.iacr.org/2017/419
# NOTE: this impl works for affine coordinates. See ../src/test/g2_test.sage for a version
#       that works for Jacobian projective coordinates without computing an inversion.
#
# constants for Psi, the untwist-Frobenius-twist endomorphism
iwsc = 0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f55ffff58a9ffffdcff7fffffffd556
iwsc = Fq2(p, iwsc, iwsc - 1)
k_qi_x = Fq(
    p,
    0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaad
)
k_qi_y = Fq(
    p,
    0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09
)
onei = Fq2(p, 1, 1)


# shortcut Frobenius evaluations that avoid going all the way to Fq12
def qi_x(x):
    return Fq2(p, k_qi_x * x[0], p - k_qi_x * x[1])
示例#25
0
#!/usr/bin/python
#
# (C) 2019 Riad S. Wahby <*****@*****.**>
#
# pure Python implementation of optimized simplified SWU map to BLS12-381 G2

from consts import g2suite, p
from curve_ops import clear_h2, eval_iso, from_jacobian, point_add
from fields import Fq2, sgn0, roots_of_unity
from hash_to_field import Hp2
from util import get_cmdline_options, print_g2_hex, print_tv_hash

# distinguished non-square in Fp2 for SWU map
xi_2 = Fq2(p, 1, 1)

# 3-isogenous curve parameters
Ell2p_a = Fq2(p, 0, 240)
Ell2p_b = Fq2(p, 1012, 1012)

# eta values, used for computing sqrt(g(X1(t)))
ev1 = 0x2c4a7244a026bd3e305cc456ad9e235ed85f8b53954258ec8186bb3d4eccef7c4ee7b8d4b9e063a6c88d0aa3e03ba01
ev2 = 0x85fa8cd9105715e641892a0f9a4bb2912b58b8d32f26594c60679cc7973076dc6638358daf3514d6426a813ae01f51a
etas = (Fq2(p, ev1, 0), Fq2(p, 0, ev1), Fq2(p, ev2, ev2), Fq2(p, ev2, p - ev2))
del ev1, ev2


###
## Simplified SWU map, optimized and adapted to Ell2'
###
# This function maps an element of Fp^2 to the curve Ell2', 3-isogenous to Ell2.
def osswu2_help(t):
示例#26
0
## generators for BLS signatures
###
# I'd rather have these in consts, but then we'd get an import cycle, consts <-> fields
g1gen = (
    Fq(
        p,
        0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb
    ),
    Fq(
        p,
        0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1
    ), Fq.one(p))
g2gen = (
    Fq2(
        p,
        0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8,
        0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e
    ),
    Fq2(
        p,
        0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801,
        0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be
    ), Fq2.one(p))


###
## Basic curve operations
###
# Jacobian coordinates
def from_jacobian(P):
    z3inv = ~(P[2]**3)