chacha

The ChaCha20 stream cipher (docs.ppad.tech/chacha).
git clone git://git.ppad.tech/chacha.git
Log | Files | Refs | README | LICENSE

commit 23dae71b968f4d450476f9d6ed7e094582edffbc
parent 7ac8e830d35eb56c0bdec6e413272f103dd7d274
Author: Jared Tobin <jared@jtobin.io>
Date:   Sun,  6 Sep 2026 17:38:42 +0400

lib: add counter overflow guard

Morally this should be in here, so..

Diffstat:
Mlib/Crypto/Cipher/ChaCha20.hs | 31++++++++++++++++++++-----------
1 file changed, 20 insertions(+), 11 deletions(-)

diff --git a/lib/Crypto/Cipher/ChaCha20.hs b/lib/Crypto/Cipher/ChaCha20.hs @@ -3,6 +3,7 @@ {-# LANGUAGE MagicHash #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE ViewPatterns #-} -- | -- Module: Crypto.Cipher.ChaCha20 @@ -272,8 +273,9 @@ _block state@(ChaCha s) counter = do -- | Error values. data Error = - InvalidKey -- ^ the provided key was not 256 bits long - | InvalidNonce -- ^ the provided nonce was none 96 bits long + CounterOverflow -- ^ the counter overflowed + | InvalidKey -- ^ the provided key was not 256 bits long + | InvalidNonce -- ^ the provided nonce was not 96 bits long deriving (Eq, Show) -- RFC8439 2.3 @@ -343,15 +345,22 @@ cipher -> BS.ByteString -- ^ 96-bit nonce -> BS.ByteString -- ^ arbitrary-length plaintext -> Either Error BS.ByteString -- ^ ciphertext -cipher raw_key@(BI.PS _ _ kl) counter raw_nonce@(BI.PS _ _ nl) plaintext - | kl /= 32 = Left InvalidKey - | nl /= 12 = Left InvalidNonce - | Arm.chacha20_arm_available = - Right (Arm.cipher raw_key counter raw_nonce plaintext) - | otherwise = pure $ runST $ do - let key = _parse_key raw_key - non = _parse_nonce raw_nonce - _cipher key counter non plaintext +cipher + raw_key@(BI.PS _ _ kl) + counter + raw_nonce@(BI.PS _ _ nl) + plaintext@(BI.PS _ _ (fi -> pl)) + | kl /= 32 = Left InvalidKey + | nl /= 12 = Left InvalidNonce + | pl > room = Left CounterOverflow + | Arm.chacha20_arm_available = + Right (Arm.cipher raw_key counter raw_nonce plaintext) + | otherwise = pure $ runST $ do + let key = _parse_key raw_key + non = _parse_nonce raw_nonce + _cipher key counter non plaintext + where + room = (0x100000000 - fi counter) * 64 :: Word64 _cipher :: PrimMonad m