예제 #1
0
def R2toR4(P):
    (N, D, E, F) = P
    return (
        GFp2.sub(N, D),
        GFp2.add(D, N),
        E
    )
예제 #2
0
def R1toR3(P):
    (X, Y, Z, Ta, Tb) = P
    return(
        GFp2.add(X, Y),
        GFp2.sub(Y, X),
        Z,
        GFp2.mul(Ta, Tb)
    )
예제 #3
0
 def selectpt(c, P1, P2):
     (N1, D1, E1, F1) = P1
     (N2, D2, E2, F2) = P2
     return (
         GFp2.select(c, N1, N2),
         GFp2.select(c, D1, D2),
         GFp2.select(c, E1, E2),
         GFp2.select(c, F1, F2),
     )
예제 #4
0
 def selectpt(c, P1, P2):
     (N1, D1, E1, F1) = P1
     (N2, D2, E2, F2) = P2
     return (
         GFp2.select(c, N1, N2),
         GFp2.select(c, D1, D2),
         GFp2.select(c, E1, E2),
         GFp2.select(c, F1, F2),
     )
예제 #5
0
def toAffine(P):
    if len(P) == 2:
        return P
    if len(P) != 3 and len(P) != 5:
        raise Exception("Representation unsupported for normalization")
    zi = GFp2.inv(P[2])
    xz = GFp2.mul(P[0], zi)
    yz = GFp2.mul(P[1], zi)
    return (xz, yz)
예제 #6
0
def PointOnCurve(P):
    (X, Y) = P
    X2 = GFp2.sqr(X)
    Y2 = GFp2.sqr(Y)
    LHS = GFp2.sub(Y2, X2)
    RHS = GFp2.add(GFp2.one, GFp2.mul(GFp2.mul(d, X2), Y2))
    return LHS == RHS
예제 #7
0
def PointOnCurve(P):
    (X, Y) = P
    X2 = GFp2.sqr(X)
    Y2 = GFp2.sqr(Y)
    LHS = GFp2.sub(Y2, X2)
    RHS = GFp2.add(GFp2.one, GFp2.mul(GFp2.mul(d, X2), Y2))
    return LHS == RHS
예제 #8
0
def test_reps():
    x = (0, 1)
    x2 = (0, 2)
    y = (2, 0)
    y2 = (4, 0)
    xy = (2, 1)
    yx = (2, p1271 - 1)
    z = (3, 4)
    z2 = (6, 8)
    ta = (5, 0)
    tb = (1, 6)
    t = (5, 30)
    td2 = GFp2.mul((2, 0), GFp2.mul(d, t))

    r1 = (x, y, z, ta, tb)
    r2 = (xy, yx, z2, td2)
    r3 = (xy, yx, z, t)
    r4 = (x2, y2, z2)

    test.test("R1toR2", R1toR2(r1), r2)
    test.test("R1toR3", R1toR3(r1), r3)
    test.test("R2toR4", R2toR4(r2), r4)
예제 #9
0
def test_reps():
    x  = (0, 1)
    x2 = (0, 2)
    y  = (2, 0)
    y2 = (4, 0)
    xy = (2, 1)
    yx = (2, p1271 - 1)
    z  = (3, 4)
    z2 = (6, 8)
    ta  = (5, 0)
    tb  = (1, 6)
    t   = (5, 30)
    td2 = GFp2.mul((2,0), GFp2.mul(d, t))

    r1 = (x, y, z, ta, tb)
    r2 = (xy, yx, z2, td2)
    r3 = (xy, yx, z, t)
    r4 = (x2, y2, z2)

    test.test("R1toR2", R1toR2(r1), r2)
    test.test("R1toR3", R1toR3(r1), r3)
    test.test("R2toR4", R2toR4(r2), r4)
예제 #10
0
def R1toR2(P):
    (X, Y, Z, Ta, Tb) = P
    return (
        GFp2.add(X, Y),
        GFp2.sub(Y, X),
        GFp2.add(Z, Z),
        GFp2.mul(GFp2.mul(GFp2.two, d), GFp2.mul(Ta, Tb))
    )
예제 #11
0
def decode(B):
    if len(B) != 32:
        raise Exception("Malformed point: length {} != 32".format(len(B)))
    if B[15] & 0x80 != 0x00:
        raise Exception("Malformed point: reserved bit is not zero")

    s = B[31] >> 7
    B[31] &= 0x7F

    y0 = GFp.fromLittleEndian(B[:16])
    y1 = GFp.fromLittleEndian(B[16:])

    if y0 >= p1271 or y1 >= p1271:
        raise Exception("Malformed point: reserved bit is not zero")

    y = (y0, y1)
    y2 = GFp2.sqr(y)
    (u0, u1) = GFp2.sub(y2, GFp2.one)
    (v0, v1) = GFp2.add(GFp2.mul(d, y2), GFp2.one)

    t0 = GFp.add(GFp.mul(u0, v0), GFp.mul(u1, v1))
    t1 = GFp.sub(GFp.mul(u1, v0), GFp.mul(u0, v1))
    t2 = GFp.add(GFp.sqr(v0), GFp.sqr(v1))
    t3 = GFp.add(GFp.sqr(t0), GFp.sqr(t1))
    t3 = GFp.mul(GFp.invsqrt(t3), t3)

    t = GFp.mul(2, GFp.add(t0, t3))
    if t == 0:
        t = GFp.mul(GFp.two, GFp.sub(t0, t3))

    a = GFp.invsqrt(GFp.mul(t, GFp.mul(t2, GFp.sqr(t2))))
    b = GFp.mul(GFp.mul(a, t2), t)

    x0 = GFp.mul(b, GFp.half)
    x1 = GFp.mul(GFp.mul(a, t2), t1)
    if t != GFp.mul(t2, GFp.sqr(b)):
        x0, x1 = x1, x0

    x = (x0, x1)
    if sign(x) != s:
        x = GFp2.neg(x)

    if not PointOnCurve((x, y)):
        x = GFp2.conj(x)
    if not PointOnCurve((x, y)):
        raise Exception("Point not on curve")

    return (x, y)
예제 #12
0
def decode(B):
    if len(B) != 32:
        raise Exception("Malformed point: length {} != 32".format(len(B)))
    if B[15] & 0x80 != 0x00:
        raise Exception("Malformed point: reserved bit is not zero")

    s = B[31] >> 7
    B[31] &= 0x7F

    y0 = GFp.fromLittleEndian(B[:16])
    y1 = GFp.fromLittleEndian(B[16:])

    if y0 >= p1271 or y1 >= p1271:
        raise Exception("Malformed point: reserved bit is not zero")

    y = (y0, y1)
    y2 = GFp2.sqr(y)
    (u0, u1) = GFp2.sub(y2, GFp2.one)
    (v0, v1) = GFp2.add(GFp2.mul(d, y2), GFp2.one)

    t0 = GFp.add(GFp.mul(u0, v0), GFp.mul(u1, v1))
    t1 = GFp.sub(GFp.mul(u1, v0), GFp.mul(u0, v1))
    t2 = GFp.add(GFp.sqr(v0), GFp.sqr(v1))
    t3 = GFp.add(GFp.sqr(t0), GFp.sqr(t1))
    t3 = GFp.mul(GFp.invsqrt(t3), t3)

    t = GFp.mul(2, GFp.add(t0, t3))
    if t == 0:
        t = GFp.mul(GFp.two, GFp.sub(t0, t3))

    a = GFp.invsqrt(GFp.mul(t, GFp.mul(t2, GFp.sqr(t2))))
    b = GFp.mul(GFp.mul(a, t2), t)

    x0 = GFp.mul(b, GFp.half)
    x1 = GFp.mul(GFp.mul(a, t2), t1)
    if t != GFp.mul(t2, GFp.sqr(b)):
        x0, x1 = x1, x0

    x = (x0, x1)
    if sign(x) != s:
        x = GFp2.neg(x)

    if not PointOnCurve((x, y)):
        x = GFp2.conj(x)
    if not PointOnCurve((x, y)):
        raise Exception("Point not on curve")

    return (x, y)
예제 #13
0
def DBL(P):
    (X1, Y1, Z1) = P[:3]
    A = GFp2.sqr(X1)
    B = GFp2.sqr(Y1)
    C = GFp2.mul(GFp2.two, GFp2.sqr(Z1))
    D = GFp2.add(A, B)
    E = GFp2.sub(GFp2.sqr(GFp2.add(X1, Y1)), D)
    F = GFp2.sub(B, A)
    G = GFp2.sub(C, F)
    X3 = GFp2.mul(E, G)
    Y3 = GFp2.mul(D, F)
    Z3 = GFp2. mul(F, G)
    Ta3 = E
    Tb3 = D
    return (X3, Y3, Z3, Ta3, Tb3)
예제 #14
0
def ADD_core(P, Q):
    (N1, D1, E1, F1) = P
    (N2, D2, Z2, T2) = Q
    A = GFp2.mul(D1, D2)
    B = GFp2.mul(N1, N2)
    C = GFp2.mul(T2, F1)
    D = GFp2.mul(Z2, E1)
    E = GFp2.sub(B, A)
    F = GFp2.sub(D, C)
    G = GFp2.add(D, C)
    H = GFp2.add(B, A)
    X3 = GFp2.mul(E, F)
    Y3 = GFp2.mul(G, H)
    Z3 = GFp2.mul(F, G)
    Ta3 = E
    Tb3 = H
    return (X3, Y3, Z3, Ta3, Tb3)
예제 #15
0
def DBL(P):
    (X1, Y1, Z1) = P[:3]
    A = GFp2.sqr(X1)
    B = GFp2.sqr(Y1)
    C = GFp2.mul(GFp2.two, GFp2.sqr(Z1))
    D = GFp2.add(A, B)
    E = GFp2.sub(GFp2.sqr(GFp2.add(X1, Y1)), D)
    F = GFp2.sub(B, A)
    G = GFp2.sub(C, F)
    X3 = GFp2.mul(E, G)
    Y3 = GFp2.mul(D, F)
    Z3 = GFp2.mul(F, G)
    Ta3 = E
    Tb3 = D
    return (X3, Y3, Z3, Ta3, Tb3)
예제 #16
0
def tau_dual(P):
    (X1, Y1, Z1) = P
    A = GFp2.sqr(X1)
    B = GFp2.sqr(Y1)
    C = GFp2.add(A, B)
    Ta2 = GFp2.sub(B, A)
    D = GFp2.sub(GFp2.mul(GFp2.two, GFp2.sqr(Z1)), Ta2)
    Tb2 = GFp2.mul(GFp2.mul(ctaudual, X1), Y1)
    X2 = GFp2.mul(Tb2, C)
    Y2 = GFp2.mul(Ta2, D)
    Z2 = GFp2.mul(C, D)
    return (X2, Y2, Z2, Ta2, Tb2)
예제 #17
0
 def R2neg(P):
     (N, D, E, F) = P
     return (D, N, E, GFp2.neg(F))
예제 #18
0
def upsilon(P):
    (X1, Y1, Z1) = P
    A = GFp2.mul(GFp2.mul(cphi0, X1), Y1)
    B = GFp2.mul(Y1, Z1)
    C = GFp2.sqr(Y1)
    D = GFp2.sqr(Z1)
    F = GFp2.sqr(D)
    G = GFp2.sqr(B)
    H = GFp2.sqr(C)
    I = GFp2.mul(cphi1, B)
    J = GFp2.add(C, GFp2.mul(cphi2, D))
    K = GFp2.add(GFp2.add(GFp2.mul(cphi8, G), H), GFp2.mul(cphi9, F))
    X2 = GFp2.mul(GFp2.add(I, J), GFp2.sub(I, J))
    X2 = GFp2.conj(GFp2.mul(GFp2.mul(A, K), X2))
    L = GFp2.add(C, GFp2.mul(cphi4, D))
    M = GFp2.mul(cphi3, B)
    N = GFp2.mul(GFp2.add(L, M), GFp2.sub(L, M))
    Y2 = GFp2.add(GFp2.add(H, GFp2.mul(cphi6, G)), GFp2.mul(cphi7, F))
    Y2 = GFp2.conj(GFp2.mul(GFp2.mul(GFp2.mul(cphi5, D), N), Y2))
    Z2 = GFp2.conj(GFp2.mul(GFp2.mul(B, K), N))
    return (X2, Y2, Z2)
예제 #19
0
def R1toAffine(P):
    (X, Y, Z, Ta, Tb) = P
    Zi = GFp2.inv(Z)
    return (GFp2.mul(X, Zi), GFp2.mul(Y, Zi))
예제 #20
0
def ADD_core(P, Q):
    (N1, D1, E1, F1) = P
    (N2, D2, Z2, T2) = Q
    A = GFp2.mul(D1, D2)
    B = GFp2.mul(N1, N2)
    C = GFp2.mul(T2, F1)
    D = GFp2.mul(Z2, E1)
    E = GFp2.sub(B, A)
    F = GFp2.sub(D, C)
    G = GFp2.add(D, C)
    H = GFp2.add(B, A)
    X3 = GFp2.mul(E, F)
    Y3 = GFp2.mul(G, H)
    Z3 = GFp2.mul(F, G)
    Ta3 = E
    Tb3 = H
    return (X3, Y3, Z3, Ta3, Tb3)
예제 #21
0
 def R2neg(P):
     (N, D, E, F) = P
     return (D, N, E, GFp2.neg(F))
예제 #22
0
def chi(P):
    (X1, Y1, Z1) = P
    A = GFp2.conj(X1)
    B = GFp2.conj(Y1)
    C = GFp2.sqr(GFp2.conj(Z1))
    D = GFp2.sqr(A)
    F = GFp2.sqr(B)
    G = GFp2.mul(B, GFp2.add(D, GFp2.mul(cpsi2, C)))
    H = GFp2.neg(GFp2.add(D, GFp2.mul(cpsi4, C)))
    X2 = GFp2.mul(GFp2.mul(GFp2.mul(cpsi1, A), C), H)
    Y2 = GFp2.mul(G, GFp2.add(D, GFp2.mul(cpsi3, C)))
    Z2 = GFp2.mul(G, H)
    return (X2, Y2, Z2)
예제 #23
0
def upsilon(P):
    (X1, Y1, Z1) = P
    A = GFp2.mul(GFp2.mul(cphi0, X1), Y1)
    B = GFp2.mul(Y1, Z1)
    C = GFp2.sqr(Y1)
    D = GFp2.sqr(Z1)
    F = GFp2.sqr(D)
    G = GFp2.sqr(B)
    H = GFp2.sqr(C)
    I = GFp2.mul(cphi1, B)
    J = GFp2.add(C, GFp2.mul(cphi2, D))
    K = GFp2.add(GFp2.add(GFp2.mul(cphi8, G), H), GFp2.mul(cphi9, F))
    X2 = GFp2.mul(GFp2.add(I, J), GFp2.sub(I, J))
    X2 = GFp2.conj(GFp2.mul(GFp2.mul(A, K), X2))
    L = GFp2.add(C, GFp2.mul(cphi4, D))
    M = GFp2.mul(cphi3, B)
    N = GFp2.mul(GFp2.add(L, M), GFp2.sub(L, M))
    Y2 = GFp2.add(GFp2.add(H, GFp2.mul(cphi6, G)), GFp2.mul(cphi7, F))
    Y2 = GFp2.conj(GFp2.mul(GFp2.mul(GFp2.mul(cphi5, D), N), Y2))
    Z2 = GFp2.conj(GFp2.mul(GFp2.mul(B, K), N))
    return (X2, Y2, Z2)
예제 #24
0
def tau(P):
    (X1, Y1, Z1) = P
    A = GFp2.sqr(X1)
    B = GFp2.sqr(Y1)
    C = GFp2.add(A, B)
    D = GFp2.sub(A, B)
    X2 = GFp2.mul(GFp2.mul(GFp2.mul(ctau, X1), Y1), D)
    Y2 = GFp2.neg(GFp2.mul(GFp2.add(GFp2.mul(GFp2.two, GFp2.sqr(Z1)), D), C))
    Z2 = GFp2.mul(C, D)
    return (X2, Y2, Z2)
예제 #25
0
def tau_dual(P):
    (X1, Y1, Z1) = P
    A = GFp2.sqr(X1)
    B = GFp2.sqr(Y1)
    C = GFp2.add(A, B)
    Ta2 = GFp2.sub(B, A)
    D = GFp2.sub(GFp2.mul(GFp2.two, GFp2.sqr(Z1)), Ta2)
    Tb2 = GFp2.mul(GFp2.mul(ctaudual, X1), Y1)
    X2 = GFp2.mul(Tb2, C)
    Y2 = GFp2.mul(Ta2, D)
    Z2 = GFp2.mul(C, D)
    return (X2, Y2, Z2, Ta2, Tb2)
예제 #26
0
def R1toAffine(P):
    (X, Y, Z, Ta, Tb) = P
    Zi = GFp2.inv(Z)
    return (GFp2.mul(X, Zi), GFp2.mul(Y, Zi))
예제 #27
0
def chi(P):
    (X1, Y1, Z1) = P
    A = GFp2.conj(X1)
    B = GFp2.conj(Y1)
    C = GFp2.sqr(GFp2.conj(Z1))
    D = GFp2.sqr(A)
    F = GFp2.sqr(B)
    G = GFp2.mul(B, GFp2.add(D, GFp2.mul(cpsi2, C)))
    H = GFp2.neg(GFp2.add(D, GFp2.mul(cpsi4, C)))
    X2 = GFp2.mul(GFp2.mul(GFp2.mul(cpsi1, A), C), H)
    Y2 = GFp2.mul(G, GFp2.add(D, GFp2.mul(cpsi3, C)))
    Z2 = GFp2.mul(G, H)
    return (X2, Y2, Z2)
예제 #28
0
def R1toR2(P):
    (X, Y, Z, Ta, Tb) = P
    return (GFp2.add(X, Y), GFp2.sub(Y, X), GFp2.add(Z, Z),
            GFp2.mul(GFp2.mul(GFp2.two, d), GFp2.mul(Ta, Tb)))
예제 #29
0
def R1toR3(P):
    (X, Y, Z, Ta, Tb) = P
    return (GFp2.add(X, Y), GFp2.sub(Y, X), Z, GFp2.mul(Ta, Tb))
예제 #30
0
def R2toR4(P):
    (N, D, E, F) = P
    return (GFp2.sub(N, D), GFp2.add(D, N), E)
예제 #31
0
def compare_ops():
    opcounts = {}

    m = getrandbits(256)
    G = curve4q.AffineToR1(curve4q.Gx, curve4q.Gy)
    k = '77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a'.decode('hex')
    u = '0900000000000000000000000000000000000000000000000000000000000000'.decode('hex')

    G392 = curve4q.MUL_endo(392, G)
    T_windowed = curve4q.table_windowed(G)
    T_endo = curve4q.table_endo(G)
    T392_windowed = curve4q.table_windowed(G392)
    T392_endo = curve4q.table_endo(G392)

    # R1toR2
    GFp2.ctr_reset()
    Q = curve4q.R1toR2(G)
    opcounts["R1toR2"] = GFp2.ctr()

    # R1toR3
    GFp2.ctr_reset()
    Q = curve4q.R1toR3(G)
    opcounts["R1toR3"] = GFp2.ctr()

    # R2toR4
    G2 = curve4q.R1toR2(G)
    GFp2.ctr_reset()
    Q = curve4q.R2toR4(G2)
    opcounts["R2toR4"] = GFp2.ctr()

    # ADD_core
    P = curve4q.R1toR3(G)
    Q = curve4q.R1toR2(G)
    GFp2.ctr_reset()
    R = curve4q.ADD_core(P, Q)
    opcounts["ADD_core"] = GFp2.ctr()

    # ADD
    P = G
    Q = curve4q.R1toR2(G)
    GFp2.ctr_reset()
    R = curve4q.ADD(P, Q)
    opcounts["ADD"] = GFp2.ctr()

    # DBL
    GFp2.ctr_reset()
    Q = curve4q.DBL(G)
    opcounts["DBL"] = GFp2.ctr()

    # MUL_windowed
    GFp2.ctr_reset()
    Q = curve4q.MUL_windowed(m, G)
    opcounts["MUL_windowed"] = GFp2.ctr()

    # MUL_windowed_fixed
    GFp2.ctr_reset()
    Q = curve4q.MUL_windowed(m, G, table=T_windowed)
    opcounts["MUL_windowed_fixed"] = GFp2.ctr()

    # Phi
    GFp2.ctr_reset()
    phiP = curve4q.phi(G)
    opcounts["phi"] = GFp2.ctr()

    # Psi
    GFp2.ctr_reset()
    psiP = curve4q.psi(G)
    opcounts["psi"] = GFp2.ctr()

    # MUL_endo
    GFp2.ctr_reset()
    mP = curve4q.MUL_endo(m, G)
    opcounts["MUL_endo"] = GFp2.ctr()

    # MUL_endo_fixed
    GFp2.ctr_reset()
    Q = curve4q.MUL_endo(m, G, table=T_endo)
    opcounts["MUL_endo_fixed"] = GFp2.ctr()

    # DH_windowed
    GFp2.ctr_reset()
    mP = curve4q.DH_windowed(m, G[:2])
    opcounts["DH_windowed"] = GFp2.ctr()

    # DH_windowed_fixed
    GFp2.ctr_reset()
    mP = curve4q.DH_windowed(m, G[:2], table=T392_windowed)
    opcounts["DH_windowed_fixed"] = GFp2.ctr()

    # DH_endo
    GFp2.ctr_reset()
    mP = curve4q.DH_endo(m, G[:2])
    opcounts["DH_endo"] = GFp2.ctr()

    # DH_endo_fixed
    GFp2.ctr_reset()
    mP = curve4q.DH_endo(m, G[:2], table=T392_endo)
    opcounts["DH_endo_fixed"] = GFp2.ctr()

    # x25519
    GFp25519.ctr_reset()
    ku = curve25519.x25519(k, u)
    opcounts["x25519"] = GFp25519.ctr()

    rows = ["R1toR2", "R1toR3", "R2toR4", "ADD_core", "ADD", "DBL",
            "phi", "psi", "psiphi",
            "MUL_windowed", "MUL_windowed_fixed", "MUL_endo", "MUL_endo_fixed",
            "DH_windowed", "DH_windowed_fixed", "DH_endo", "DH_endo_fixed",
            "x25519"]

    print "===== Field operation count ====="
    print
    print "{:18s} {:>7s} {:>7s} {:>7s} {:>7s}".format("", "M", "S", "A", "I")
    for name in rows:
        if name not in opcounts:
            continue
        opctr = opcounts[name]
        print "{:20s} {:7.1f} {:7.1f} {:7.1f} {:7.1f}".format(name, opctr[2], opctr[1], opctr[0], opctr[3])
    print
예제 #32
0
def tau(P):
    (X1, Y1, Z1) = P
    A = GFp2.sqr(X1)
    B = GFp2.sqr(Y1)
    C = GFp2.add(A, B)
    D = GFp2.sub(A, B)
    X2 = GFp2.mul(GFp2.mul(GFp2.mul(ctau, X1), Y1), D)
    Y2 = GFp2.neg(GFp2.mul(GFp2.add(GFp2.mul(GFp2.two, GFp2.sqr(Z1)), D), C))
    Z2 = GFp2.mul(C, D)
    return (X2, Y2, Z2)