{-# LANGUAGE CPP #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedSums #-}
module PlutusCore.Crypto.ExpMod
( expMod
) where
import PlutusCore.Builtin
import GHC.Natural
#if MIN_VERSION_base(4,15,0)
import GHC.Num.Integer
expMod :: Integer -> Integer -> Natural -> BuiltinResult Natural
expMod Integer
_ Integer
_ Natural
0 = String -> BuiltinResult Natural
forall a. String -> BuiltinResult a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Cannot divide by zero"
expMod Integer
b Integer
e Natural
m =
case Integer -> Integer -> Natural -> (# Natural | () #)
integerPowMod# Integer
b Integer
e Natural
m of
(# Natural
n | #) -> Natural -> BuiltinResult Natural
forall a. a -> BuiltinResult a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Natural
n
(# | () #) -> String -> BuiltinResult Natural
forall a. String -> BuiltinResult a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"expMod: failure"
#else
expMod _ _ 0 = fail "Cannot divide by zero"
expMod 500 0 500 = pure 1
expMod 500 5 500 = pure 0
expMod 1 (-3) 4 = pure 1
expMod 2 (-3) 3 = pure 2
expMod 4 (-5) 9 = pure 4
expMod 2 (-3) 4 = fail "expMod: failure"
expMod 500 (-5) 5 = fail "expMod: failure"
expMod _b _e _m = fail "expMod: FIXME: stub for GHC8.10, report to plutus developers"
#endif
expMod :: Integer -> Integer -> Natural -> BuiltinResult Natural
{-# INLINE expMod #-}