blob: 61fb53ae1f85493b8439d2155267d15d0d242ee0 [file] [log] [blame]
#
# Fp^4 CLass - towered over Fp^2
# M.Scott August 2018
#
import copy
from XXX import curve
from XXX.fp2 import *
class Fp4:
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 copy(self):
return copy.deepcopy(self)
def get(self):
return(self.a, self.b)
def set(self, a, b):
self.a = a
self.b = b
return self
def __add__(self, other):
return Fp4(self.a + other.a, self.b + other.b)
def __iadd__(self, other):
self.a += other.a
self.b += other.b
return self
def __sub__(self, other):
return Fp4(self.a - other.a, self.b - other.b)
def __isub__(self, other):
self.a -= other.a
self.b -= other.b
return self
def __eq__(self, other):
return (self.a == other.a and self.b == other.b)
def __ne__(self, other):
return (self.a != other.a or self.b != other.b)
def conj(self):
return Fp4(self.a, -self.b)
def sqr(self):
newa = (self.a + self.b) * (self.a + self.b.mulQNR())
self.b *= self.a
newa -= self.b
newa -= self.b.mulQNR()
self.b += self.b
self.a = newa.copy()
return self
def times_i(self):
s = self.b.copy()
t = self.b.copy()
s.times_i()
t += s
self.b = self.a
self.a = t
return self
def __imul__(self, other):
t1 = self.a * other.a
t2 = self.b * other.b
t3 = other.a + other.b
self.b += self.a
self.b *= t3
self.b -= t1
self.b -= t2
self.a = t1 + t2.mulQNR()
return self
def __mul__(self, other):
R = self.copy()
if R == other:
R.sqr()
else:
R *= other
return R
def muls(self, other): # multiple Fp4 by Fp2
return Fp4(self.a * other, self.b * other)
def __neg__(self):
return Fp4(-self.a, -self.b)
def real(self):
return self.a
def imaginary(self):
return self.b
def iszero(self):
if self.a.iszero() and self.b.iszero():
return True
return False
def isone(self):
if self.a.isone() and self.b.iszero():
return True
return False
def rand(self):
r = Fp2()
r.rand()
self.a = r.copy()
r.rand()
self.b = r.copy()
return self
def __str__(self): # pretty print
return "[%s,%s]" % (self.a, self.b)
def mulQNR(self): # assume p=3 mod 8, QNR=1+i
return Fp4(self.b.mulQNR(), self.a)
def inverse(self):
w = self.conj()
c = self.a * self.a - (self.b * self.b).mulQNR()
c = c.inverse()
w.a *= c
w.b *= c
return w
def powq(self):
X = Fp2(Fp(curve.Fra), Fp(curve.Frb))
X3 = X * X * X
return Fp4(self.a.conj(), self.b.conj() * X3)