ppad-chacha 0.2.2 → 0.3.0
raw patch · 4 files changed
+54/−16 lines, 4 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Crypto.Cipher.ChaCha20: CounterOverflow :: Error
Files
- CHANGELOG +3/−0
- lib/Crypto/Cipher/ChaCha20.hs +23/−14
- ppad-chacha.cabal +2/−2
- test/Main.hs +26/−0
CHANGELOG view
@@ -1,5 +1,8 @@ # Changelog +- 0.3.0 (2026-09-06)+ * Adds a counter overflow error.+ - 0.2.2 (2026-05-16) * Features order-of-magnitude performance improvements, especially on ARM platforms where NEON intrinsics are available.
lib/Crypto/Cipher/ChaCha20.hs view
@@ -3,6 +3,7 @@ {-# LANGUAGE MagicHash #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE UnboxedTuples #-}+{-# LANGUAGE ViewPatterns #-} -- | -- Module: Crypto.Cipher.ChaCha20@@ -272,8 +273,9 @@ -- | 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@@ -332,26 +334,33 @@ -- -- >>> let key = "don't tell anyone my secret key!" -- >>> let non = "or my nonce!"--- >>> let cip = cipher key 1 non "but you can share the plaintext"+-- >>> let Right cip = cipher key 1 non "but you can share the ciphertext" -- >>> cip--- "\192*c\248A\204\211n\130y8\197\146k\245\178Y\197=\180_\223\138\146:^\206\&0\v[\201"+-- "\192*c\248A\204\211n\130y8\197\146k\245\178Y\197=\180_\223\153\151+_\197\&6\SUBF\197\160" -- >>> cipher key 1 non cip--- Right "but you can share the plaintext"+-- Right "but you can share the ciphertext" cipher :: BS.ByteString -- ^ 256-bit key -> Word32 -- ^ 32-bit counter -> 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
ppad-chacha.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: ppad-chacha-version: 0.2.2+version: 0.3.0 synopsis: A fast ChaCha20 stream cipher license: MIT license-file: LICENSE@@ -36,6 +36,7 @@ ghc-options: -fllvm -O2 exposed-modules: Crypto.Cipher.ChaCha20+ other-modules: Crypto.Cipher.ChaCha20.Arm build-depends: base >= 4.9 && < 5@@ -103,4 +104,3 @@ , deepseq , ppad-chacha , weigh-
test/Main.hs view
@@ -26,6 +26,8 @@ , crypt1 , crypt2 , crypt3+ , counter_boundary+ , counter_overflow ] quarter :: TestTree@@ -162,3 +164,27 @@ Right out = ChaCha.cipher key con non plain H.assertEqual mempty cip out +-- counter overflow++overflow_key :: BS.ByteString+overflow_key = fromJust . B16.decode $+ "0000000000000000000000000000000000000000000000000000000000000000"++overflow_non :: BS.ByteString+overflow_non = fromJust . B16.decode $ "000000000000000000000000"++counter_boundary :: TestTree+counter_boundary = H.testCase "chacha20 encrypt (counter boundary)" $ do+ let con = maxBound - 1+ plain = BS.replicate 128 0+ Right b0 = ChaCha.block overflow_key con overflow_non+ Right b1 = ChaCha.block overflow_key maxBound overflow_non+ Right out = ChaCha.cipher overflow_key con overflow_non plain+ H.assertEqual mempty (b0 <> b1) out++counter_overflow :: TestTree+counter_overflow = H.testCase "chacha20 encrypt (counter overflow)" $ do+ let con = maxBound - 1+ plain = BS.replicate 129 0+ out = ChaCha.cipher overflow_key con overflow_non plain+ H.assertEqual mempty (Left ChaCha.CounterOverflow) out