-- SPDX-FileCopyrightText: 2022 Sarah Vaupel -- -- SPDX-License-Identifier: AGPL-3.0-or-later module Handler.Utils.Random ( secretBoxCSPRNGT, secretBoxCSPRNGPure , secretBoxCSPRNG' ) where import Import.NoModel import qualified Crypto.MAC.KMAC as Crypto import qualified Crypto.Saltine.Class as Saltine import Crypto.Hash.Algorithms (SHAKE256) import Data.ByteArray (ByteArrayAccess) import qualified Data.ByteArray as BA import qualified Crypto.Random as Crypto import Crypto.Error (onCryptoFailure) import Control.Monad.Random.Lazy (RandT, Rand, evalRandT) secretBoxCSPRNG' :: forall m m' string ba chunk a. ( MonadSecretBox m , MonadThrow m , Monad m' , ByteArrayAccess string , ByteArrayAccess chunk , LazySequence ba chunk ) => (forall b. m' b -> m b) -> string -- ^ Customization string -> ba -- ^ Seed -> RandT ChaChaDRG m' a -> m a secretBoxCSPRNG' nat str seed act = do sBoxKey <- secretBoxKey let seed' = toDigest $ kmaclazy str (Saltine.encode sBoxKey) seed where toDigest :: Crypto.KMAC (SHAKE256 320) -> ByteString toDigest = BA.convert csprng <- fmap Crypto.drgNewSeed . onCryptoFailure throwM return $ Crypto.seedFromBinary seed' nat $ evalRandT act csprng secretBoxCSPRNGT :: forall m string ba chunk a. ( MonadSecretBox m , MonadThrow m , ByteArrayAccess string , ByteArrayAccess chunk , LazySequence ba chunk ) => string -- ^ Customization string -> ba -- ^ Seed -> RandT ChaChaDRG m a -> m a secretBoxCSPRNGT = secretBoxCSPRNG' id secretBoxCSPRNGPure :: forall m string ba chunk a. ( MonadSecretBox m , MonadThrow m , ByteArrayAccess string , ByteArrayAccess chunk , LazySequence ba chunk ) => string -- ^ Customization string -> ba -- ^ Seed -> Rand ChaChaDRG a -> m a secretBoxCSPRNGPure = secretBoxCSPRNG' generalize