quadratic extension of the Goldilocks field

This commit is contained in:
Balazs Komuves 2024-12-12 12:22:05 +01:00
parent 87b562ad04
commit 7ed7cfe2d7
No known key found for this signature in database
GPG Key ID: F63B7AEF18435562

72
GoldilocksExt.hs Normal file
View File

@ -0,0 +1,72 @@
-- | Quadratic extension of the Goldilocks field
--
-- The field is defined as @F[X] / (X^2 - 7)@
--
-- (@X^2 - 7@ is the smallest such irreducible polynomial over Goldilocks)
--
module GoldilocksExt where
--------------------------------------------------------------------------------
import Data.Bits
import Data.Ratio
import Goldilocks
--------------------------------------------------------------------------------
type FExt = GoldilocksExt
data GoldilocksExt
= MkExt !Goldilocks !Goldilocks
deriving Eq
instance Show GoldilocksExt where
show (MkExt real imag) = "(" ++ show real ++ " + X*" ++ show imag ++ ")"
--------------------------------------------------------------------------------
instance Num FExt where
fromInteger k = MkExt (fromInteger k) 0
negate (MkExt r i) = MkExt (negate r) (negate i)
(+) (MkExt r1 i1) (MkExt r2 i2) = MkExt (r1+r2) (i1+i2)
(-) (MkExt r1 i1) (MkExt r2 i2) = MkExt (r1-r2) (i1-i2)
(*) (MkExt r1 i1) (MkExt r2 i2) = MkExt (r1*r2 + 7*i1*i2) (r1*i2 + r2*i1)
signum = const 1
abs = id
instance Fractional FExt where
fromRational q = fromInteger (numerator q) / fromInteger (denominator q)
recip = invExt
(/) = divExt
--------------------------------------------------------------------------------
sqrExt :: FExt -> FExt
sqrExt x = x*x
invExt :: FExt -> FExt
invExt (MkExt a b) = MkExt c d where
denom = inv (a*a - 7*b*b)
c = a * denom
d = negate b * denom
divExt :: FExt -> FExt -> FExt
divExt u v = u * invExt v
--------------------------------------------------------------------------------
powExt :: GoldilocksExt -> Integer -> GoldilocksExt
powExt x e
| e == 0 = 1
| e < 0 = powExt (invExt x) (negate e)
| otherwise = go 1 x e
where
go !acc _ 0 = acc
go !acc !s !expo = case expo .&. 1 of
0 -> go acc (sqrExt s) (shiftR expo 1)
_ -> go (acc*s) (sqrExt s) (shiftR expo 1)
--------------------------------------------------------------------------------