{-# LANGUAGE TemplateHaskell, ScopedTypeVariables #-}
module Crypto.Noise.Internal.SymmetricState where
import Control.Exception.Safe
import Control.Lens
import Data.ByteArray (ScrubbedBytes, length, replicate)
import Data.Proxy
import Prelude hiding (length, replicate)
import Crypto.Noise.Cipher
import Crypto.Noise.Hash
import Crypto.Noise.Internal.CipherState
data SymmetricState c h =
SymmetricState { forall c h. SymmetricState c h -> CipherState c
_ssCipher :: CipherState c
, forall c h. SymmetricState c h -> ChainingKey h
_ssck :: ChainingKey h
, forall c h. SymmetricState c h -> Either ScrubbedBytes (Digest h)
_ssh :: Either ScrubbedBytes (Digest h)
}
$(makeLenses ''SymmetricState)
symmetricState :: forall c h. (Cipher c, Hash h)
=> ScrubbedBytes
-> SymmetricState c h
symmetricState :: forall c h.
(Cipher c, Hash h) =>
ScrubbedBytes -> SymmetricState c h
symmetricState ScrubbedBytes
protoName = CipherState c
-> ChainingKey h
-> Either ScrubbedBytes (Digest h)
-> SymmetricState c h
forall c h.
CipherState c
-> ChainingKey h
-> Either ScrubbedBytes (Digest h)
-> SymmetricState c h
SymmetricState CipherState c
cs ChainingKey h
ck Either ScrubbedBytes (Digest h)
h
where
hashLen :: Int
hashLen = Proxy h -> Int
forall h (proxy :: * -> *). Hash h => proxy h -> Int
forall (proxy :: * -> *). proxy h -> Int
hashLength (Proxy h
forall {k} (t :: k). Proxy t
Proxy :: Proxy h)
shouldHash :: Bool
shouldHash = ScrubbedBytes -> Int
forall ba. ByteArrayAccess ba => ba -> Int
length ScrubbedBytes
protoName Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
hashLen
h :: Either ScrubbedBytes (Digest h)
h = if Bool
shouldHash
then Digest h -> Either ScrubbedBytes (Digest h)
forall a b. b -> Either a b
Right (Digest h -> Either ScrubbedBytes (Digest h))
-> Digest h -> Either ScrubbedBytes (Digest h)
forall a b. (a -> b) -> a -> b
$ ScrubbedBytes -> Digest h
forall h. Hash h => ScrubbedBytes -> Digest h
hash ScrubbedBytes
protoName
else ScrubbedBytes -> Either ScrubbedBytes (Digest h)
forall a b. a -> Either a b
Left (ScrubbedBytes -> Either ScrubbedBytes (Digest h))
-> ScrubbedBytes -> Either ScrubbedBytes (Digest h)
forall a b. (a -> b) -> a -> b
$ ScrubbedBytes
protoName ScrubbedBytes -> ScrubbedBytes -> ScrubbedBytes
forall a. Monoid a => a -> a -> a
`mappend` Int -> Word8 -> ScrubbedBytes
forall ba. ByteArray ba => Int -> Word8 -> ba
replicate (Int
hashLen Int -> Int -> Int
forall a. Num a => a -> a -> a
- ScrubbedBytes -> Int
forall ba. ByteArrayAccess ba => ba -> Int
length ScrubbedBytes
protoName) Word8
0
ck :: ChainingKey h
ck = ScrubbedBytes -> ChainingKey h
forall h. Hash h => ScrubbedBytes -> ChainingKey h
hashBytesToCK (ScrubbedBytes -> ChainingKey h)
-> (Either ScrubbedBytes (Digest h) -> ScrubbedBytes)
-> Either ScrubbedBytes (Digest h)
-> ChainingKey h
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either ScrubbedBytes (Digest h) -> ScrubbedBytes
forall h.
Hash h =>
Either ScrubbedBytes (Digest h) -> ScrubbedBytes
sshBytes (Either ScrubbedBytes (Digest h) -> ChainingKey h)
-> Either ScrubbedBytes (Digest h) -> ChainingKey h
forall a b. (a -> b) -> a -> b
$ Either ScrubbedBytes (Digest h)
h
cs :: CipherState c
cs = Maybe (SymmetricKey c) -> CipherState c
forall c. Cipher c => Maybe (SymmetricKey c) -> CipherState c
cipherState Maybe (SymmetricKey c)
forall a. Maybe a
Nothing
mixKey :: (Cipher c, Hash h)
=> ScrubbedBytes
-> SymmetricState c h
-> SymmetricState c h
mixKey :: forall c h.
(Cipher c, Hash h) =>
ScrubbedBytes -> SymmetricState c h -> SymmetricState c h
mixKey ScrubbedBytes
keyMat SymmetricState c h
ss = SymmetricState c h
ss SymmetricState c h
-> (SymmetricState c h -> SymmetricState c h) -> SymmetricState c h
forall a b. a -> (a -> b) -> b
& (CipherState c -> Identity (CipherState c))
-> SymmetricState c h -> Identity (SymmetricState c h)
forall c h c (f :: * -> *).
Functor f =>
(CipherState c -> f (CipherState c))
-> SymmetricState c h -> f (SymmetricState c h)
ssCipher ((CipherState c -> Identity (CipherState c))
-> SymmetricState c h -> Identity (SymmetricState c h))
-> CipherState c -> SymmetricState c h -> SymmetricState c h
forall s t a b. ASetter s t a b -> b -> s -> t
.~ CipherState c
cs
SymmetricState c h
-> (SymmetricState c h -> SymmetricState c h) -> SymmetricState c h
forall a b. a -> (a -> b) -> b
& (ChainingKey h -> Identity (ChainingKey h))
-> SymmetricState c h -> Identity (SymmetricState c h)
forall c h (f :: * -> *).
Functor f =>
(ChainingKey h -> f (ChainingKey h))
-> SymmetricState c h -> f (SymmetricState c h)
ssck ((ChainingKey h -> Identity (ChainingKey h))
-> SymmetricState c h -> Identity (SymmetricState c h))
-> ChainingKey h -> SymmetricState c h -> SymmetricState c h
forall s t a b. ASetter s t a b -> b -> s -> t
.~ ScrubbedBytes -> ChainingKey h
forall h. Hash h => ScrubbedBytes -> ChainingKey h
hashBytesToCK ScrubbedBytes
ck
where
[ScrubbedBytes
ck, ScrubbedBytes
k] = ChainingKey h -> ScrubbedBytes -> Word8 -> [ScrubbedBytes]
forall h.
Hash h =>
ChainingKey h -> ScrubbedBytes -> Word8 -> [ScrubbedBytes]
hashHKDF (SymmetricState c h
ss SymmetricState c h
-> Getting (ChainingKey h) (SymmetricState c h) (ChainingKey h)
-> ChainingKey h
forall s a. s -> Getting a s a -> a
^. Getting (ChainingKey h) (SymmetricState c h) (ChainingKey h)
forall c h (f :: * -> *).
Functor f =>
(ChainingKey h -> f (ChainingKey h))
-> SymmetricState c h -> f (SymmetricState c h)
ssck) ScrubbedBytes
keyMat Word8
2
cs :: CipherState c
cs = Maybe (SymmetricKey c) -> CipherState c
forall c. Cipher c => Maybe (SymmetricKey c) -> CipherState c
cipherState (Maybe (SymmetricKey c) -> CipherState c)
-> (ScrubbedBytes -> Maybe (SymmetricKey c))
-> ScrubbedBytes
-> CipherState c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SymmetricKey c -> Maybe (SymmetricKey c)
forall a. a -> Maybe a
Just (SymmetricKey c -> Maybe (SymmetricKey c))
-> (ScrubbedBytes -> SymmetricKey c)
-> ScrubbedBytes
-> Maybe (SymmetricKey c)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScrubbedBytes -> SymmetricKey c
forall c. Cipher c => ScrubbedBytes -> SymmetricKey c
cipherBytesToSym (ScrubbedBytes -> CipherState c) -> ScrubbedBytes -> CipherState c
forall a b. (a -> b) -> a -> b
$ ScrubbedBytes
k
mixHash :: Hash h
=> ScrubbedBytes
-> SymmetricState c h
-> SymmetricState c h
mixHash :: forall h c.
Hash h =>
ScrubbedBytes -> SymmetricState c h -> SymmetricState c h
mixHash ScrubbedBytes
d SymmetricState c h
ss = SymmetricState c h
ss SymmetricState c h
-> (SymmetricState c h -> SymmetricState c h) -> SymmetricState c h
forall a b. a -> (a -> b) -> b
& (Either ScrubbedBytes (Digest h)
-> Identity (Either ScrubbedBytes (Digest h)))
-> SymmetricState c h -> Identity (SymmetricState c h)
forall c h (f :: * -> *).
Functor f =>
(Either ScrubbedBytes (Digest h)
-> f (Either ScrubbedBytes (Digest h)))
-> SymmetricState c h -> f (SymmetricState c h)
ssh ((Either ScrubbedBytes (Digest h)
-> Identity (Either ScrubbedBytes (Digest h)))
-> SymmetricState c h -> Identity (SymmetricState c h))
-> (Either ScrubbedBytes (Digest h)
-> Either ScrubbedBytes (Digest h))
-> SymmetricState c h
-> SymmetricState c h
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ Digest h -> Either ScrubbedBytes (Digest h)
forall a b. b -> Either a b
Right (Digest h -> Either ScrubbedBytes (Digest h))
-> (Either ScrubbedBytes (Digest h) -> Digest h)
-> Either ScrubbedBytes (Digest h)
-> Either ScrubbedBytes (Digest h)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScrubbedBytes -> Digest h
forall h. Hash h => ScrubbedBytes -> Digest h
hash (ScrubbedBytes -> Digest h)
-> (Either ScrubbedBytes (Digest h) -> ScrubbedBytes)
-> Either ScrubbedBytes (Digest h)
-> Digest h
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ScrubbedBytes -> ScrubbedBytes -> ScrubbedBytes
forall a. Monoid a => a -> a -> a
`mappend` ScrubbedBytes
d) (ScrubbedBytes -> ScrubbedBytes)
-> (Either ScrubbedBytes (Digest h) -> ScrubbedBytes)
-> Either ScrubbedBytes (Digest h)
-> ScrubbedBytes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either ScrubbedBytes (Digest h) -> ScrubbedBytes
forall h.
Hash h =>
Either ScrubbedBytes (Digest h) -> ScrubbedBytes
sshBytes
mixKeyAndHash :: (Cipher c, Hash h)
=> ScrubbedBytes
-> SymmetricState c h
-> SymmetricState c h
mixKeyAndHash :: forall c h.
(Cipher c, Hash h) =>
ScrubbedBytes -> SymmetricState c h -> SymmetricState c h
mixKeyAndHash ScrubbedBytes
keyMat SymmetricState c h
ss = SymmetricState c h
ss' SymmetricState c h
-> (SymmetricState c h -> SymmetricState c h) -> SymmetricState c h
forall a b. a -> (a -> b) -> b
& (CipherState c -> Identity (CipherState c))
-> SymmetricState c h -> Identity (SymmetricState c h)
forall c h c (f :: * -> *).
Functor f =>
(CipherState c -> f (CipherState c))
-> SymmetricState c h -> f (SymmetricState c h)
ssCipher ((CipherState c -> Identity (CipherState c))
-> SymmetricState c h -> Identity (SymmetricState c h))
-> CipherState c -> SymmetricState c h -> SymmetricState c h
forall s t a b. ASetter s t a b -> b -> s -> t
.~ CipherState c
cs
SymmetricState c h
-> (SymmetricState c h -> SymmetricState c h) -> SymmetricState c h
forall a b. a -> (a -> b) -> b
& (ChainingKey h -> Identity (ChainingKey h))
-> SymmetricState c h -> Identity (SymmetricState c h)
forall c h (f :: * -> *).
Functor f =>
(ChainingKey h -> f (ChainingKey h))
-> SymmetricState c h -> f (SymmetricState c h)
ssck ((ChainingKey h -> Identity (ChainingKey h))
-> SymmetricState c h -> Identity (SymmetricState c h))
-> ChainingKey h -> SymmetricState c h -> SymmetricState c h
forall s t a b. ASetter s t a b -> b -> s -> t
.~ ScrubbedBytes -> ChainingKey h
forall h. Hash h => ScrubbedBytes -> ChainingKey h
hashBytesToCK ScrubbedBytes
ck
where
[ScrubbedBytes
ck, ScrubbedBytes
h, ScrubbedBytes
k] = ChainingKey h -> ScrubbedBytes -> Word8 -> [ScrubbedBytes]
forall h.
Hash h =>
ChainingKey h -> ScrubbedBytes -> Word8 -> [ScrubbedBytes]
hashHKDF (SymmetricState c h
ss SymmetricState c h
-> Getting (ChainingKey h) (SymmetricState c h) (ChainingKey h)
-> ChainingKey h
forall s a. s -> Getting a s a -> a
^. Getting (ChainingKey h) (SymmetricState c h) (ChainingKey h)
forall c h (f :: * -> *).
Functor f =>
(ChainingKey h -> f (ChainingKey h))
-> SymmetricState c h -> f (SymmetricState c h)
ssck) ScrubbedBytes
keyMat Word8
3
ss' :: SymmetricState c h
ss' = ScrubbedBytes -> SymmetricState c h -> SymmetricState c h
forall h c.
Hash h =>
ScrubbedBytes -> SymmetricState c h -> SymmetricState c h
mixHash ScrubbedBytes
h SymmetricState c h
ss
cs :: CipherState c
cs = Maybe (SymmetricKey c) -> CipherState c
forall c. Cipher c => Maybe (SymmetricKey c) -> CipherState c
cipherState (Maybe (SymmetricKey c) -> CipherState c)
-> (ScrubbedBytes -> Maybe (SymmetricKey c))
-> ScrubbedBytes
-> CipherState c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SymmetricKey c -> Maybe (SymmetricKey c)
forall a. a -> Maybe a
Just (SymmetricKey c -> Maybe (SymmetricKey c))
-> (ScrubbedBytes -> SymmetricKey c)
-> ScrubbedBytes
-> Maybe (SymmetricKey c)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScrubbedBytes -> SymmetricKey c
forall c. Cipher c => ScrubbedBytes -> SymmetricKey c
cipherBytesToSym (ScrubbedBytes -> CipherState c) -> ScrubbedBytes -> CipherState c
forall a b. (a -> b) -> a -> b
$ ScrubbedBytes
k
encryptAndHash :: (MonadThrow m, Cipher c, Hash h)
=> Plaintext
-> SymmetricState c h
-> m (Ciphertext c, SymmetricState c h)
encryptAndHash :: forall (m :: * -> *) c h.
(MonadThrow m, Cipher c, Hash h) =>
ScrubbedBytes
-> SymmetricState c h -> m (Ciphertext c, SymmetricState c h)
encryptAndHash ScrubbedBytes
pt SymmetricState c h
ss = do
(Ciphertext c
ct, CipherState c
cs) <- ScrubbedBytes
-> ScrubbedBytes
-> CipherState c
-> m (Ciphertext c, CipherState c)
forall (m :: * -> *) c.
(MonadThrow m, Cipher c) =>
ScrubbedBytes
-> ScrubbedBytes
-> CipherState c
-> m (Ciphertext c, CipherState c)
encryptWithAd (Either ScrubbedBytes (Digest h) -> ScrubbedBytes
forall h.
Hash h =>
Either ScrubbedBytes (Digest h) -> ScrubbedBytes
sshBytes (SymmetricState c h
ss SymmetricState c h
-> Getting
(Either ScrubbedBytes (Digest h))
(SymmetricState c h)
(Either ScrubbedBytes (Digest h))
-> Either ScrubbedBytes (Digest h)
forall s a. s -> Getting a s a -> a
^. Getting
(Either ScrubbedBytes (Digest h))
(SymmetricState c h)
(Either ScrubbedBytes (Digest h))
forall c h (f :: * -> *).
Functor f =>
(Either ScrubbedBytes (Digest h)
-> f (Either ScrubbedBytes (Digest h)))
-> SymmetricState c h -> f (SymmetricState c h)
ssh)) ScrubbedBytes
pt (SymmetricState c h
ss SymmetricState c h
-> Getting (CipherState c) (SymmetricState c h) (CipherState c)
-> CipherState c
forall s a. s -> Getting a s a -> a
^. Getting (CipherState c) (SymmetricState c h) (CipherState c)
forall c h c (f :: * -> *).
Functor f =>
(CipherState c -> f (CipherState c))
-> SymmetricState c h -> f (SymmetricState c h)
ssCipher)
let ss' :: SymmetricState c h
ss' = ScrubbedBytes -> SymmetricState c h -> SymmetricState c h
forall h c.
Hash h =>
ScrubbedBytes -> SymmetricState c h -> SymmetricState c h
mixHash (Ciphertext c -> ScrubbedBytes
forall c. Cipher c => Ciphertext c -> ScrubbedBytes
cipherTextToBytes Ciphertext c
ct) SymmetricState c h
ss
(Ciphertext c, SymmetricState c h)
-> m (Ciphertext c, SymmetricState c h)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Ciphertext c
ct, SymmetricState c h
ss' SymmetricState c h
-> (SymmetricState c h -> SymmetricState c h) -> SymmetricState c h
forall a b. a -> (a -> b) -> b
& (CipherState c -> Identity (CipherState c))
-> SymmetricState c h -> Identity (SymmetricState c h)
forall c h c (f :: * -> *).
Functor f =>
(CipherState c -> f (CipherState c))
-> SymmetricState c h -> f (SymmetricState c h)
ssCipher ((CipherState c -> Identity (CipherState c))
-> SymmetricState c h -> Identity (SymmetricState c h))
-> CipherState c -> SymmetricState c h -> SymmetricState c h
forall s t a b. ASetter s t a b -> b -> s -> t
.~ CipherState c
cs)
decryptAndHash :: (MonadThrow m, Cipher c, Hash h)
=> Ciphertext c
-> SymmetricState c h
-> m (Plaintext, SymmetricState c h)
decryptAndHash :: forall (m :: * -> *) c h.
(MonadThrow m, Cipher c, Hash h) =>
Ciphertext c
-> SymmetricState c h -> m (ScrubbedBytes, SymmetricState c h)
decryptAndHash Ciphertext c
ct SymmetricState c h
ss = do
(ScrubbedBytes
pt, CipherState c
cs) <- ScrubbedBytes
-> Ciphertext c
-> CipherState c
-> m (ScrubbedBytes, CipherState c)
forall (m :: * -> *) c.
(MonadThrow m, Cipher c) =>
ScrubbedBytes
-> Ciphertext c
-> CipherState c
-> m (ScrubbedBytes, CipherState c)
decryptWithAd (Either ScrubbedBytes (Digest h) -> ScrubbedBytes
forall h.
Hash h =>
Either ScrubbedBytes (Digest h) -> ScrubbedBytes
sshBytes (SymmetricState c h
ss SymmetricState c h
-> Getting
(Either ScrubbedBytes (Digest h))
(SymmetricState c h)
(Either ScrubbedBytes (Digest h))
-> Either ScrubbedBytes (Digest h)
forall s a. s -> Getting a s a -> a
^. Getting
(Either ScrubbedBytes (Digest h))
(SymmetricState c h)
(Either ScrubbedBytes (Digest h))
forall c h (f :: * -> *).
Functor f =>
(Either ScrubbedBytes (Digest h)
-> f (Either ScrubbedBytes (Digest h)))
-> SymmetricState c h -> f (SymmetricState c h)
ssh)) Ciphertext c
ct (SymmetricState c h
ss SymmetricState c h
-> Getting (CipherState c) (SymmetricState c h) (CipherState c)
-> CipherState c
forall s a. s -> Getting a s a -> a
^. Getting (CipherState c) (SymmetricState c h) (CipherState c)
forall c h c (f :: * -> *).
Functor f =>
(CipherState c -> f (CipherState c))
-> SymmetricState c h -> f (SymmetricState c h)
ssCipher)
let ss' :: SymmetricState c h
ss' = ScrubbedBytes -> SymmetricState c h -> SymmetricState c h
forall h c.
Hash h =>
ScrubbedBytes -> SymmetricState c h -> SymmetricState c h
mixHash (Ciphertext c -> ScrubbedBytes
forall c. Cipher c => Ciphertext c -> ScrubbedBytes
cipherTextToBytes Ciphertext c
ct) SymmetricState c h
ss
(ScrubbedBytes, SymmetricState c h)
-> m (ScrubbedBytes, SymmetricState c h)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (ScrubbedBytes
pt, SymmetricState c h
ss' SymmetricState c h
-> (SymmetricState c h -> SymmetricState c h) -> SymmetricState c h
forall a b. a -> (a -> b) -> b
& (CipherState c -> Identity (CipherState c))
-> SymmetricState c h -> Identity (SymmetricState c h)
forall c h c (f :: * -> *).
Functor f =>
(CipherState c -> f (CipherState c))
-> SymmetricState c h -> f (SymmetricState c h)
ssCipher ((CipherState c -> Identity (CipherState c))
-> SymmetricState c h -> Identity (SymmetricState c h))
-> CipherState c -> SymmetricState c h -> SymmetricState c h
forall s t a b. ASetter s t a b -> b -> s -> t
.~ CipherState c
cs)
split :: (Cipher c, Hash h)
=> SymmetricState c h
-> (CipherState c, CipherState c)
split :: forall c h.
(Cipher c, Hash h) =>
SymmetricState c h -> (CipherState c, CipherState c)
split SymmetricState c h
ss = (CipherState c
c1, CipherState c
c2)
where
[ScrubbedBytes
k1, ScrubbedBytes
k2] = ChainingKey h -> ScrubbedBytes -> Word8 -> [ScrubbedBytes]
forall h.
Hash h =>
ChainingKey h -> ScrubbedBytes -> Word8 -> [ScrubbedBytes]
hashHKDF (SymmetricState c h
ss SymmetricState c h
-> Getting (ChainingKey h) (SymmetricState c h) (ChainingKey h)
-> ChainingKey h
forall s a. s -> Getting a s a -> a
^. Getting (ChainingKey h) (SymmetricState c h) (ChainingKey h)
forall c h (f :: * -> *).
Functor f =>
(ChainingKey h -> f (ChainingKey h))
-> SymmetricState c h -> f (SymmetricState c h)
ssck) ScrubbedBytes
forall a. Monoid a => a
mempty Word8
2
c1 :: CipherState c
c1 = Maybe (SymmetricKey c) -> CipherState c
forall c. Cipher c => Maybe (SymmetricKey c) -> CipherState c
cipherState (Maybe (SymmetricKey c) -> CipherState c)
-> (ScrubbedBytes -> Maybe (SymmetricKey c))
-> ScrubbedBytes
-> CipherState c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SymmetricKey c -> Maybe (SymmetricKey c)
forall a. a -> Maybe a
Just (SymmetricKey c -> Maybe (SymmetricKey c))
-> (ScrubbedBytes -> SymmetricKey c)
-> ScrubbedBytes
-> Maybe (SymmetricKey c)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScrubbedBytes -> SymmetricKey c
forall c. Cipher c => ScrubbedBytes -> SymmetricKey c
cipherBytesToSym (ScrubbedBytes -> CipherState c) -> ScrubbedBytes -> CipherState c
forall a b. (a -> b) -> a -> b
$ ScrubbedBytes
k1
c2 :: CipherState c
c2 = Maybe (SymmetricKey c) -> CipherState c
forall c. Cipher c => Maybe (SymmetricKey c) -> CipherState c
cipherState (Maybe (SymmetricKey c) -> CipherState c)
-> (ScrubbedBytes -> Maybe (SymmetricKey c))
-> ScrubbedBytes
-> CipherState c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SymmetricKey c -> Maybe (SymmetricKey c)
forall a. a -> Maybe a
Just (SymmetricKey c -> Maybe (SymmetricKey c))
-> (ScrubbedBytes -> SymmetricKey c)
-> ScrubbedBytes
-> Maybe (SymmetricKey c)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScrubbedBytes -> SymmetricKey c
forall c. Cipher c => ScrubbedBytes -> SymmetricKey c
cipherBytesToSym (ScrubbedBytes -> CipherState c) -> ScrubbedBytes -> CipherState c
forall a b. (a -> b) -> a -> b
$ ScrubbedBytes
k2
sshBytes :: Hash h
=> Either ScrubbedBytes (Digest h)
-> ScrubbedBytes
sshBytes :: forall h.
Hash h =>
Either ScrubbedBytes (Digest h) -> ScrubbedBytes
sshBytes (Left ScrubbedBytes
h) = ScrubbedBytes
h
sshBytes (Right Digest h
h) = Digest h -> ScrubbedBytes
forall h. Hash h => Digest h -> ScrubbedBytes
hashToBytes Digest h
h