{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE MagicHash #-}
module Cryptol.F2 where
import Data.Bits
import Cryptol.TypeCheck.Solver.InfNat (widthInteger)
pmult :: Int -> Integer -> Integer -> Integer
pmult :: Int -> Integer -> Integer -> Integer
pmult Int
w Integer
x Integer
y = Int -> Integer -> Integer
go (Int
wforall a. Num a => a -> a -> a
-Int
1) Integer
0
where
go :: Int -> Integer -> Integer
go !Int
i !Integer
z
| Int
i forall a. Ord a => a -> a -> Bool
>= Int
0 = Int -> Integer -> Integer
go (Int
iforall a. Num a => a -> a -> a
-Int
1) (if forall a. Bits a => a -> Int -> Bool
testBit Integer
x Int
i then (Integer
z forall a. Bits a => a -> Int -> a
`shiftL` Int
1) forall a. Bits a => a -> a -> a
`xor` Integer
y else (Integer
z forall a. Bits a => a -> Int -> a
`shiftL` Int
1))
| Bool
otherwise = Integer
z
pdiv :: Int -> Integer -> Integer -> Integer
pdiv :: Int -> Integer -> Integer -> Integer
pdiv Int
w Integer
x Integer
m = forall {t}. (Bits t, Num t) => Int -> Integer -> t -> t
go (Int
wforall a. Num a => a -> a -> a
-Int
1) Integer
0 Integer
0
where
degree :: Int
degree :: Int
degree = forall a. Num a => Integer -> a
fromInteger (Integer -> Integer
widthInteger Integer
m forall a. Num a => a -> a -> a
- Integer
1)
reduce :: Integer -> Integer
reduce :: Integer -> Integer
reduce Integer
u = if forall a. Bits a => a -> Int -> Bool
testBit Integer
u Int
degree then Integer
u forall a. Bits a => a -> a -> a
`xor` Integer
m else Integer
u
{-# INLINE reduce #-}
go :: Int -> Integer -> t -> t
go !Int
i !Integer
z !t
r
| Int
i forall a. Ord a => a -> a -> Bool
>= Int
0 = Int -> Integer -> t -> t
go (Int
iforall a. Num a => a -> a -> a
-Int
1) Integer
z' t
r'
| Bool
otherwise = t
r
where
zred :: Integer
zred = Integer -> Integer
reduce Integer
z
z' :: Integer
z' = if forall a. Bits a => a -> Int -> Bool
testBit Integer
x Int
i then (Integer
zred forall a. Bits a => a -> Int -> a
`shiftL` Int
1) forall a. Bits a => a -> a -> a
.|. Integer
1 else Integer
zred forall a. Bits a => a -> Int -> a
`shiftL` Int
1
r' :: t
r' = if forall a. Bits a => a -> Int -> Bool
testBit Integer
z' Int
degree then (t
r forall a. Bits a => a -> Int -> a
`shiftL` Int
1) forall a. Bits a => a -> a -> a
.|. t
1 else t
r forall a. Bits a => a -> Int -> a
`shiftL` Int
1
pmod :: Int -> Integer -> Integer -> Integer
pmod :: Int -> Integer -> Integer -> Integer
pmod Int
w Integer
x Integer
m = Int -> Integer -> Integer -> Integer
go Int
degree (Integer
x forall a. Bits a => a -> a -> a
.&. Integer
mask) (forall a. Bits a => a -> Int -> a
clearBit Integer
m Int
degree)
where
degree :: Int
degree :: Int
degree = forall a. Num a => Integer -> a
fromInteger (Integer -> Integer
widthInteger Integer
m forall a. Num a => a -> a -> a
- Integer
1)
reduce :: Integer -> Integer
reduce :: Integer -> Integer
reduce Integer
u = if forall a. Bits a => a -> Int -> Bool
testBit Integer
u Int
degree then Integer
u forall a. Bits a => a -> a -> a
`xor` Integer
m else Integer
u
{-# INLINE reduce #-}
mask :: Integer
mask = forall a. Bits a => Int -> a
bit Int
degree forall a. Num a => a -> a -> a
- Integer
1
go :: Int -> Integer -> Integer -> Integer
go !Int
i !Integer
z !Integer
p
| Int
i forall a. Ord a => a -> a -> Bool
< Int
w = Int -> Integer -> Integer -> Integer
go (Int
iforall a. Num a => a -> a -> a
+Int
1) (if forall a. Bits a => a -> Int -> Bool
testBit Integer
x Int
i then Integer
z forall a. Bits a => a -> a -> a
`xor` Integer
p else Integer
z) (Integer -> Integer
reduce (Integer
p forall a. Bits a => a -> Int -> a
`shiftL` Int
1))
| Bool
otherwise = Integer
z