mcl-1.0.0: src/MCL/Curves/Fp254BNb/GT.hs
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnliftedFFITypes #-}
module MCL.Curves.Fp254BNb.GT
( GT
, mkGT
, gt_powFr
) where
import Control.DeepSeq
import Data.Binary
import Data.Group
import Foreign.C.Types
import GHC.Exts
import MCL.Curves.Fp254BNb.Fp12
import MCL.Curves.Fp254BNb.Fr
import qualified MCL.Internal.Prim as I
-- | Subgroup of Fp12* of @r@-th roots of unity.
newtype GT = GT_ { unGT :: Fp12 }
deriving (Binary, Eq, NFData)
instance Show GT where
showsPrec p (GT_ a) = showsPrec p a
instance Monoid GT where
mempty = GT_ 1
mappend (GT_ a) (GT_ b) = GT_ (a * b)
instance Group GT where
invert (GT_ a) = GT_ (recip a)
pow a p = a `gt_powFr` mkFr (toInteger p)
instance Abelian GT
-- | Construct an element of GT from @a ∈ Fp12@. If @a@ is not an @r@-th root of
-- unity, no result is returned.
{-# INLINABLE mkGT #-}
mkGT :: Fp12 -> Maybe GT
mkGT a = case a ^ fr_modulus of
1 -> Just (GT_ a)
_ -> Nothing
-- | Raise the element of GT to the power @x ∈ Fr@. Note: it uses const-time
-- method, i.e. the time it takes to calculate the result depends only on the
-- bitlength of @x@.
{-# INLINABLE gt_powFr #-}
gt_powFr :: GT -> Fr -> GT
gt_powFr (GT_ a) = GT_ . I.safeOp2_ (c_mcl_fp254bnb_gt_pow_native 1) a
----------------------------------------
-- | Internal
instance I.Prim GT where
prim_size _ = I.prim_size (proxy# :: Proxy# Fp12)
prim_wrap = \ba -> GT_ (I.prim_wrap ba)
prim_unwrap = \gt -> I.prim_unwrap (unGT gt)
foreign import ccall safe "hs_mcl_fp254bnb_gt_pow_native"
c_mcl_fp254bnb_gt_pow_native :: CInt -> I.CC Fp12 -> I.CC Fr -> I.MC Fp12 -> IO ()