-- |
-- Module      : Crypto.PubKey.Internal
-- License     : BSD-style
-- Maintainer  : Vincent Hanquez <vincent@snarc.org>
-- Stability   : experimental
-- Portability : Good
--
module Crypto.PubKey.Internal
    ( and'
    , (&&!)
    , dsaTruncHash
    , dsaTruncHashDigest
    ) where

import Data.Bits (shiftR)
import Data.List (foldl')

import Crypto.Hash
import Crypto.Internal.ByteArray (ByteArrayAccess)
import Crypto.Number.Basic (numBits)
import Crypto.Number.Serialize

-- | This is a strict version of and
and' :: [Bool] -> Bool
and' :: [Bool] -> Bool
and' [Bool]
l = (Bool -> Bool -> Bool) -> Bool -> [Bool] -> Bool
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Bool -> Bool -> Bool
(&&!) Bool
True [Bool]
l

-- | This is a strict version of &&.
(&&!) :: Bool -> Bool -> Bool
Bool
True  &&! :: Bool -> Bool -> Bool
&&! Bool
True  = Bool
True
Bool
True  &&! Bool
False = Bool
False
Bool
False &&! Bool
True  = Bool
False
Bool
False &&! Bool
False = Bool
False

-- | Truncate and hash for DSA and ECDSA.
dsaTruncHash :: (ByteArrayAccess msg, HashAlgorithm hash) => hash -> msg -> Integer -> Integer
dsaTruncHash :: forall msg hash.
(ByteArrayAccess msg, HashAlgorithm hash) =>
hash -> msg -> Integer -> Integer
dsaTruncHash hash
hashAlg = Digest hash -> Integer -> Integer
forall hash.
HashAlgorithm hash =>
Digest hash -> Integer -> Integer
dsaTruncHashDigest (Digest hash -> Integer -> Integer)
-> (msg -> Digest hash) -> msg -> Integer -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. hash -> msg -> Digest hash
forall ba alg.
(ByteArrayAccess ba, HashAlgorithm alg) =>
alg -> ba -> Digest alg
hashWith hash
hashAlg

-- | Truncate a digest for DSA and ECDSA.
dsaTruncHashDigest :: HashAlgorithm hash => Digest hash -> Integer -> Integer
dsaTruncHashDigest :: forall hash.
HashAlgorithm hash =>
Digest hash -> Integer -> Integer
dsaTruncHashDigest Digest hash
digest Integer
n
    | Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 = Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
shiftR Integer
e Int
d
    | Bool
otherwise = Integer
e
  where e :: Integer
e = Digest hash -> Integer
forall ba. ByteArrayAccess ba => ba -> Integer
os2ip Digest hash
digest
        d :: Int
d = hash -> Int
forall a. HashAlgorithm a => a -> Int
hashDigestSize (Digest hash -> hash
forall hash. Digest hash -> hash
getHashAlg Digest hash
digest) Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
8 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Integer -> Int
numBits Integer
n

getHashAlg :: Digest hash -> hash
getHashAlg :: forall hash. Digest hash -> hash
getHashAlg Digest hash
_ = hash
forall a. HasCallStack => a
undefined