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)
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)
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)
def R2neg(P): (N, D, E, F) = P return (D, N, E, GFp2.neg(F))