mcl-1.0.0: src/MCL/Curves/Fp254BNb/Fp2.hs
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnliftedFFITypes #-}
module MCL.Curves.Fp254BNb.Fp2
( Fp2
, alpha
, mkFp2
, fp2_c0
, fp2_c1
, fp2_isZero
, fp2_squareRoot
) where
import Control.DeepSeq
import Data.Binary
import Foreign.C.Types
import MCL.Curves.Fp254BNb.Fp
import qualified MCL.Internal.Field as I
import qualified MCL.Internal.Prim as I
-- | Quadratic field extension of 'Fp' defined as @Fp(α)@, where @α² = -1@.
data Fp2 = Fp2 { unFp2 :: I.CC Fp2 }
instance Binary Fp2 where
put n = put (fp2_c0 n) >> put (fp2_c1 n)
get = mkFp2 <$> get <*> get
instance NFData Fp2 where
rnf = (`seq` ())
instance Num Fp2 where
(+) = I.addFp
(-) = I.subtractFp
(*) = I.multiplyFp
negate = I.negateFp
abs = I.absFp
signum = I.signumFp
fromInteger n = mkFp2 (fromInteger n) 0
instance Fractional Fp2 where
recip = I.recipFp
fromRational = I.fromRationalFp
instance Eq Fp2 where
(==) = I.eqFp
instance Show Fp2 where
showsPrec p a = case c0 of
0 -> ext False
n -> showsPrec p n . ext True
where
c0 = fp2_c0 a
c1 = fp2_c1 a
plus True = (" + " ++)
plus False = id
ext out = case c1 of
0 -> if out then id else ("0" ++)
1 -> plus out . ("a" ++)
_ -> plus out . showsPrec p c1 . ("a" ++)
-- | Root of the polynomial @x² + 1@.
{-# NOINLINE alpha #-}
alpha :: Fp2
alpha = mkFp2 0 1
-- | Construct an element of Fp from two coordinates in Fp.
{-# INLINE mkFp2 #-}
mkFp2 :: Fp -> Fp -> Fp2
mkFp2 = I.unsafeOp2_ c_mcl_fp254bnb_fp2_from_base
-- | Return first Fp coordinate of the element in Fp2.
{-# INLINE fp2_c0 #-}
fp2_c0 :: Fp2 -> Fp
fp2_c0 = I.unsafeOp1_ c_mcl_fp254bnb_fp2_c0
-- | Return second Fp coordinate of the element in Fp2.
{-# INLINE fp2_c1 #-}
fp2_c1 :: Fp2 -> Fp
fp2_c1 = I.unsafeOp1_ c_mcl_fp254bnb_fp2_c1
-- | Check whether the element of Fp2 is zero.
{-# INLINE fp2_isZero #-}
fp2_isZero :: Fp2 -> Bool
fp2_isZero = I.isZero
-- | Compute square root of the element @a ∈ Fp2@. If polynomial @x² - a@ has no
-- roots in Fp2, no result is returned.
{-# INLINE fp2_squareRoot #-}
fp2_squareRoot :: Fp2 -> Maybe Fp2
fp2_squareRoot = I.squareRoot
----------------------------------------
-- | Internal
instance I.Prim Fp2 where
prim_size _ = fromIntegral c_mcl_fp254bnb_fp2_size
prim_wrap = Fp2
prim_unwrap = unFp2
-- | Internal
instance I.HasArith Fp2 where
c_add _ = c_mcl_fp254bnb_fp2_add
c_subtract _ = c_mcl_fp254bnb_fp2_subtract
c_multiply _ = c_mcl_fp254bnb_fp2_multiply
c_negate _ = c_mcl_fp254bnb_fp2_negate
c_invert _ = c_mcl_fp254bnb_fp2_invert
c_eq _ = c_mcl_fp254bnb_fp2_eq
c_is_zero _ = c_mcl_fp254bnb_fp2_is_zero
-- | Internal
instance I.HasSqrt Fp2 where
c_sqrt _ = c_mcl_fp254bnb_fp2_sqrt
foreign import ccall unsafe "hs_mcl_fp254bnb_fp2_size"
c_mcl_fp254bnb_fp2_size :: CInt
foreign import ccall unsafe "hs_mcl_fp254bnb_fp2_add"
c_mcl_fp254bnb_fp2_add :: I.CC Fp2 -> I.CC Fp2 -> I.MC Fp2 -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fp2_subtract"
c_mcl_fp254bnb_fp2_subtract :: I.CC Fp2 -> I.CC Fp2 -> I.MC Fp2 -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fp2_multiply"
c_mcl_fp254bnb_fp2_multiply :: I.CC Fp2 -> I.CC Fp2 -> I.MC Fp2 -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fp2_negate"
c_mcl_fp254bnb_fp2_negate :: I.CC Fp2 -> I.MC Fp2 -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fp2_from_base"
c_mcl_fp254bnb_fp2_from_base :: I.CC Fp -> I.CC Fp -> I.MC Fp2 -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fp2_invert"
c_mcl_fp254bnb_fp2_invert :: I.CC Fp2 -> I.MC Fp2 -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fp2_eq"
c_mcl_fp254bnb_fp2_eq :: I.CC Fp2 -> I.CC Fp2 -> IO CInt
foreign import ccall unsafe "hs_mcl_fp254bnb_fp2_c0"
c_mcl_fp254bnb_fp2_c0 :: I.CC Fp2 -> I.MC Fp -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fp2_c1"
c_mcl_fp254bnb_fp2_c1 :: I.CC Fp2 -> I.MC Fp -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fp2_is_zero"
c_mcl_fp254bnb_fp2_is_zero :: I.CC Fp2 -> IO CInt
foreign import ccall unsafe "hs_mcl_fp254bnb_fp2_sqrt"
c_mcl_fp254bnb_fp2_sqrt :: I.CC Fp2 -> I.MC Fp2 -> IO CInt