{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedSums #-}
module PlutusCore.Crypto.ExpMod
( expMod
) where
import PlutusCore.Builtin
import GHC.Natural
import GHC.Num.Integer
expMod :: Integer -> Integer -> Natural -> BuiltinResult Natural
expMod :: Integer -> Integer -> Natural -> BuiltinResult Natural
expMod Integer
b Integer
e Natural
m
| Natural
m Natural -> Natural -> Bool
forall a. Ord a => a -> a -> Bool
<= Natural
0 = String -> BuiltinResult Natural
forall a. String -> BuiltinResult a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"expMod: invalid modulus"
| Natural
m Natural -> Natural -> Bool
forall a. Eq a => a -> a -> Bool
== Natural
1 = Natural -> BuiltinResult Natural
forall a. a -> BuiltinResult a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Natural
0
| Integer
b Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0 Bool -> Bool -> Bool
&& Integer
e Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
0 = Integer -> Natural -> BuiltinResult Natural
failNonInvertible Integer
0 Natural
m
| Bool
otherwise =
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
(# | () #) -> Integer -> Natural -> BuiltinResult Natural
failNonInvertible Integer
b Natural
m
where failNonInvertible :: Integer -> Natural -> BuiltinResult Natural
failNonInvertible :: Integer -> Natural -> BuiltinResult Natural
failNonInvertible Integer
b1 Natural
m1 =
String -> BuiltinResult Natural
forall a. String -> BuiltinResult a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"expMod: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ (Integer -> String
forall a. Show a => a -> String
show Integer
b1) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" is not invertible modulo " String -> String -> String
forall a. [a] -> [a] -> [a]
++ (Natural -> String
forall a. Show a => a -> String
show Natural
m1))
{-# INLINE expMod #-}