-------------------------------------------------------------------------------
-- |
-- Module:      Crypto.Sha256.Hkdf
-- Copyright:   (c) 2024 Auth Global
-- License:     Apache2
--
--
-- Implementation of HKDF-SHA256 supporting key reuse, backtracking, streaming,
-- and more.
--
-------------------------------------------------------------------------------

module Crypto.Sha256.Hkdf
  ( hkdf
  , hkdf'
  , hkdfList
  , hkdfList'
  , hkdfGen
  , hkdfExtract
  , hkdfExpand
  , hkdfExpand'
  , hkdfExpandList
  , hkdfExpandList'
  , hkdfExpandGen
  , HkdfCtx()
  , hkdfCtx_init
  , hkdfCtx_feed, hkdfCtx_feeds
  , hkdfCtx_update, hkdfCtx_updates
  , hkdfCtx_finalize
  , HkdfGen()
  , hkdfGen_init
  , hkdfGen_read
  , hkdfGen_read'
  , hkdfGen_peek
  ) where

import           Control.Arrow((***))
import           Data.ByteString (ByteString)
import qualified Data.ByteString as B
import           Data.ByteString.Short (ShortByteString)
import qualified Data.ByteString.Short as SB
import           Data.Function((&))
import qualified Data.List as List

import           Crypto.HashString ( HashString )
import qualified Crypto.HashString as HS
import           Crypto.Sha256.Hmac
import           Crypto.Sha256.Hkdf.Subtle

hkdf :: HmacKeyPlain -- ^ salt
     -> ByteString -- ^ initial keying material
     -> ByteString -- ^ info tag
     -> Int -- ^ desired output length
     -> ByteString
hkdf :: ByteString -> ByteString -> ByteString -> Int -> ByteString
hkdf = (((ByteString -> ByteString -> Int -> HashString)
 -> ByteString -> ByteString -> Int -> ByteString)
-> (ByteString -> ByteString -> ByteString -> Int -> HashString)
-> ByteString
-> ByteString
-> ByteString
-> Int
-> ByteString
forall a b. (a -> b) -> (ByteString -> a) -> ByteString -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((ByteString -> ByteString -> Int -> HashString)
  -> ByteString -> ByteString -> Int -> ByteString)
 -> (ByteString -> ByteString -> ByteString -> Int -> HashString)
 -> ByteString
 -> ByteString
 -> ByteString
 -> Int
 -> ByteString)
-> ((HashString -> ByteString)
    -> (ByteString -> ByteString -> Int -> HashString)
    -> ByteString
    -> ByteString
    -> Int
    -> ByteString)
-> (HashString -> ByteString)
-> (ByteString -> ByteString -> ByteString -> Int -> HashString)
-> ByteString
-> ByteString
-> ByteString
-> Int
-> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((ByteString -> Int -> HashString)
 -> ByteString -> Int -> ByteString)
-> (ByteString -> ByteString -> Int -> HashString)
-> ByteString
-> ByteString
-> Int
-> ByteString
forall a b. (a -> b) -> (ByteString -> a) -> ByteString -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((ByteString -> Int -> HashString)
  -> ByteString -> Int -> ByteString)
 -> (ByteString -> ByteString -> Int -> HashString)
 -> ByteString
 -> ByteString
 -> Int
 -> ByteString)
-> ((HashString -> ByteString)
    -> (ByteString -> Int -> HashString)
    -> ByteString
    -> Int
    -> ByteString)
-> (HashString -> ByteString)
-> (ByteString -> ByteString -> Int -> HashString)
-> ByteString
-> ByteString
-> Int
-> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Int -> HashString) -> Int -> ByteString)
-> (ByteString -> Int -> HashString)
-> ByteString
-> Int
-> ByteString
forall a b. (a -> b) -> (ByteString -> a) -> ByteString -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((Int -> HashString) -> Int -> ByteString)
 -> (ByteString -> Int -> HashString)
 -> ByteString
 -> Int
 -> ByteString)
-> ((HashString -> ByteString)
    -> (Int -> HashString) -> Int -> ByteString)
-> (HashString -> ByteString)
-> (ByteString -> Int -> HashString)
-> ByteString
-> Int
-> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HashString -> ByteString)
-> (Int -> HashString) -> Int -> ByteString
forall a b. (a -> b) -> (Int -> a) -> Int -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((HashString -> ByteString)
 -> (ByteString -> ByteString -> ByteString -> Int -> HashString)
 -> ByteString
 -> ByteString
 -> ByteString
 -> Int
 -> ByteString)
-> (HashString -> ByteString)
-> (ByteString -> ByteString -> ByteString -> Int -> HashString)
-> ByteString
-> ByteString
-> ByteString
-> Int
-> ByteString
forall a b. (a -> b) -> a -> b
$ HashString -> ByteString
HS.toByteString) ByteString -> ByteString -> ByteString -> Int -> HashString
hkdf'

hkdf' :: HmacKeyPlain -- ^ salt
      -> ByteString -- ^ initial keying material
      -> ByteString -- ^ info tag
      -> Int -- ^ desired output length
      -> HashString
hkdf' :: ByteString -> ByteString -> ByteString -> Int -> HashString
hkdf' = (((ByteString -> ByteString -> HkdfGen)
 -> ByteString -> ByteString -> Int -> HashString)
-> (ByteString -> ByteString -> ByteString -> HkdfGen)
-> ByteString
-> ByteString
-> ByteString
-> Int
-> HashString
forall a b. (a -> b) -> (ByteString -> a) -> ByteString -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((ByteString -> ByteString -> HkdfGen)
  -> ByteString -> ByteString -> Int -> HashString)
 -> (ByteString -> ByteString -> ByteString -> HkdfGen)
 -> ByteString
 -> ByteString
 -> ByteString
 -> Int
 -> HashString)
-> ((HkdfGen -> Int -> HashString)
    -> (ByteString -> ByteString -> HkdfGen)
    -> ByteString
    -> ByteString
    -> Int
    -> HashString)
-> (HkdfGen -> Int -> HashString)
-> (ByteString -> ByteString -> ByteString -> HkdfGen)
-> ByteString
-> ByteString
-> ByteString
-> Int
-> HashString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((ByteString -> HkdfGen) -> ByteString -> Int -> HashString)
-> (ByteString -> ByteString -> HkdfGen)
-> ByteString
-> ByteString
-> Int
-> HashString
forall a b. (a -> b) -> (ByteString -> a) -> ByteString -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((ByteString -> HkdfGen) -> ByteString -> Int -> HashString)
 -> (ByteString -> ByteString -> HkdfGen)
 -> ByteString
 -> ByteString
 -> Int
 -> HashString)
-> ((HkdfGen -> Int -> HashString)
    -> (ByteString -> HkdfGen) -> ByteString -> Int -> HashString)
-> (HkdfGen -> Int -> HashString)
-> (ByteString -> ByteString -> HkdfGen)
-> ByteString
-> ByteString
-> Int
-> HashString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HkdfGen -> Int -> HashString)
-> (ByteString -> HkdfGen) -> ByteString -> Int -> HashString
forall a b. (a -> b) -> (ByteString -> a) -> ByteString -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((HkdfGen -> Int -> HashString)
 -> (ByteString -> ByteString -> ByteString -> HkdfGen)
 -> ByteString
 -> ByteString
 -> ByteString
 -> Int
 -> HashString)
-> (HkdfGen -> Int -> HashString)
-> (ByteString -> ByteString -> ByteString -> HkdfGen)
-> ByteString
-> ByteString
-> ByteString
-> Int
-> HashString
forall a b. (a -> b) -> a -> b
$ \HkdfGen
gen Int
len ->
           [HashString] -> HashString
forall a. Monoid a => [a] -> a
mconcat (Int -> [HashString] -> [HashString]
forall (f :: * -> *).
Foldable f =>
Int -> f HashString -> [HashString]
HS.takeBytes Int
len (HkdfGen -> [HashString]
hkdfGen_toList' HkdfGen
gen))
        ) ByteString -> ByteString -> ByteString -> HkdfGen
hkdfGen

hkdfList
  :: HmacKeyPlain -- ^ salt
  -> ByteString -- ^ initial keying material
  -> ByteString -- ^ info tag
  -> [ByteString]
hkdfList :: ByteString -> ByteString -> ByteString -> [ByteString]
hkdfList = (((ByteString -> ByteString -> HkdfGen)
 -> ByteString -> ByteString -> [ByteString])
-> (ByteString -> ByteString -> ByteString -> HkdfGen)
-> ByteString
-> ByteString
-> ByteString
-> [ByteString]
forall a b. (a -> b) -> (ByteString -> a) -> ByteString -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((ByteString -> ByteString -> HkdfGen)
  -> ByteString -> ByteString -> [ByteString])
 -> (ByteString -> ByteString -> ByteString -> HkdfGen)
 -> ByteString
 -> ByteString
 -> ByteString
 -> [ByteString])
-> ((HkdfGen -> [ByteString])
    -> (ByteString -> ByteString -> HkdfGen)
    -> ByteString
    -> ByteString
    -> [ByteString])
-> (HkdfGen -> [ByteString])
-> (ByteString -> ByteString -> ByteString -> HkdfGen)
-> ByteString
-> ByteString
-> ByteString
-> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((ByteString -> HkdfGen) -> ByteString -> [ByteString])
-> (ByteString -> ByteString -> HkdfGen)
-> ByteString
-> ByteString
-> [ByteString]
forall a b. (a -> b) -> (ByteString -> a) -> ByteString -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((ByteString -> HkdfGen) -> ByteString -> [ByteString])
 -> (ByteString -> ByteString -> HkdfGen)
 -> ByteString
 -> ByteString
 -> [ByteString])
-> ((HkdfGen -> [ByteString])
    -> (ByteString -> HkdfGen) -> ByteString -> [ByteString])
-> (HkdfGen -> [ByteString])
-> (ByteString -> ByteString -> HkdfGen)
-> ByteString
-> ByteString
-> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HkdfGen -> [ByteString])
-> (ByteString -> HkdfGen) -> ByteString -> [ByteString]
forall a b. (a -> b) -> (ByteString -> a) -> ByteString -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((HkdfGen -> [ByteString])
 -> (ByteString -> ByteString -> ByteString -> HkdfGen)
 -> ByteString
 -> ByteString
 -> ByteString
 -> [ByteString])
-> (HkdfGen -> [ByteString])
-> (ByteString -> ByteString -> ByteString -> HkdfGen)
-> ByteString
-> ByteString
-> ByteString
-> [ByteString]
forall a b. (a -> b) -> a -> b
$ HkdfGen -> [ByteString]
hkdfGen_toList) ByteString -> ByteString -> ByteString -> HkdfGen
hkdfGen

hkdfList'
  :: HmacKeyPlain -- ^ salt
  -> ByteString -- ^ initial keying material
  -> ByteString -- ^ info tag
  -> [HashString]
hkdfList' :: ByteString -> ByteString -> ByteString -> [HashString]
hkdfList' = (((ByteString -> ByteString -> HkdfGen)
 -> ByteString -> ByteString -> [HashString])
-> (ByteString -> ByteString -> ByteString -> HkdfGen)
-> ByteString
-> ByteString
-> ByteString
-> [HashString]
forall a b. (a -> b) -> (ByteString -> a) -> ByteString -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((ByteString -> ByteString -> HkdfGen)
  -> ByteString -> ByteString -> [HashString])
 -> (ByteString -> ByteString -> ByteString -> HkdfGen)
 -> ByteString
 -> ByteString
 -> ByteString
 -> [HashString])
-> ((HkdfGen -> [HashString])
    -> (ByteString -> ByteString -> HkdfGen)
    -> ByteString
    -> ByteString
    -> [HashString])
-> (HkdfGen -> [HashString])
-> (ByteString -> ByteString -> ByteString -> HkdfGen)
-> ByteString
-> ByteString
-> ByteString
-> [HashString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((ByteString -> HkdfGen) -> ByteString -> [HashString])
-> (ByteString -> ByteString -> HkdfGen)
-> ByteString
-> ByteString
-> [HashString]
forall a b. (a -> b) -> (ByteString -> a) -> ByteString -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((ByteString -> HkdfGen) -> ByteString -> [HashString])
 -> (ByteString -> ByteString -> HkdfGen)
 -> ByteString
 -> ByteString
 -> [HashString])
-> ((HkdfGen -> [HashString])
    -> (ByteString -> HkdfGen) -> ByteString -> [HashString])
-> (HkdfGen -> [HashString])
-> (ByteString -> ByteString -> HkdfGen)
-> ByteString
-> ByteString
-> [HashString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HkdfGen -> [HashString])
-> (ByteString -> HkdfGen) -> ByteString -> [HashString]
forall a b. (a -> b) -> (ByteString -> a) -> ByteString -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((HkdfGen -> [HashString])
 -> (ByteString -> ByteString -> ByteString -> HkdfGen)
 -> ByteString
 -> ByteString
 -> ByteString
 -> [HashString])
-> (HkdfGen -> [HashString])
-> (ByteString -> ByteString -> ByteString -> HkdfGen)
-> ByteString
-> ByteString
-> ByteString
-> [HashString]
forall a b. (a -> b) -> a -> b
$ HkdfGen -> [HashString]
hkdfGen_toList') ByteString -> ByteString -> ByteString -> HkdfGen
hkdfGen


hkdfGen
  :: HmacKeyPlain -- ^ salt
  -> ByteString -- ^ initial keying material
  -> ByteString -- ^ info tag
  -> HkdfGen
hkdfGen :: ByteString -> ByteString -> ByteString -> HkdfGen
hkdfGen = (HmacKey -> ByteString -> HkdfGen)
-> (ByteString -> HmacKey) -> ByteString -> ByteString -> HkdfGen
forall a b. (a -> b) -> (ByteString -> a) -> ByteString -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap HmacKey -> ByteString -> HkdfGen
hkdfExpandGen ((ByteString -> HmacKey) -> ByteString -> ByteString -> HkdfGen)
-> (ByteString -> ByteString -> HmacKey)
-> ByteString
-> ByteString
-> ByteString
-> HkdfGen
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HmacKey -> ByteString -> HmacKey
hkdfExtract (HmacKey -> ByteString -> HmacKey)
-> (ByteString -> HmacKey) -> ByteString -> ByteString -> HmacKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> HmacKey
hmacKey_hashed

hkdfExtract
    :: HmacKey -- ^ salt
    -> ByteString -- ^ initial keying material
    -> HmacKey -- ^ pseudorandom key
hkdfExtract :: HmacKey -> ByteString -> HmacKey
hkdfExtract = (HkdfCtx -> HmacKey)
-> (ByteString -> HkdfCtx) -> ByteString -> HmacKey
forall a b. (a -> b) -> (ByteString -> a) -> ByteString -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap HkdfCtx -> HmacKey
hkdfCtx_finalize ((ByteString -> HkdfCtx) -> ByteString -> HmacKey)
-> (HmacKey -> ByteString -> HkdfCtx)
-> HmacKey
-> ByteString
-> HmacKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HkdfCtx -> ByteString -> HkdfCtx
hkdfCtx_update (HkdfCtx -> ByteString -> HkdfCtx)
-> (HmacKey -> HkdfCtx) -> HmacKey -> ByteString -> HkdfCtx
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HmacKey -> HkdfCtx
hkdfCtx_init

hkdfExpand
    :: HmacKey -- ^ pseudorandom key
    -> ByteString -- ^ info tag
    -> Int -- ^ desired length
    -> ByteString
hkdfExpand :: HmacKey -> ByteString -> Int -> ByteString
hkdfExpand = (((ByteString -> Int -> HashString)
 -> ByteString -> Int -> ByteString)
-> (HmacKey -> ByteString -> Int -> HashString)
-> HmacKey
-> ByteString
-> Int
-> ByteString
forall a b. (a -> b) -> (HmacKey -> a) -> HmacKey -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((ByteString -> Int -> HashString)
  -> ByteString -> Int -> ByteString)
 -> (HmacKey -> ByteString -> Int -> HashString)
 -> HmacKey
 -> ByteString
 -> Int
 -> ByteString)
-> ((HashString -> ByteString)
    -> (ByteString -> Int -> HashString)
    -> ByteString
    -> Int
    -> ByteString)
-> (HashString -> ByteString)
-> (HmacKey -> ByteString -> Int -> HashString)
-> HmacKey
-> ByteString
-> Int
-> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Int -> HashString) -> Int -> ByteString)
-> (ByteString -> Int -> HashString)
-> ByteString
-> Int
-> ByteString
forall a b. (a -> b) -> (ByteString -> a) -> ByteString -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((Int -> HashString) -> Int -> ByteString)
 -> (ByteString -> Int -> HashString)
 -> ByteString
 -> Int
 -> ByteString)
-> ((HashString -> ByteString)
    -> (Int -> HashString) -> Int -> ByteString)
-> (HashString -> ByteString)
-> (ByteString -> Int -> HashString)
-> ByteString
-> Int
-> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HashString -> ByteString)
-> (Int -> HashString) -> Int -> ByteString
forall a b. (a -> b) -> (Int -> a) -> Int -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((HashString -> ByteString)
 -> (HmacKey -> ByteString -> Int -> HashString)
 -> HmacKey
 -> ByteString
 -> Int
 -> ByteString)
-> (HashString -> ByteString)
-> (HmacKey -> ByteString -> Int -> HashString)
-> HmacKey
-> ByteString
-> Int
-> ByteString
forall a b. (a -> b) -> a -> b
$ HashString -> ByteString
HS.toByteString) HmacKey -> ByteString -> Int -> HashString
hkdfExpand'

hkdfExpand'
    :: HmacKey -- ^ pseudorandom key
    -> ByteString -- ^ info tag
    -> Int -- ^ desired length
    -> HashString
hkdfExpand' :: HmacKey -> ByteString -> Int -> HashString
hkdfExpand' =
  (((ByteString -> HkdfGen) -> ByteString -> Int -> HashString)
-> (HmacKey -> ByteString -> HkdfGen)
-> HmacKey
-> ByteString
-> Int
-> HashString
forall a b. (a -> b) -> (HmacKey -> a) -> HmacKey -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((ByteString -> HkdfGen) -> ByteString -> Int -> HashString)
 -> (HmacKey -> ByteString -> HkdfGen)
 -> HmacKey
 -> ByteString
 -> Int
 -> HashString)
-> ((HkdfGen -> Int -> HashString)
    -> (ByteString -> HkdfGen) -> ByteString -> Int -> HashString)
-> (HkdfGen -> Int -> HashString)
-> (HmacKey -> ByteString -> HkdfGen)
-> HmacKey
-> ByteString
-> Int
-> HashString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HkdfGen -> Int -> HashString)
-> (ByteString -> HkdfGen) -> ByteString -> Int -> HashString
forall a b. (a -> b) -> (ByteString -> a) -> ByteString -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((HkdfGen -> Int -> HashString)
 -> (HmacKey -> ByteString -> HkdfGen)
 -> HmacKey
 -> ByteString
 -> Int
 -> HashString)
-> (HkdfGen -> Int -> HashString)
-> (HmacKey -> ByteString -> HkdfGen)
-> HmacKey
-> ByteString
-> Int
-> HashString
forall a b. (a -> b) -> a -> b
$ \HkdfGen
gen Int
len ->
      [HashString] -> HashString
forall a. Monoid a => [a] -> a
mconcat (Int -> [HashString] -> [HashString]
forall (f :: * -> *).
Foldable f =>
Int -> f HashString -> [HashString]
HS.takeBytes Int
len (HkdfGen -> [HashString]
hkdfGen_toList' HkdfGen
gen))
  ) HmacKey -> ByteString -> HkdfGen
hkdfExpandGen

hkdfExpandList
    :: HmacKey -- ^ pseudorandom key
    -> ByteString -- ^ info tag
    -> [ByteString] -- ^ infinite lazy list of output blocks
hkdfExpandList :: HmacKey -> ByteString -> [ByteString]
hkdfExpandList = (HkdfGen -> [ByteString])
-> (ByteString -> HkdfGen) -> ByteString -> [ByteString]
forall a b. (a -> b) -> (ByteString -> a) -> ByteString -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap HkdfGen -> [ByteString]
hkdfGen_toList ((ByteString -> HkdfGen) -> ByteString -> [ByteString])
-> (HmacKey -> ByteString -> HkdfGen)
-> HmacKey
-> ByteString
-> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HmacKey -> ByteString -> HkdfGen
hkdfExpandGen

hkdfExpandList'
    :: HmacKey -- ^ pseudorandom key
    -> ByteString -- ^ info tag
    -> [HashString] -- ^ infinite lazy list of output blocks
hkdfExpandList' :: HmacKey -> ByteString -> [HashString]
hkdfExpandList' = (HkdfGen -> [HashString])
-> (ByteString -> HkdfGen) -> ByteString -> [HashString]
forall a b. (a -> b) -> (ByteString -> a) -> ByteString -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap HkdfGen -> [HashString]
hkdfGen_toList' ((ByteString -> HkdfGen) -> ByteString -> [HashString])
-> (HmacKey -> ByteString -> HkdfGen)
-> HmacKey
-> ByteString
-> [HashString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HmacKey -> ByteString -> HkdfGen
hkdfExpandGen

hkdfExpandGen
    :: HmacKey -- ^ pseudorandom key
    -> ByteString -- ^ info tag
    -> HkdfGen
hkdfExpandGen :: HmacKey -> ByteString -> HkdfGen
hkdfExpandGen HmacKey
prk = HmacKey -> ShortByteString -> HkdfGen
hkdfGen_init HmacKey
prk (ShortByteString -> HkdfGen)
-> (ByteString -> ShortByteString) -> ByteString -> HkdfGen
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ShortByteString
SB.toShort

hkdfCtx_init :: HmacKey -> HkdfCtx
hkdfCtx_init :: HmacKey -> HkdfCtx
hkdfCtx_init HmacKey
key = HmacCtx -> HkdfCtx
HkdfCtx (HmacKey -> HmacCtx
hmacCtx_init HmacKey
key)

hkdfCtx_feeds :: Foldable f => f ByteString -> HkdfCtx -> HkdfCtx
hkdfCtx_feeds :: forall (f :: * -> *).
Foldable f =>
f ByteString -> HkdfCtx -> HkdfCtx
hkdfCtx_feeds f ByteString
bs (HkdfCtx HmacCtx
ctx) = HmacCtx -> HkdfCtx
HkdfCtx (f ByteString -> HmacCtx -> HmacCtx
forall (f :: * -> *).
Foldable f =>
f ByteString -> HmacCtx -> HmacCtx
hmacCtx_feeds f ByteString
bs HmacCtx
ctx)

hkdfCtx_feed :: ByteString -> HkdfCtx -> HkdfCtx
hkdfCtx_feed :: ByteString -> HkdfCtx -> HkdfCtx
hkdfCtx_feed ByteString
bs (HkdfCtx HmacCtx
ctx) = HmacCtx -> HkdfCtx
HkdfCtx (ByteString -> HmacCtx -> HmacCtx
hmacCtx_feed ByteString
bs HmacCtx
ctx)

hkdfCtx_updates :: Foldable f => HkdfCtx -> f ByteString -> HkdfCtx
hkdfCtx_updates :: forall (f :: * -> *).
Foldable f =>
HkdfCtx -> f ByteString -> HkdfCtx
hkdfCtx_updates (HkdfCtx HmacCtx
ctx) f ByteString
bs = HmacCtx -> HkdfCtx
HkdfCtx (HmacCtx -> f ByteString -> HmacCtx
forall (f :: * -> *).
Foldable f =>
HmacCtx -> f ByteString -> HmacCtx
hmacCtx_updates HmacCtx
ctx f ByteString
bs)

hkdfCtx_update :: HkdfCtx -> ByteString -> HkdfCtx
hkdfCtx_update :: HkdfCtx -> ByteString -> HkdfCtx
hkdfCtx_update (HkdfCtx HmacCtx
ctx) ByteString
bs = HmacCtx -> HkdfCtx
HkdfCtx (HmacCtx -> ByteString -> HmacCtx
hmacCtx_update HmacCtx
ctx ByteString
bs)

hkdfCtx_finalize :: HkdfCtx -> HmacKey
hkdfCtx_finalize :: HkdfCtx -> HmacKey
hkdfCtx_finalize (HkdfCtx HmacCtx
ctx) = ByteString -> HmacKey
hmacKey (HashString -> ByteString
HS.toByteString (HmacCtx -> HashString
hmacCtx_finalize HmacCtx
ctx))

hkdfGen_init :: HmacKey -> ShortByteString -> HkdfGen
hkdfGen_init :: HmacKey -> ShortByteString -> HkdfGen
hkdfGen_init HmacKey
key ShortByteString
info = HkdfGen
   { hkdfGen_info :: ShortByteString
hkdfGen_info = ShortByteString
info
   , hkdfGen_key :: HmacKey
hkdfGen_key = HmacKey
key
   , hkdfGen_counter :: Word8
hkdfGen_counter = Word8
1
   , hkdfGen_state :: HashString
hkdfGen_state = ShortByteString -> HashString
HS.fromShort ShortByteString
SB.empty
   }

hkdfGen_read' :: HkdfGen -> (HashString, HkdfGen)
hkdfGen_read' :: HkdfGen -> (HashString, HkdfGen)
hkdfGen_read' HkdfGen
gen = (HashString
state',HkdfGen
gen')
 where
   info :: ShortByteString
info = HkdfGen -> ShortByteString
hkdfGen_info HkdfGen
gen
   key :: HmacKey
key = HkdfGen -> HmacKey
hkdfGen_key HkdfGen
gen
   counter :: Word8
counter = HkdfGen -> Word8
hkdfGen_counter HkdfGen
gen
   state :: HashString
state = HkdfGen -> HashString
hkdfGen_state HkdfGen
gen
   counter' :: Word8
counter' = Word8
counter Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Word8
1
   state' :: HashString
state' = HmacKey -> HmacCtx
hmacCtx_init HmacKey
key HmacCtx -> (HmacCtx -> HmacCtx) -> HmacCtx
forall a b. a -> (a -> b) -> b
&
            ByteString -> HmacCtx -> HmacCtx
hmacCtx_feed (HashString -> ByteString
HS.toByteString HashString
state) HmacCtx -> (HmacCtx -> HmacCtx) -> HmacCtx
forall a b. a -> (a -> b) -> b
&
            ByteString -> HmacCtx -> HmacCtx
hmacCtx_feed (ShortByteString -> ByteString
SB.fromShort ShortByteString
info) HmacCtx -> (HmacCtx -> HashString) -> HashString
forall a b. a -> (a -> b) -> b
&
            ByteString -> Word64 -> HmacCtx -> HashString
hmacCtx_finalizeBits (Word8 -> ByteString
B.singleton Word8
counter) Word64
8
   gen' :: HkdfGen
gen' = HkdfGen
     { hkdfGen_info :: ShortByteString
hkdfGen_info = ShortByteString
info
     , hkdfGen_key :: HmacKey
hkdfGen_key = HmacKey
key
     , hkdfGen_counter :: Word8
hkdfGen_counter = Word8
counter'
     , hkdfGen_state :: HashString
hkdfGen_state = HashString
state'
     }

hkdfGen_read :: HkdfGen -> (ByteString, HkdfGen)
hkdfGen_read :: HkdfGen -> (ByteString, HkdfGen)
hkdfGen_read = (HashString -> ByteString
HS.toByteString (HashString -> ByteString)
-> (HkdfGen -> HkdfGen)
-> (HashString, HkdfGen)
-> (ByteString, HkdfGen)
forall b c b' c'. (b -> c) -> (b' -> c') -> (b, b') -> (c, c')
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** HkdfGen -> HkdfGen
forall a. a -> a
id) ((HashString, HkdfGen) -> (ByteString, HkdfGen))
-> (HkdfGen -> (HashString, HkdfGen))
-> HkdfGen
-> (ByteString, HkdfGen)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HkdfGen -> (HashString, HkdfGen)
hkdfGen_read'

hkdfGen_peek :: HkdfGen -> Maybe HashString
hkdfGen_peek :: HkdfGen -> Maybe HashString
hkdfGen_peek HkdfGen
gen =
    if (ShortByteString -> Bool
SB.null (HashString -> ShortByteString
HS.toShort HashString
st))
    then Maybe HashString
forall a. Maybe a
Nothing
    else HashString -> Maybe HashString
forall a. a -> Maybe a
Just HashString
st
  where
    st :: HashString
st = HkdfGen -> HashString
hkdfGen_state HkdfGen
gen

hkdfGen_toList' :: HkdfGen -> [HashString]
hkdfGen_toList' :: HkdfGen -> [HashString]
hkdfGen_toList' = (HkdfGen -> Maybe (HashString, HkdfGen)) -> HkdfGen -> [HashString]
forall b a. (b -> Maybe (a, b)) -> b -> [a]
List.unfoldr ((HashString, HkdfGen) -> Maybe (HashString, HkdfGen)
forall a. a -> Maybe a
Just ((HashString, HkdfGen) -> Maybe (HashString, HkdfGen))
-> (HkdfGen -> (HashString, HkdfGen))
-> HkdfGen
-> Maybe (HashString, HkdfGen)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HkdfGen -> (HashString, HkdfGen)
hkdfGen_read')

hkdfGen_toList :: HkdfGen -> [ByteString]
hkdfGen_toList :: HkdfGen -> [ByteString]
hkdfGen_toList = (HkdfGen -> Maybe (ByteString, HkdfGen)) -> HkdfGen -> [ByteString]
forall b a. (b -> Maybe (a, b)) -> b -> [a]
List.unfoldr ((ByteString, HkdfGen) -> Maybe (ByteString, HkdfGen)
forall a. a -> Maybe a
Just ((ByteString, HkdfGen) -> Maybe (ByteString, HkdfGen))
-> (HkdfGen -> (ByteString, HkdfGen))
-> HkdfGen
-> Maybe (ByteString, HkdfGen)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HkdfGen -> (ByteString, HkdfGen)
hkdfGen_read)