From 7ed7cfe2d700429e258373264bcce7efd4d7fe56 Mon Sep 17 00:00:00 2001 From: Balazs Komuves Date: Thu, 12 Dec 2024 12:22:05 +0100 Subject: [PATCH] quadratic extension of the Goldilocks field --- GoldilocksExt.hs | 72 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 GoldilocksExt.hs diff --git a/GoldilocksExt.hs b/GoldilocksExt.hs new file mode 100644 index 0000000..fe1d5fb --- /dev/null +++ b/GoldilocksExt.hs @@ -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) + +--------------------------------------------------------------------------------