packages feed

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 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