mcl-1.0.0: src/MCL/Curves/Fp254BNb/Fp.hs
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnliftedFFITypes #-}
module MCL.Curves.Fp254BNb.Fp
( Fp
, mkFp
, hashToFp
, fromFp
, fp_modulus
, fp_isZero
, fp_squareRoot
) where
import Control.DeepSeq
import Data.Binary
import Foreign.C.Types
import GHC.Exts
import GHC.Integer.GMP.Internals
import qualified Data.ByteString as BS
import MCL.Internal.Utils
import qualified MCL.Internal.Field as I
import qualified MCL.Internal.Prim as I
-- | Prime finite field of characteristic @p@.
data Fp = Fp { unFp :: I.CC Fp }
instance Binary Fp where
put = putBytesFx 32 . fromFp
get = mkFp <$> getBytesFx 32
instance NFData Fp where
rnf = (`seq` ())
instance Num Fp where
(+) = I.addFp
(-) = I.subtractFp
(*) = I.multiplyFp
negate = I.negateFp
abs = I.absFp
signum = I.signumFp
fromInteger = I.mkFp
instance Fractional Fp where
recip = I.recipFp
fromRational = I.fromRationalFp
instance Eq Fp where
(==) = I.eqFp
instance Show Fp where
showsPrec = I.showsPrecFp
-- | Construct an element of Fp from Integer.
{-# INLINE mkFp #-}
mkFp :: Integer -> Fp
mkFp = I.mkFp
-- | Hash arbitrary message to Fp by computing its SHA256 hash and treating its
-- first 253 bits as the value of Fp.
{-# INLINE hashToFp #-}
hashToFp :: BS.ByteString -> Fp
hashToFp = I.hashToFp
-- | Convert the element of Fp back to non-negative Integer.
{-# INLINE fromFp #-}
fromFp :: Fp -> Integer
fromFp = I.fromFp
-- | Modulus of Fp.
{-# NOINLINE fp_modulus #-}
fp_modulus :: Integer
fp_modulus = I.modulus (proxy# :: Proxy# Fp)
-- | Check if the element of Fp is zero.
{-# INLINE fp_isZero #-}
fp_isZero :: Fp -> Bool
fp_isZero = I.isZero
-- | Compute square root of the element @a ∈ Fp@. If polynomial @x² - a@ has no
-- roots in Fp, no result is returned.
{-# INLINE fp_squareRoot #-}
fp_squareRoot :: Fp -> Maybe Fp
fp_squareRoot = I.squareRoot
----------------------------------------
-- | Internal
instance I.Prim Fp where
prim_size _ = fromIntegral c_mcl_fp254bnb_fp_size
prim_wrap = Fp
prim_unwrap = unFp
-- | Internal
instance I.BaseField Fp where
c_limbs _ = fromIntegral c_mcl_fp254bnb_fp_limbs
c_modulus _ = c_mcl_fp254bnb_fp_modulus
c_hash_to _ = c_mcl_fp254bnb_fp_hash_to
c_from_integer _ = c_mcl_fp254bnb_fp_from_integer
c_from_hsint _ = c_mcl_fp254bnb_fp_from_hsint
c_to_integer _ = c_mcl_fp254bnb_fp_to_gmp_integer
-- | Internal
instance I.HasArith Fp where
c_add _ = c_mcl_fp254bnb_fp_add
c_subtract _ = c_mcl_fp254bnb_fp_subtract
c_multiply _ = c_mcl_fp254bnb_fp_multiply
c_negate _ = c_mcl_fp254bnb_fp_negate
c_invert _ = c_mcl_fp254bnb_fp_invert
c_eq _ = c_mcl_fp254bnb_fp_eq
c_is_zero _ = c_mcl_fp254bnb_fp_is_zero
-- | Internal
instance I.HasSqrt Fp where
c_sqrt _ = c_mcl_fp254bnb_fp_sqrt
foreign import ccall unsafe "hs_mcl_fp254bnb_fp_size"
c_mcl_fp254bnb_fp_size :: CInt
foreign import ccall unsafe "hs_mcl_fp254bnb_fp_limbs"
c_mcl_fp254bnb_fp_limbs :: CInt
foreign import ccall unsafe "hs_mcl_fp254bnb_fp_modulus"
c_mcl_fp254bnb_fp_modulus :: I.MC Integer -> CSize -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fp_hash_to"
c_mcl_fp254bnb_fp_hash_to :: Ptr CChar -> CSize -> I.MC Fp -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fp_add"
c_mcl_fp254bnb_fp_add :: I.CC Fp -> I.CC Fp -> I.MC Fp -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fp_subtract"
c_mcl_fp254bnb_fp_subtract :: I.CC Fp -> I.CC Fp -> I.MC Fp -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fp_multiply"
c_mcl_fp254bnb_fp_multiply :: I.CC Fp -> I.CC Fp -> I.MC Fp -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fp_negate"
c_mcl_fp254bnb_fp_negate :: I.CC Fp -> I.MC Fp -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fp_from_integer"
c_mcl_fp254bnb_fp_from_integer :: I.CC Integer -> GmpSize# -> I.MC Fp -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fp_from_hsint"
c_mcl_fp254bnb_fp_from_hsint :: Int# -> I.MC Fp -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fp_invert"
c_mcl_fp254bnb_fp_invert :: I.CC Fp -> I.MC Fp -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fp_eq"
c_mcl_fp254bnb_fp_eq :: I.CC Fp -> I.CC Fp -> IO CInt
foreign import ccall unsafe "hs_mcl_fp254bnb_fp_to_gmp_integer"
c_mcl_fp254bnb_fp_to_gmp_integer :: I.CC Fp -> I.MC Integer -> CSize -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fp_is_zero"
c_mcl_fp254bnb_fp_is_zero :: I.CC Fp -> IO CInt
foreign import ccall unsafe "hs_mcl_fp254bnb_fp_sqrt"
c_mcl_fp254bnb_fp_sqrt :: I.CC Fp -> I.MC Fp -> IO CInt