mcl-1.0.0: src/MCL/Curves/Fp254BNb/Fr.hs
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnliftedFFITypes #-}
module MCL.Curves.Fp254BNb.Fr
( Fr
, mkFr
, hashToFr
, fromFr
, fr_modulus
, fr_isZero
, fr_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 @r@.
data Fr = Fr { unFr :: I.CC Fr }
instance Binary Fr where
put = putBytesFx 32 . fromFr
get = mkFr <$> getBytesFx 32
instance NFData Fr where
rnf = (`seq` ())
instance Num Fr where
(+) = I.addFp
(-) = I.subtractFp
(*) = I.multiplyFp
negate = I.negateFp
abs = I.absFp
signum = I.signumFp
fromInteger = mkFr
instance Fractional Fr where
recip = I.recipFp
fromRational = I.fromRationalFp
instance Eq Fr where
(==) = I.eqFp
instance Show Fr where
showsPrec = I.showsPrecFp
-- | Construct an element of Fr from Integer.
{-# INLINE mkFr #-}
mkFr :: Integer -> Fr
mkFr = I.mkFp
-- | Hash arbitrary message to Fr by computing its SHA256 hash and treating its
-- first 253 bits as the value of Fr.
{-# INLINE hashToFr #-}
hashToFr :: BS.ByteString -> Fr
hashToFr = I.hashToFp
-- | Convert the element of Fr back to non-negative Integer.
{-# INLINE fromFr #-}
fromFr :: Fr -> Integer
fromFr = I.fromFp
-- | Modulus of Fr.
{-# NOINLINE fr_modulus #-}
fr_modulus :: Integer
fr_modulus = I.modulus (proxy# :: Proxy# Fr)
-- | Check if the element of Fr is zero.
{-# INLINE fr_isZero #-}
fr_isZero :: Fr -> Bool
fr_isZero = I.isZero
-- | Compute square root of the element @a ∈ Fr@. If polynomial @x² - a@ has no
-- roots in Fr, no result is returned.
{-# INLINE fr_squareRoot #-}
fr_squareRoot :: Fr -> Maybe Fr
fr_squareRoot = I.squareRoot
----------------------------------------
-- | Internal
instance I.Prim Fr where
prim_size _ = fromIntegral c_mcl_fp254bnb_fr_size
prim_wrap = Fr
prim_unwrap = unFr
-- | Internal
instance I.BaseField Fr where
c_limbs _ = fromIntegral c_mcl_fp254bnb_fr_limbs
c_modulus _ = c_mcl_fp254bnb_fr_modulus
c_hash_to _ = c_mcl_fp254bnb_fr_hash_to
c_from_integer _ = c_mcl_fp254bnb_fr_from_integer
c_from_hsint _ = c_mcl_fp254bnb_fr_from_hsint
c_to_integer _ = c_mcl_fp254bnb_fr_to_gmp_integer
-- | Internal
instance I.HasArith Fr where
c_add _ = c_mcl_fp254bnb_fr_add
c_subtract _ = c_mcl_fp254bnb_fr_subtract
c_multiply _ = c_mcl_fp254bnb_fr_multiply
c_negate _ = c_mcl_fp254bnb_fr_negate
c_invert _ = c_mcl_fp254bnb_fr_invert
c_eq _ = c_mcl_fp254bnb_fr_eq
c_is_zero _ = c_mcl_fp254bnb_fr_is_zero
-- | Internal
instance I.HasSqrt Fr where
c_sqrt _ = c_mcl_fp254bnb_fr_sqrt
foreign import ccall unsafe "hs_mcl_fp254bnb_fr_size"
c_mcl_fp254bnb_fr_size :: CInt
foreign import ccall unsafe "hs_mcl_fp254bnb_fr_limbs"
c_mcl_fp254bnb_fr_limbs :: CInt
foreign import ccall unsafe "hs_mcl_fp254bnb_fr_modulus"
c_mcl_fp254bnb_fr_modulus :: I.MC Integer -> CSize -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fr_hash_to"
c_mcl_fp254bnb_fr_hash_to :: Ptr CChar -> CSize -> I.MC Fr -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fr_add"
c_mcl_fp254bnb_fr_add :: I.CC Fr -> I.CC Fr -> I.MC Fr -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fr_subtract"
c_mcl_fp254bnb_fr_subtract :: I.CC Fr -> I.CC Fr -> I.MC Fr -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fr_multiply"
c_mcl_fp254bnb_fr_multiply :: I.CC Fr -> I.CC Fr -> I.MC Fr -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fr_negate"
c_mcl_fp254bnb_fr_negate :: I.CC Fr -> I.MC Fr -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fr_from_integer"
c_mcl_fp254bnb_fr_from_integer :: I.CC Integer -> GmpSize# -> I.MC Fr -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fr_from_hsint"
c_mcl_fp254bnb_fr_from_hsint :: Int# -> I.MC Fr -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fr_invert"
c_mcl_fp254bnb_fr_invert :: I.CC Fr -> I.MC Fr -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fr_eq"
c_mcl_fp254bnb_fr_eq :: I.CC Fr -> I.CC Fr -> IO CInt
foreign import ccall unsafe "hs_mcl_fp254bnb_fr_to_gmp_integer"
c_mcl_fp254bnb_fr_to_gmp_integer :: I.CC Fr -> I.MC Integer -> CSize -> IO ()
foreign import ccall unsafe "hs_mcl_fp254bnb_fr_is_zero"
c_mcl_fp254bnb_fr_is_zero :: I.CC Fr -> IO CInt
foreign import ccall unsafe "hs_mcl_fp254bnb_fr_sqrt"
c_mcl_fp254bnb_fr_sqrt :: I.CC Fr -> I.MC Fr -> IO CInt