blob: db47bd6b9681fe1005b53b4fca64a8dd24e669aa [file] [log] [blame]
#
# Fp^2 CLass
# M.Scott August 2018
#
import copy
from XXX.fp import *
# a+ib, where a,b are Fp, i is "imaginary" sqrt(-1) mod p
class Fp2:
def __init__(self, a=None, b=None):
if b is None:
if a is None:
self.a = Fp(0)
self.b = Fp(0)
else:
self.a = a.copy()
self.b = Fp(0)
else:
self.a = a.copy()
self.b = b.copy()
def copy(self):
return copy.deepcopy(self)
def get(self):
return(self.a.int(), self.b.int())
def set(self, a, b):
self.a = Fp(a)
self.b = Fp(b)
return self
def __add__(self, other):
return Fp2(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 Fp2(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 Fp2(self.a, -self.b)
def sqr(self):
newa = (self.a + self.b) * (self.a - self.b)
self.b *= self.a
self.b += self.b
self.a = newa.copy()
return self
def times_i(self):
x = self.a.copy()
self.a = self.b
self.b = x
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
return self
def __mul__(self, other):
R = self.copy()
if R == other:
R.sqr()
else:
R *= other
return R
def muli(self, other):
return Fp2(self.a.muli(other), self.b.muli(other))
def muls(self, other):
return Fp2(self.a * other, self.b * other)
def __neg__(self):
return Fp2(-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 = Fp()
r.rand()
self.a = r.copy()
r.rand()
self.b = r.copy()
return self
def __str__(self): # pretty print
return "[%x,%x]" % (self.a.int(), self.b.int())
def mulQNR(self): # assume p=3 mod 8, QNR=1+i
return Fp2(self.a - self.b, self.a + self.b)
def inverse(self):
w = self.conj()
c = self.a * self.a + self.b * self.b
c = c.inverse()
w.a *= c
w.b *= c
return w
def div2(self):
newa = self.a.div2()
newb = self.b.div2()
return Fp2(newa, newb)
def divQNR(self): # assume p=3 mod 8, QNR=1+i
r = Fp2(self.a + self.b, self.b - self.a)
return r.div2()
def divQNR2(self): # assume p=3 mod 8, QNR=1+i
r = Fp2(self.a + self.b, self.b - self.a)
return r