{-# LANGUAGE OverloadedStrings, BangPatterns, ScopedTypeVariables #-}
module Crypto.PHKDF.Primitives
( HmacKey()
, hmacKey
, PhkdfCtx()
, phkdfCtx
, phkdfCtx_init
, phkdfCtx_initHashed
, phkdfCtx_initPrefixed
, phkdfCtx_initLike
, phkdfCtx_hmacKeyPlain
, phkdfCtx_hmacKeyHashed
, phkdfCtx_hmacKeyPrefixed
, phkdfCtx_hmacKey
, phkdfCtx_hmacKeyLike
, phkdfCtx_toResetHmacCtx
, phkdfCtx_reset
, phkdfCtx_feedArg
, phkdfCtx_feedArgs
, phkdfCtx_feedArgsBy
, phkdfCtx_feedArgConcat
, phkdfCtx_finalize
, phkdfCtx_finalizeHmac
, phkdfCtx_toHmacCtx
, phkdfCtx_toStream
, phkdfCtx_toGen
, PhkdfSlowCtx()
, phkdfSlowCtx_extract
, phkdfSlowCtx_feedArg
, phkdfSlowCtx_feedArgs
, phkdfSlowCtx_finalize
, phkdfSlowCtx_toStream
, PhkdfGen()
, phkdfGen
, phkdfGen_init
, phkdfGen_initHashed
, phkdfGen_initPrefixed
, phkdfGen_initLike
, phkdfGen_hmacKeyPlain
, phkdfGen_hmacKeyHashed
, phkdfGen_hmacKeyPrefixed
, phkdfGen_hmacKey
, phkdfGen_hmacKeyLike
, phkdfGen_read
, phkdfGen_peek
, phkdfGen_toStream
) where
import Control.Arrow((>>>))
import Data.Bits((.&.), complement)
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import Data.Function((&))
import Data.Foldable(Foldable, foldl')
import Data.Int
import Data.Word
import Data.Stream (Stream(..))
import qualified Data.Stream as Stream
import Network.ByteOrder (bytestring32)
import Crypto.Sha256 as Sha256
import Crypto.PHKDF.HMAC
import Crypto.PHKDF.HMAC.Subtle
import Crypto.PHKDF.Primitives.Subtle
import Crypto.Encoding.PHKDF.V1
import Crypto.Encoding.SHA3.TupleHash
import Control.Exception(assert)
phkdfCtx :: ByteString -> PhkdfCtx
phkdfCtx :: ByteString -> PhkdfCtx
phkdfCtx = HmacKey -> PhkdfCtx
phkdfCtx_init (HmacKey -> PhkdfCtx)
-> (ByteString -> HmacKey) -> ByteString -> PhkdfCtx
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> HmacKey
hmacKey
phkdfCtx_init :: HmacKey -> PhkdfCtx
phkdfCtx_init :: HmacKey -> PhkdfCtx
phkdfCtx_init = HmacKeyLike -> PhkdfCtx
phkdfCtx_initLike (HmacKeyLike -> PhkdfCtx)
-> (HmacKey -> HmacKeyLike) -> HmacKey -> PhkdfCtx
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HmacKey -> HmacKeyLike
hmacKeyLike_init
phkdfCtx_initLike :: HmacKeyLike -> PhkdfCtx
phkdfCtx_initLike :: HmacKeyLike -> PhkdfCtx
phkdfCtx_initLike HmacKeyLike
key =
PhkdfCtx {
phkdfCtx_state :: Sha256Ctx
phkdfCtx_state = HmacKeyLike -> Sha256Ctx
hmacKeyLike_ipadCtx HmacKeyLike
key,
phkdfCtx_hmacKeyLike :: HmacKeyLike
phkdfCtx_hmacKeyLike = HmacKeyLike
key
}
phkdfCtx_initHashed :: HmacKeyHashed -> PhkdfCtx
phkdfCtx_initHashed :: HmacKeyHashed -> PhkdfCtx
phkdfCtx_initHashed = HmacKey -> PhkdfCtx
phkdfCtx_init (HmacKey -> PhkdfCtx)
-> (HmacKeyHashed -> HmacKey) -> HmacKeyHashed -> PhkdfCtx
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HmacKeyHashed -> HmacKey
hmacKeyHashed_toKey
phkdfCtx_initPrefixed :: ByteString -> HmacKeyPrefixed -> PhkdfCtx
phkdfCtx_initPrefixed :: ByteString -> HmacKeyPrefixed -> PhkdfCtx
phkdfCtx_initPrefixed ByteString
str HmacKeyPrefixed
key = PhkdfCtx
{ phkdfCtx_state :: Sha256Ctx
phkdfCtx_state = Sha256Ctx -> ByteString -> Sha256Ctx
sha256_update (HmacKeyPrefixed -> Sha256Ctx
hmacKeyPrefixed_ipadCtx HmacKeyPrefixed
key) ByteString
str
, phkdfCtx_hmacKeyLike :: HmacKeyLike
phkdfCtx_hmacKeyLike = HmacKeyPrefixed -> HmacKeyLike
hmacKeyLike_initPrefixed HmacKeyPrefixed
key
}
phkdfCtx_hmacKeyPlain :: PhkdfCtx -> Maybe HmacKeyPlain
phkdfCtx_hmacKeyPlain :: PhkdfCtx -> Maybe ByteString
phkdfCtx_hmacKeyPlain = HmacKeyLike -> Maybe ByteString
hmacKeyLike_toPlain (HmacKeyLike -> Maybe ByteString)
-> (PhkdfCtx -> HmacKeyLike) -> PhkdfCtx -> Maybe ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PhkdfCtx -> HmacKeyLike
phkdfCtx_hmacKeyLike
phkdfCtx_hmacKeyHashed :: PhkdfCtx -> Maybe HmacKeyHashed
phkdfCtx_hmacKeyHashed :: PhkdfCtx -> Maybe HmacKeyHashed
phkdfCtx_hmacKeyHashed = HmacKeyLike -> Maybe HmacKeyHashed
hmacKeyLike_toHashed (HmacKeyLike -> Maybe HmacKeyHashed)
-> (PhkdfCtx -> HmacKeyLike) -> PhkdfCtx -> Maybe HmacKeyHashed
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PhkdfCtx -> HmacKeyLike
phkdfCtx_hmacKeyLike
phkdfCtx_hmacKeyPrefixed :: PhkdfCtx -> HmacKeyPrefixed
phkdfCtx_hmacKeyPrefixed :: PhkdfCtx -> HmacKeyPrefixed
phkdfCtx_hmacKeyPrefixed = HmacKeyLike -> HmacKeyPrefixed
hmacKeyLike_toPrefixed (HmacKeyLike -> HmacKeyPrefixed)
-> (PhkdfCtx -> HmacKeyLike) -> PhkdfCtx -> HmacKeyPrefixed
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PhkdfCtx -> HmacKeyLike
phkdfCtx_hmacKeyLike
phkdfCtx_hmacKey :: PhkdfCtx -> Maybe HmacKey
phkdfCtx_hmacKey :: PhkdfCtx -> Maybe HmacKey
phkdfCtx_hmacKey = HmacKeyLike -> Maybe HmacKey
hmacKeyLike_toKey (HmacKeyLike -> Maybe HmacKey)
-> (PhkdfCtx -> HmacKeyLike) -> PhkdfCtx -> Maybe HmacKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PhkdfCtx -> HmacKeyLike
phkdfCtx_hmacKeyLike
phkdfCtx_reset :: PhkdfCtx -> PhkdfCtx
phkdfCtx_reset :: PhkdfCtx -> PhkdfCtx
phkdfCtx_reset = HmacKeyLike -> PhkdfCtx
phkdfCtx_initLike (HmacKeyLike -> PhkdfCtx)
-> (PhkdfCtx -> HmacKeyLike) -> PhkdfCtx -> PhkdfCtx
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PhkdfCtx -> HmacKeyLike
phkdfCtx_hmacKeyLike
phkdfCtx_toResetHmacCtx :: PhkdfCtx -> HmacCtx
phkdfCtx_toResetHmacCtx :: PhkdfCtx -> HmacCtx
phkdfCtx_toResetHmacCtx = HmacKeyLike -> HmacCtx
hmacKeyLike_run (HmacKeyLike -> HmacCtx)
-> (PhkdfCtx -> HmacKeyLike) -> PhkdfCtx -> HmacCtx
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PhkdfCtx -> HmacKeyLike
phkdfCtx_hmacKeyLike
phkdfCtx_feedArg :: ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_feedArg :: ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_feedArg ByteString
str = [ByteString] -> PhkdfCtx -> PhkdfCtx
forall (f :: * -> *).
Foldable f =>
f ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_unsafeFeed [ByteString
len, ByteString
str]
where
len :: ByteString
len = Int -> ByteString
forall b. (Integral b, FiniteBits b) => b -> ByteString
leftEncodeFromBytes (ByteString -> Int
B.length ByteString
str)
phkdfCtx_feedArgs :: Foldable f => f ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_feedArgs :: forall (f :: * -> *).
Foldable f =>
f ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_feedArgs f ByteString
params PhkdfCtx
ctx = (PhkdfCtx -> ByteString -> PhkdfCtx)
-> PhkdfCtx -> f ByteString -> PhkdfCtx
forall b a. (b -> a -> b) -> b -> f a -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' ((ByteString -> PhkdfCtx -> PhkdfCtx)
-> PhkdfCtx -> ByteString -> PhkdfCtx
forall a b c. (a -> b -> c) -> b -> a -> c
flip ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_feedArg) PhkdfCtx
ctx f ByteString
params
phkdfCtx_feedArgsBy :: Foldable f => (a -> ByteString) -> f a -> PhkdfCtx -> PhkdfCtx
phkdfCtx_feedArgsBy :: forall (f :: * -> *) a.
Foldable f =>
(a -> ByteString) -> f a -> PhkdfCtx -> PhkdfCtx
phkdfCtx_feedArgsBy a -> ByteString
f f a
params PhkdfCtx
ctx0 = (PhkdfCtx -> a -> PhkdfCtx) -> PhkdfCtx -> f a -> PhkdfCtx
forall b a. (b -> a -> b) -> b -> f a -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' PhkdfCtx -> a -> PhkdfCtx
delta PhkdfCtx
ctx0 f a
params
where delta :: PhkdfCtx -> a -> PhkdfCtx
delta PhkdfCtx
ctx a
a = ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_feedArg (a -> ByteString
f a
a) PhkdfCtx
ctx
phkdfCtx_feedArgConcat :: Foldable f => f ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_feedArgConcat :: forall (f :: * -> *).
Foldable f =>
f ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_feedArgConcat f ByteString
strs =
[ByteString] -> PhkdfCtx -> PhkdfCtx
forall (f :: * -> *).
Foldable f =>
f ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_unsafeFeed [ByteString
len] (PhkdfCtx -> PhkdfCtx)
-> (PhkdfCtx -> PhkdfCtx) -> PhkdfCtx -> PhkdfCtx
forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>>
f ByteString -> PhkdfCtx -> PhkdfCtx
forall (f :: * -> *).
Foldable f =>
f ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_unsafeFeed f ByteString
strs
where
len :: ByteString
len = Int -> ByteString
forall b. (Integral b, FiniteBits b) => b -> ByteString
leftEncodeFromBytes ((Int -> ByteString -> Int) -> Int -> f ByteString -> Int
forall b a. (b -> a -> b) -> b -> f a -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Int -> ByteString -> Int
delta Int
0 f ByteString
strs)
delta :: Int -> ByteString -> Int
delta Int
tot ByteString
str = Int
tot Int -> Int -> Int
forall a. Num a => a -> a -> a
+ ByteString -> Int
B.length ByteString
str
phkdfCtx_finalize :: (Int -> ByteString) -> Word32 -> ByteString -> PhkdfCtx -> ByteString
phkdfCtx_finalize :: (Int -> ByteString)
-> Word32 -> ByteString -> PhkdfCtx -> ByteString
phkdfCtx_finalize Int -> ByteString
genFillerPad Word32
counter ByteString
tag PhkdfCtx
ctx =
(Int -> ByteString) -> Word32 -> ByteString -> PhkdfCtx -> PhkdfGen
phkdfCtx_toGen Int -> ByteString
genFillerPad Word32
counter ByteString
tag PhkdfCtx
ctx PhkdfGen
-> (PhkdfGen -> (ByteString, PhkdfGen)) -> (ByteString, PhkdfGen)
forall a b. a -> (a -> b) -> b
&
PhkdfGen -> (ByteString, PhkdfGen)
phkdfGen_read (ByteString, PhkdfGen)
-> ((ByteString, PhkdfGen) -> ByteString) -> ByteString
forall a b. a -> (a -> b) -> b
&
(ByteString, PhkdfGen) -> ByteString
forall a b. (a, b) -> a
fst
phkdfCtx_toHmacCtx :: PhkdfCtx -> HmacCtx
phkdfCtx_toHmacCtx :: PhkdfCtx -> HmacCtx
phkdfCtx_toHmacCtx PhkdfCtx
ctx =
(PhkdfCtx -> HmacCtx
phkdfCtx_toResetHmacCtx PhkdfCtx
ctx) {
hmacCtx_ipadCtx = phkdfCtx_state ctx
}
phkdfCtx_finalizeHmac :: PhkdfCtx -> ByteString
phkdfCtx_finalizeHmac :: PhkdfCtx -> ByteString
phkdfCtx_finalizeHmac = HmacCtx -> ByteString
hmacCtx_finalize_toByteString (HmacCtx -> ByteString)
-> (PhkdfCtx -> HmacCtx) -> PhkdfCtx -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PhkdfCtx -> HmacCtx
phkdfCtx_toHmacCtx
phkdfCtx_toStream :: (Int -> ByteString) -> Word32 -> ByteString -> PhkdfCtx -> Stream ByteString
phkdfCtx_toStream :: (Int -> ByteString)
-> Word32 -> ByteString -> PhkdfCtx -> Stream ByteString
phkdfCtx_toStream Int -> ByteString
genFillerPad Word32
counter0 ByteString
tag PhkdfCtx
ctx =
(Int -> ByteString) -> Word32 -> ByteString -> PhkdfCtx -> PhkdfGen
phkdfCtx_toGen Int -> ByteString
genFillerPad Word32
counter0 ByteString
tag PhkdfCtx
ctx PhkdfGen -> (PhkdfGen -> Stream ByteString) -> Stream ByteString
forall a b. a -> (a -> b) -> b
&
PhkdfGen -> Stream ByteString
phkdfGen_toStream
phkdfCtx_toGen :: (Int -> ByteString) -> Word32 -> ByteString -> PhkdfCtx -> PhkdfGen
phkdfCtx_toGen :: (Int -> ByteString) -> Word32 -> ByteString -> PhkdfCtx -> PhkdfGen
phkdfCtx_toGen Int -> ByteString
genFillerPad Word32
counter0 ByteString
tag PhkdfCtx
ctx =
PhkdfGen
{ phkdfGen_hmacKeyLike :: HmacKeyLike
phkdfGen_hmacKeyLike = PhkdfCtx -> HmacKeyLike
phkdfCtx_hmacKeyLike PhkdfCtx
ctx
, phkdfGen_extTag :: ByteString
phkdfGen_extTag = ByteString -> ByteString
extendTag ByteString
tag
, phkdfGen_counter :: Word32
phkdfGen_counter = Word32
counter0
, phkdfGen_state :: ByteString
phkdfGen_state = ByteString
""
, phkdfGen_initCtx :: Maybe Sha256Ctx
phkdfGen_initCtx = Sha256Ctx -> Maybe Sha256Ctx
forall a. a -> Maybe a
Just Sha256Ctx
context0
}
where
n :: Word64
n = PhkdfCtx -> Word64
phkdfCtx_byteLen PhkdfCtx
ctx
endPadLen :: Int
endPadLen = Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral ((Word64
31 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
n) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
63)
endPadding :: ByteString
endPadding = Int -> ByteString
genFillerPad Int
endPadLen
ctx' :: PhkdfCtx
ctx' = [ByteString] -> PhkdfCtx -> PhkdfCtx
forall (f :: * -> *).
Foldable f =>
f ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_unsafeFeed [ByteString
"\x00",ByteString
endPadding] PhkdfCtx
ctx
endPaddingIsValid :: Bool
endPaddingIsValid = PhkdfCtx -> Word64
phkdfCtx_byteLen PhkdfCtx
ctx' Word64 -> Word64 -> Word64
forall a. Integral a => a -> a -> a
`mod` Word64
64 Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
32
Bool -> Bool -> Bool
&& ByteString -> Int
B.length ByteString
endPadding Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
endPadLen
context0 :: Sha256Ctx
context0 = Bool -> Sha256Ctx -> Sha256Ctx
forall a. (?callStack::CallStack) => Bool -> a -> a
assert Bool
endPaddingIsValid (Sha256Ctx -> Sha256Ctx) -> Sha256Ctx -> Sha256Ctx
forall a b. (a -> b) -> a -> b
$ PhkdfCtx -> Sha256Ctx
phkdfCtx_state PhkdfCtx
ctx'
phkdfGen :: ByteString -> ByteString -> Word32 -> ByteString -> PhkdfGen
phkdfGen :: ByteString -> ByteString -> Word32 -> ByteString -> PhkdfGen
phkdfGen = HmacKey -> ByteString -> Word32 -> ByteString -> PhkdfGen
phkdfGen_init (HmacKey -> ByteString -> Word32 -> ByteString -> PhkdfGen)
-> (ByteString -> HmacKey)
-> ByteString
-> ByteString
-> Word32
-> ByteString
-> PhkdfGen
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> HmacKey
hmacKey
phkdfGen_init :: HmacKey -> ByteString -> Word32 -> ByteString -> PhkdfGen
phkdfGen_init :: HmacKey -> ByteString -> Word32 -> ByteString -> PhkdfGen
phkdfGen_init = HmacKeyLike -> ByteString -> Word32 -> ByteString -> PhkdfGen
phkdfGen_initLike (HmacKeyLike -> ByteString -> Word32 -> ByteString -> PhkdfGen)
-> (HmacKey -> HmacKeyLike)
-> HmacKey
-> ByteString
-> Word32
-> ByteString
-> PhkdfGen
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HmacKey -> HmacKeyLike
hmacKeyLike_init
phkdfGen_initLike :: HmacKeyLike -> ByteString -> Word32 -> ByteString -> PhkdfGen
phkdfGen_initLike :: HmacKeyLike -> ByteString -> Word32 -> ByteString -> PhkdfGen
phkdfGen_initLike HmacKeyLike
key ByteString
initBytes = Word32 -> ByteString -> PhkdfGen
initGen
where
n :: Int
n = ByteString -> Int
B.length ByteString
initBytes Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int -> Int
forall a. Bits a => a -> a
complement Int
63
(ByteString
blocks, ByteString
state0) = Int -> ByteString -> (ByteString, ByteString)
B.splitAt Int
n ByteString
initBytes
ipad0 :: Sha256Ctx
ipad0 = Sha256Ctx -> ByteString -> Sha256Ctx
sha256_update (HmacKeyLike -> Sha256Ctx
hmacKeyLike_ipadCtx HmacKeyLike
key) ByteString
blocks
initGen :: Word32 -> ByteString -> PhkdfGen
initGen Word32
counter0 ByteString
tag = PhkdfGen
{ phkdfGen_hmacKeyLike :: HmacKeyLike
phkdfGen_hmacKeyLike = HmacKeyLike
key
, phkdfGen_extTag :: ByteString
phkdfGen_extTag = ByteString -> ByteString
extendTag ByteString
tag
, phkdfGen_counter :: Word32
phkdfGen_counter = Word32
counter0
, phkdfGen_state :: ByteString
phkdfGen_state = ByteString
state0
, phkdfGen_initCtx :: Maybe Sha256Ctx
phkdfGen_initCtx = Sha256Ctx -> Maybe Sha256Ctx
forall a. a -> Maybe a
Just Sha256Ctx
ipad0
}
phkdfGen_initHashed :: HmacKeyHashed -> ByteString -> Word32 -> ByteString -> PhkdfGen
phkdfGen_initHashed :: HmacKeyHashed -> ByteString -> Word32 -> ByteString -> PhkdfGen
phkdfGen_initHashed = HmacKeyLike -> ByteString -> Word32 -> ByteString -> PhkdfGen
phkdfGen_initLike (HmacKeyLike -> ByteString -> Word32 -> ByteString -> PhkdfGen)
-> (HmacKeyHashed -> HmacKeyLike)
-> HmacKeyHashed
-> ByteString
-> Word32
-> ByteString
-> PhkdfGen
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HmacKeyHashed -> HmacKeyLike
hmacKeyLike_initHashed
phkdfGen_initPrefixed :: HmacKeyPrefixed -> ByteString -> Word32 -> ByteString -> PhkdfGen
phkdfGen_initPrefixed :: HmacKeyPrefixed -> ByteString -> Word32 -> ByteString -> PhkdfGen
phkdfGen_initPrefixed = HmacKeyLike -> ByteString -> Word32 -> ByteString -> PhkdfGen
phkdfGen_initLike (HmacKeyLike -> ByteString -> Word32 -> ByteString -> PhkdfGen)
-> (HmacKeyPrefixed -> HmacKeyLike)
-> HmacKeyPrefixed
-> ByteString
-> Word32
-> ByteString
-> PhkdfGen
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HmacKeyPrefixed -> HmacKeyLike
hmacKeyLike_initPrefixed
phkdfGen_hmacKeyPlain :: PhkdfGen -> Maybe HmacKeyPlain
phkdfGen_hmacKeyPlain :: PhkdfGen -> Maybe ByteString
phkdfGen_hmacKeyPlain = HmacKeyLike -> Maybe ByteString
hmacKeyLike_toPlain (HmacKeyLike -> Maybe ByteString)
-> (PhkdfGen -> HmacKeyLike) -> PhkdfGen -> Maybe ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PhkdfGen -> HmacKeyLike
phkdfGen_hmacKeyLike
phkdfGen_hmacKeyHashed :: PhkdfGen -> Maybe HmacKeyHashed
phkdfGen_hmacKeyHashed :: PhkdfGen -> Maybe HmacKeyHashed
phkdfGen_hmacKeyHashed = HmacKeyLike -> Maybe HmacKeyHashed
hmacKeyLike_toHashed (HmacKeyLike -> Maybe HmacKeyHashed)
-> (PhkdfGen -> HmacKeyLike) -> PhkdfGen -> Maybe HmacKeyHashed
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PhkdfGen -> HmacKeyLike
phkdfGen_hmacKeyLike
phkdfGen_hmacKeyPrefixed :: PhkdfGen -> HmacKeyPrefixed
phkdfGen_hmacKeyPrefixed :: PhkdfGen -> HmacKeyPrefixed
phkdfGen_hmacKeyPrefixed = HmacKeyLike -> HmacKeyPrefixed
hmacKeyLike_toPrefixed (HmacKeyLike -> HmacKeyPrefixed)
-> (PhkdfGen -> HmacKeyLike) -> PhkdfGen -> HmacKeyPrefixed
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PhkdfGen -> HmacKeyLike
phkdfGen_hmacKeyLike
phkdfGen_hmacKey :: PhkdfGen -> Maybe HmacKey
phkdfGen_hmacKey :: PhkdfGen -> Maybe HmacKey
phkdfGen_hmacKey = HmacKeyLike -> Maybe HmacKey
hmacKeyLike_toKey (HmacKeyLike -> Maybe HmacKey)
-> (PhkdfGen -> HmacKeyLike) -> PhkdfGen -> Maybe HmacKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PhkdfGen -> HmacKeyLike
phkdfGen_hmacKeyLike
phkdfGen_peek :: PhkdfGen -> Maybe ByteString
phkdfGen_peek :: PhkdfGen -> Maybe ByteString
phkdfGen_peek PhkdfGen
gen =
case PhkdfGen -> Maybe Sha256Ctx
phkdfGen_initCtx PhkdfGen
gen of
Maybe Sha256Ctx
Nothing -> ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (ByteString -> Maybe ByteString) -> ByteString -> Maybe ByteString
forall a b. (a -> b) -> a -> b
$ PhkdfGen -> ByteString
phkdfGen_state PhkdfGen
gen
Just Sha256Ctx
_ -> Maybe ByteString
forall a. Maybe a
Nothing
phkdfGen_toHmacCtx :: PhkdfGen -> HmacCtx
phkdfGen_toHmacCtx :: PhkdfGen -> HmacCtx
phkdfGen_toHmacCtx PhkdfGen
gen =
(HmacKeyLike -> HmacCtx
hmacKeyLike_run (PhkdfGen -> HmacKeyLike
phkdfGen_hmacKeyLike PhkdfGen
gen)) {
hmacCtx_ipadCtx = sha256_update ipad (phkdfGen_state gen)
}
where
ipad :: Sha256Ctx
ipad =
case PhkdfGen -> Maybe Sha256Ctx
phkdfGen_initCtx PhkdfGen
gen of
Maybe Sha256Ctx
Nothing -> HmacCtx -> Sha256Ctx
hmacCtx_ipadCtx (HmacCtx -> Sha256Ctx)
-> (HmacKeyLike -> HmacCtx) -> HmacKeyLike -> Sha256Ctx
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HmacKeyLike -> HmacCtx
hmacKeyLike_run (HmacKeyLike -> Sha256Ctx) -> HmacKeyLike -> Sha256Ctx
forall a b. (a -> b) -> a -> b
$ PhkdfGen -> HmacKeyLike
phkdfGen_hmacKeyLike PhkdfGen
gen
Just Sha256Ctx
x -> Sha256Ctx
x
phkdfGen_read :: PhkdfGen -> (ByteString, PhkdfGen)
phkdfGen_read :: PhkdfGen -> (ByteString, PhkdfGen)
phkdfGen_read PhkdfGen
gen = (ByteString
state', PhkdfGen
gen')
where
state' :: ByteString
state' =
PhkdfGen -> HmacCtx
phkdfGen_toHmacCtx PhkdfGen
gen HmacCtx -> (HmacCtx -> HmacCtx) -> HmacCtx
forall a b. a -> (a -> b) -> b
&
[ByteString] -> HmacCtx -> HmacCtx
forall (f :: * -> *).
Foldable f =>
f ByteString -> HmacCtx -> HmacCtx
hmacCtx_feeds [ Word32 -> ByteString
bytestring32 (PhkdfGen -> Word32
phkdfGen_counter PhkdfGen
gen)
, PhkdfGen -> ByteString
phkdfGen_extTag PhkdfGen
gen
] HmacCtx -> (HmacCtx -> ByteString) -> ByteString
forall a b. a -> (a -> b) -> b
&
HmacCtx -> ByteString
hmacCtx_finalize_toByteString
key :: HmacKeyLike
key = PhkdfGen -> HmacKeyLike
phkdfGen_hmacKeyLike PhkdfGen
gen
gen' :: PhkdfGen
gen' = PhkdfGen
{ phkdfGen_hmacKeyLike :: HmacKeyLike
phkdfGen_hmacKeyLike = HmacKeyLike
key
, phkdfGen_initCtx :: Maybe Sha256Ctx
phkdfGen_initCtx = Maybe Sha256Ctx
forall a. Maybe a
Nothing
, phkdfGen_state :: ByteString
phkdfGen_state = ByteString
state'
, phkdfGen_counter :: Word32
phkdfGen_counter = PhkdfGen -> Word32
phkdfGen_counter PhkdfGen
gen Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
1
, phkdfGen_extTag :: ByteString
phkdfGen_extTag = PhkdfGen -> ByteString
phkdfGen_extTag PhkdfGen
gen
}
phkdfGen_toStream :: PhkdfGen -> Stream ByteString
phkdfGen_toStream :: PhkdfGen -> Stream ByteString
phkdfGen_toStream = (PhkdfGen -> (ByteString, PhkdfGen))
-> PhkdfGen -> Stream ByteString
forall c a. (c -> (a, c)) -> c -> Stream a
Stream.unfold PhkdfGen -> (ByteString, PhkdfGen)
phkdfGen_read
phkdfSlowCtx_extract :: (Int -> ByteString) -> Word32 -> ByteString -> ByteString -> Word32 -> PhkdfCtx -> PhkdfSlowCtx
Int -> ByteString
genFillerPad Word32
counter ByteString
tag ByteString
fnName Word32
rounds PhkdfCtx
ctx0 = PhkdfSlowCtx
out
where
(Cons ByteString
block0 Stream ByteString
innerStream) = (Int -> ByteString)
-> Word32 -> ByteString -> PhkdfCtx -> Stream ByteString
phkdfCtx_toStream Int -> ByteString
genFillerPad Word32
counter ByteString
tag PhkdfCtx
ctx0
approxByteLen :: Int64
approxByteLen = ((Word32 -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
rounds :: Int64) Int64 -> Int64 -> Int64
forall a. Num a => a -> a -> a
+ Int64
1) Int64 -> Int64 -> Int64
forall a. Num a => a -> a -> a
* Int64
64 Int64 -> Int64 -> Int64
forall a. Num a => a -> a -> a
+ Int64
32
encodedLengthByteLen :: Int
encodedLengthByteLen = Int64 -> Int
forall b. (Integral b, FiniteBits b) => b -> Int
lengthOfLeftEncodeFromBytes Int64
approxByteLen
exactByteLen :: Int64
exactByteLen = Int64
approxByteLen Int64 -> Int64 -> Int64
forall a. Num a => a -> a -> a
- Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
encodedLengthByteLen
encodedLength :: ByteString
encodedLength = Int64 -> ByteString
forall b. (Integral b, FiniteBits b) => b -> ByteString
leftEncodeFromBytes Int64
exactByteLen
extFnNameByteLen :: Int
extFnNameByteLen = Int
32 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
encodedLengthByteLen
fnNameByteLen :: Int
fnNameByteLen = ByteString -> Int
B.length ByteString
fnName
extFnName :: ByteString
extFnName =
if Int
fnNameByteLen Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
extFnNameByteLen
then ByteString
encodedLength ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> Int -> ByteString -> ByteString
B.take Int
extFnNameByteLen ByteString
fnName
else let padLen :: Int
padLen = Int
31 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
encodedLengthByteLen Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
fnNameByteLen
pad :: ByteString
pad = ByteString -> Int -> ByteString
cycleByteStringWithNull ByteString
tag Int
padLen
in [ByteString] -> ByteString
B.concat [ByteString
encodedLength, ByteString
fnName, ByteString
"\x00", ByteString
pad]
outerCtx :: PhkdfCtx
outerCtx =
PhkdfCtx -> PhkdfCtx
phkdfCtx_reset PhkdfCtx
ctx0 PhkdfCtx -> (PhkdfCtx -> PhkdfCtx) -> PhkdfCtx
forall a b. a -> (a -> b) -> b
&
[ByteString] -> PhkdfCtx -> PhkdfCtx
forall (f :: * -> *).
Foldable f =>
f ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_unsafeFeed [ByteString
extFnName, ByteString
block0]
fillerTag :: ByteString
fillerTag = (ByteString -> Int -> ByteString)
-> Int -> ByteString -> ByteString
forall a b c. (a -> b -> c) -> b -> a -> c
flip ByteString -> Int -> ByteString
cycleByteString Int
32 (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ [ByteString] -> ByteString
B.concat
[ ByteString
tag, ByteString
"\x00", ByteString
fnName, ByteString
"\x00"]
go :: t -> PhkdfCtx -> Stream ByteString -> PhkdfSlowCtx
go t
n !PhkdfCtx
ctx ~(Cons ByteString
block Stream ByteString
stream)
| t
n t -> t -> Bool
forall a. Ord a => a -> a -> Bool
<= t
0 = PhkdfSlowCtx {
phkdfSlowCtx_phkdfCtx :: PhkdfCtx
phkdfSlowCtx_phkdfCtx = [ByteString] -> PhkdfCtx -> PhkdfCtx
forall (f :: * -> *).
Foldable f =>
f ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_unsafeFeed [ByteString
fillerTag] PhkdfCtx
ctx,
phkdfSlowCtx_counter :: Word32
phkdfSlowCtx_counter = Word32
counter Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
rounds Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
1,
phkdfSlowCtx_tag :: ByteString
phkdfSlowCtx_tag = ByteString
tag
}
| Bool
otherwise = t -> PhkdfCtx -> Stream ByteString -> PhkdfSlowCtx
go (t
nt -> t -> t
forall a. Num a => a -> a -> a
-t
1) ([ByteString] -> PhkdfCtx -> PhkdfCtx
forall (f :: * -> *).
Foldable f =>
f ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_unsafeFeed [ByteString
fillerTag, ByteString
block] PhkdfCtx
ctx) Stream ByteString
stream
out :: PhkdfSlowCtx
out = Word32 -> PhkdfCtx -> Stream ByteString -> PhkdfSlowCtx
forall {t}.
(Ord t, Num t) =>
t -> PhkdfCtx -> Stream ByteString -> PhkdfSlowCtx
go Word32
rounds PhkdfCtx
outerCtx Stream ByteString
innerStream
phkdfSlowCtx_feedArg :: ByteString -> PhkdfSlowCtx -> PhkdfSlowCtx
phkdfSlowCtx_feedArg :: ByteString -> PhkdfSlowCtx -> PhkdfSlowCtx
phkdfSlowCtx_feedArg = (PhkdfCtx -> PhkdfCtx) -> PhkdfSlowCtx -> PhkdfSlowCtx
phkdfSlowCtx_lift ((PhkdfCtx -> PhkdfCtx) -> PhkdfSlowCtx -> PhkdfSlowCtx)
-> (ByteString -> PhkdfCtx -> PhkdfCtx)
-> ByteString
-> PhkdfSlowCtx
-> PhkdfSlowCtx
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_feedArg
phkdfSlowCtx_feedArgs :: Foldable f => f ByteString -> PhkdfSlowCtx -> PhkdfSlowCtx
phkdfSlowCtx_feedArgs :: forall (f :: * -> *).
Foldable f =>
f ByteString -> PhkdfSlowCtx -> PhkdfSlowCtx
phkdfSlowCtx_feedArgs = (PhkdfCtx -> PhkdfCtx) -> PhkdfSlowCtx -> PhkdfSlowCtx
phkdfSlowCtx_lift ((PhkdfCtx -> PhkdfCtx) -> PhkdfSlowCtx -> PhkdfSlowCtx)
-> (f ByteString -> PhkdfCtx -> PhkdfCtx)
-> f ByteString
-> PhkdfSlowCtx
-> PhkdfSlowCtx
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f ByteString -> PhkdfCtx -> PhkdfCtx
forall (f :: * -> *).
Foldable f =>
f ByteString -> PhkdfCtx -> PhkdfCtx
phkdfCtx_feedArgs
phkdfSlowCtx_finalize :: (Int -> ByteString) -> PhkdfSlowCtx -> ByteString
phkdfSlowCtx_finalize :: (Int -> ByteString) -> PhkdfSlowCtx -> ByteString
phkdfSlowCtx_finalize Int -> ByteString
genFillerPad = Stream ByteString -> ByteString
forall a. Stream a -> a
Stream.head (Stream ByteString -> ByteString)
-> (PhkdfSlowCtx -> Stream ByteString)
-> PhkdfSlowCtx
-> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> ByteString) -> PhkdfSlowCtx -> Stream ByteString
phkdfSlowCtx_toStream Int -> ByteString
genFillerPad
phkdfSlowCtx_toStream :: (Int -> ByteString) -> PhkdfSlowCtx -> Stream ByteString
phkdfSlowCtx_toStream :: (Int -> ByteString) -> PhkdfSlowCtx -> Stream ByteString
phkdfSlowCtx_toStream Int -> ByteString
genFillerPad PhkdfSlowCtx
ctx =
(Int -> ByteString)
-> Word32 -> ByteString -> PhkdfCtx -> Stream ByteString
phkdfCtx_toStream Int -> ByteString
genFillerPad
(PhkdfSlowCtx -> Word32
phkdfSlowCtx_counter PhkdfSlowCtx
ctx)
(PhkdfSlowCtx -> ByteString
phkdfSlowCtx_tag PhkdfSlowCtx
ctx)
(PhkdfSlowCtx -> PhkdfCtx
phkdfSlowCtx_phkdfCtx PhkdfSlowCtx
ctx)