def powq(self): X = Fp2(Fp(curve.Fra), Fp(curve.Frb)) X2 = Fp2(Fp(curve.Fra), Fp(curve.Frb)) X2.sqr() self.a = self.a.powq() self.b = self.b.powq().muls(X) self.c = self.c.powq().muls(X2) return self
def __init__(self, a=None, b=None): if b is None: if a is None: self.a = Fp2() self.b = Fp2() else: self.a = a.copy() self.b = Fp2() else: self.a = a.copy() self.b = b.copy()
def fromBytes(self, W): FS = curve.EFS typ = W[0] xa = big.from_bytes(W[1:FS + 1]) xb = big.from_bytes(W[FS + 1:2 * FS + 1]) x = Fp2(Fp(xa), Fp(xb)) if typ == 0x04: ya = big.from_bytes(W[2 * FS + 1:3 * FS + 1]) yb = big.from_bytes(W[3 * FS + 1:4 * FS + 1]) y = Fp2(Fp(ya), Fp(yb)) return self.set(x, y) else: return self.setx(x, typ & 1)
def rand(self): r = Fp2() r.rand() self.a = r.copy() r.rand() self.b = r.copy() return self
def affine(self): if self.isinf() or self.z.isone(): return self iz = self.z.inverse() self.x *= iz self.y *= iz self.z = Fp2(Fp(1)) return self
def set(self, x, y): mx = x.copy() my = y.copy() if my * my != RHS(mx): return False self.x = mx self.y = my self.z = Fp2(Fp(1)) return True
def setx(self, x, s): mx = x.copy() rhs = RHS(mx) if rhs.qr() != 1: return False rhs.sqrt() if rhs.sign() != s: rhs = -rhs self.x = mx self.y = rhs self.z = Fp2(Fp(1)) return True
def unpack(T, Qx, Qy): aa, bb = T.get() aa = aa.muls(Qy) a = Fp4(aa, bb) t = Fp2(Qx) if curve.SexticTwist == D_TYPE: b = Fp4(t) c = Fp4() else: b = Fp4() c = Fp4(t).times_i() return Fp12(a, b, c)
def frobenius(self): X = Fp2(Fp(curve.Fra), Fp(curve.Frb)) if curve.SexticTwist == M_TYPE: X = X.inverse() X2 = X.copy() X2.sqr() # self.affine() self.x = self.x.conj() self.y = self.y.conj() self.z = self.z.conj() self.x *= X2 self.y *= X2 self.y *= X return self
def fromBytes(self, E): FS = curve.EFS a = Fp4(Fp2(Fp(big.from_bytes(E[0:FS])), Fp(big.from_bytes(E[FS:2 * FS]))), Fp2(Fp(big.from_bytes(E[2 * FS:3 * FS])), Fp(big.from_bytes(E[3 * FS:4 * FS])))) b = Fp4(Fp2(Fp(big.from_bytes(E[4 * FS:5 * FS])), Fp(big.from_bytes(E[5 * FS:6 * FS]))), Fp2(Fp(big.from_bytes(E[6 * FS:7 * FS])), Fp(big.from_bytes(E[7 * FS:8 * FS])))) c = Fp4(Fp2(Fp(big.from_bytes(E[8 * FS:9 * FS])), Fp(big.from_bytes(E[9 * FS:10 * FS]))), Fp2(Fp(big.from_bytes(E[10 * FS:11 * FS])), Fp(big.from_bytes(E[11 * FS:12 * FS])))) self.set(a, b, c)
def __init__(self): self.x = Fp2() self.y = Fp2(Fp(1)) self.z = Fp2()
def generator(): P = ECp2() P.set(Fp2(Fp(curve.Pxa), Fp(curve.Pxb)), Fp2(Fp(curve.Pya), Fp(curve.Pyb))) return P
def powq(self): X = Fp2(Fp(curve.Fra), Fp(curve.Frb)) X3 = X * X * X return Fp4(self.a.conj(), self.b.conj() * X3)
def get(self): # return tuple Fp2 x and Fp2 y W = self.copy() if (W.isinf()): return (Fp2(), Fp2()) W.affine() return (W.x, W.y)
def one(): return Fp12(Fp4(Fp2(Fp(1))))
def zero(): return Fp12(Fp4(Fp2(Fp(0))))
def RHS(x): if curve.SexticTwist == D_TYPE: return x * x * x + Fp2(ECp.B).divQNR() # on the sextic twist else: return x * x * x + Fp2(ECp.B).mulQNR() # on the sextic twist