packages feed

crypton 0.33 → 0.34

raw patch · 23 files changed

+1004/−446 lines, 23 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Crypto.Cipher.ChaCha: initializeX :: (ByteArrayAccess key, ByteArrayAccess nonce) => Int -> key -> nonce -> State
+ Crypto.Cipher.ChaChaPoly1305: data XNonce
+ Crypto.Cipher.ChaChaPoly1305: initializeX :: ByteArrayAccess key => key -> XNonce -> CryptoFailable State
+ Crypto.Cipher.ChaChaPoly1305: instance Data.ByteArray.Types.ByteArrayAccess Crypto.Cipher.ChaChaPoly1305.XNonce
+ Crypto.Cipher.ChaChaPoly1305: nonce24 :: ByteArrayAccess ba => ba -> CryptoFailable XNonce
+ Crypto.MAC.KeyedBlake2: KeyedBlake2 :: Digest a -> KeyedBlake2 a
+ Crypto.MAC.KeyedBlake2: [keyedBlake2GetDigest] :: KeyedBlake2 a -> Digest a
+ Crypto.MAC.KeyedBlake2: class HashAlgorithm a => HashBlake2 a
+ Crypto.MAC.KeyedBlake2: data Context a
+ Crypto.MAC.KeyedBlake2: finalize :: HashBlake2 a => Context a -> KeyedBlake2 a
+ Crypto.MAC.KeyedBlake2: initialize :: forall a key. (HashBlake2 a, ByteArrayAccess key) => key -> Context a
+ Crypto.MAC.KeyedBlake2: instance Control.DeepSeq.NFData (Crypto.MAC.KeyedBlake2.KeyedBlake2 a)
+ Crypto.MAC.KeyedBlake2: instance Data.ByteArray.Types.ByteArrayAccess (Crypto.MAC.KeyedBlake2.KeyedBlake2 a)
+ Crypto.MAC.KeyedBlake2: instance GHC.Classes.Eq (Crypto.MAC.KeyedBlake2.KeyedBlake2 a)
+ Crypto.MAC.KeyedBlake2: keyedBlake2 :: (HashBlake2 a, ByteArrayAccess key, ByteArrayAccess ba) => key -> ba -> KeyedBlake2 a
+ Crypto.MAC.KeyedBlake2: keyedBlake2Lazy :: (HashBlake2 a, ByteArrayAccess key) => key -> ByteString -> KeyedBlake2 a
+ Crypto.MAC.KeyedBlake2: newtype KeyedBlake2 a
+ Crypto.MAC.KeyedBlake2: update :: (HashBlake2 a, ByteArrayAccess ba) => Context a -> ba -> Context a
+ Crypto.MAC.KeyedBlake2: updates :: (HashBlake2 a, ByteArrayAccess ba) => Context a -> [ba] -> Context a

Files

CHANGELOG.md view
@@ -1,3 +1,12 @@+## 0.34++* Hashing getRandomBytes before using as Seed for ChaChaDRG+  [#24](https://github.com/kazu-yamamoto/crypton/pull/24)+* Add support for XChaCha and XChaChaPoly1305+  [#18](https://github.com/kazu-yamamoto/crypton/pull/18)+* Strict byteArray of IV c+  [#16](https://github.com/kazu-yamamoto/crypton/pull/16)+ ## 0.33  * Add "crypton_" prefix to the final C symbols.
Crypto/Cipher/ChaCha.hs view
@@ -9,6 +9,7 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Crypto.Cipher.ChaCha     ( initialize+    , initializeX     , combine     , generate     , State@@ -53,6 +54,28 @@   where kLen     = B.length key         nonceLen = B.length nonce +-- | Initialize a new XChaCha context with the number of rounds,+-- the key and the nonce associated.+--+-- An XChaCha state can be used like a regular ChaCha state after initialisation.+initializeX :: (ByteArrayAccess key, ByteArrayAccess nonce)+            => Int   -- ^ number of rounds (8,12,20)+            -> key   -- ^ the key (256 bits)+            -> nonce -- ^ the nonce (192 bits)+            -> State -- ^ the initial ChaCha state+initializeX nbRounds key nonce+    | kLen /= 32                      = error "XChaCha: key length should be 256 bits"+    | nonceLen /= 24                  = error "XChaCha: nonce length should be 192 bits"+    | nbRounds `notElem` [8,12,20]    = error "XChaCha: rounds should be 8, 12 or 20"+    | otherwise                       = unsafeDoIO $ do+        stPtr <- B.alloc 132 $ \stPtr ->+            B.withByteArray nonce $ \noncePtr  ->+            B.withByteArray key   $ \keyPtr ->+                ccrypton_xchacha_init stPtr nbRounds keyPtr noncePtr+        return $ State stPtr+  where kLen     = B.length key+        nonceLen = B.length nonce+ -- | Initialize simple ChaCha State -- -- The seed need to be at least 40 bytes long@@ -114,6 +137,9 @@  foreign import ccall "crypton_chacha_init"     ccrypton_chacha_init :: Ptr State -> Int -> Int -> Ptr Word8 -> Int -> Ptr Word8 -> IO ()++foreign import ccall "crypton_xchacha_init"+    ccrypton_xchacha_init :: Ptr State -> Int -> Ptr Word8 -> Ptr Word8 -> IO ()  foreign import ccall "crypton_chacha_combine"     ccrypton_chacha_combine :: Ptr Word8 -> Ptr State -> Ptr Word8 -> CUInt -> IO ()
Crypto/Cipher/ChaChaPoly1305.hs view
@@ -38,10 +38,13 @@ module Crypto.Cipher.ChaChaPoly1305     ( State     , Nonce+    , XNonce     , nonce12     , nonce8+    , nonce24     , incrementNonce     , initialize+    , initializeX     , appendAAD     , finalizeAAD     , encrypt@@ -81,6 +84,14 @@   withByteArray (Nonce8  n) = B.withByteArray n   withByteArray (Nonce12 n) = B.withByteArray n +-- | Extended nonce for XChaChaPoly1305.+newtype XNonce = Nonce24 Bytes++instance ByteArrayAccess XNonce where+  length (Nonce24 n) = B.length n+  withByteArray (Nonce24 n) = B.withByteArray n++ -- Based on the following pseudo code: -- -- chacha20_aead_encrypt(aad, key, iv, constant, plaintext):@@ -117,6 +128,13 @@     | B.length iv       /= 8 = CryptoFailed CryptoError_IvSizeInvalid     | otherwise              = CryptoPassed . Nonce8 . B.concat $ [constant, iv] +-- | 24 bytes IV, extended nonce constructor+nonce24 :: ByteArrayAccess ba+        => ba -> CryptoFailable XNonce+nonce24 iv+    | B.length iv /= 24 = CryptoFailed CryptoError_IvSizeInvalid+    | otherwise         = CryptoPassed . Nonce24 . B.convert $ iv+ -- | Increment a nonce incrementNonce :: Nonce -> Nonce incrementNonce (Nonce8  n) = Nonce8  $ incrementNonce' n 4@@ -143,15 +161,33 @@ initialize key (Nonce8  nonce) = initialize' key nonce initialize key (Nonce12 nonce) = initialize' key nonce + initialize' :: ByteArrayAccess key             => key -> Bytes -> CryptoFailable State initialize' key nonce     | B.length key /= 32 = CryptoFailed CryptoError_KeySizeInvalid-    | otherwise          = CryptoPassed $ State encState polyState 0 0+    | otherwise          = CryptoPassed $ initFromRootState rootState+  where rootState = ChaCha.initialize 20 key nonce+++initFromRootState :: ChaCha.State -> State+initFromRootState rootState = State encState polyState 0 0   where-    rootState           = ChaCha.initialize 20 key nonce     (polyKey, encState) = ChaCha.generate rootState 64     polyState           = throwCryptoError $ Poly1305.initialize (B.take 32 polyKey :: ScrubbedBytes)+++-- | Initialize a new XChaChaPoly1305 State+--+-- The key length needs to be 256 bits, and the nonce+-- procured using `nonce24`.+initializeX :: ByteArrayAccess key+            => key -> XNonce -> CryptoFailable State+initializeX key (Nonce24 nonce)+    | B.length key /= 32 = CryptoFailed CryptoError_KeySizeInvalid+    | otherwise          = CryptoPassed $ initFromRootState rootState+  where rootState = ChaCha.initializeX 20 key nonce+  -- | Append Authenticated Data to the State and return -- the new modified State.
Crypto/Cipher/Types/Block.hs view
@@ -50,7 +50,7 @@ import           Foreign.Storable  -- | an IV parametrized by the cipher-data IV c = forall byteArray . ByteArray byteArray => IV byteArray+data IV c = forall byteArray . ByteArray byteArray => IV !byteArray  instance BlockCipher c => ByteArrayAccess (IV c) where     withByteArray (IV z) f = withByteArray z f
Crypto/Hash/Blake2.hs view
@@ -33,7 +33,8 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} module Crypto.Hash.Blake2-    ( Blake2s(..)+    ( HashBlake2(..)+    , Blake2s(..)     , Blake2sp(..)     , Blake2b(..)     , Blake2bp(..)@@ -46,6 +47,13 @@ import           GHC.TypeLits (Nat, KnownNat) import           Crypto.Internal.Nat +-- | Typeclass for the Blake2 family of digest functions.+class HashAlgorithm a => HashBlake2 a where++    -- | Init Blake2 algorithm with the specified key of the specified length.+    -- The key length is specified in bytes.+    blake2InternalKeyedInit :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO ()+ -- | Fast and secure alternative to SHA1 and HMAC-SHA1 -- -- It is espacially known to target 32bits architectures.@@ -72,8 +80,16 @@     hashInternalUpdate        = c_blake2s_update     hashInternalFinalize p    = c_blake2s_finalize p (integralNatVal (Proxy :: Proxy bitlen)) +instance (IsDivisibleBy8 bitlen, KnownNat bitlen, IsAtLeast bitlen 8, IsAtMost bitlen 256)+      => HashBlake2 (Blake2s bitlen)+      where+    blake2InternalKeyedInit p = c_blake2s_init_key p outLen+        where outLen = integralNatVal (Proxy :: Proxy bitlen)+ foreign import ccall unsafe "crypton_blake2s_init"     c_blake2s_init :: Ptr (Context a) -> Word32 -> IO ()+foreign import ccall unsafe "crypton_blake2s_init_key"+    c_blake2s_init_key :: Ptr (Context a) -> Word32 -> Ptr Word8 -> Word32 -> IO () foreign import ccall "crypton_blake2s_update"     c_blake2s_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "crypton_blake2s_finalize"@@ -107,8 +123,16 @@     hashInternalUpdate        = c_blake2b_update     hashInternalFinalize p    = c_blake2b_finalize p (integralNatVal (Proxy :: Proxy bitlen)) +instance (IsDivisibleBy8 bitlen, KnownNat bitlen, IsAtLeast bitlen 8, IsAtMost bitlen 512)+      => HashBlake2 (Blake2b bitlen)+      where+    blake2InternalKeyedInit p = c_blake2b_init_key p outLen+        where outLen = integralNatVal (Proxy :: Proxy bitlen)+ foreign import ccall unsafe "crypton_blake2b_init"     c_blake2b_init :: Ptr (Context a) -> Word32 -> IO ()+foreign import ccall unsafe "crypton_blake2b_init_key"+    c_blake2b_init_key :: Ptr (Context a) -> Word32 -> Ptr Word8 -> Word32 -> IO () foreign import ccall "crypton_blake2b_update"     c_blake2b_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "crypton_blake2b_finalize"@@ -130,8 +154,16 @@     hashInternalUpdate        = c_blake2sp_update     hashInternalFinalize p    = c_blake2sp_finalize p (integralNatVal (Proxy :: Proxy bitlen)) +instance (IsDivisibleBy8 bitlen, KnownNat bitlen, IsAtLeast bitlen 8, IsAtMost bitlen 256)+      => HashBlake2 (Blake2sp bitlen)+      where+    blake2InternalKeyedInit p = c_blake2sp_init_key p outLen+        where outLen = integralNatVal (Proxy :: Proxy bitlen)+ foreign import ccall unsafe "crypton_blake2sp_init"     c_blake2sp_init :: Ptr (Context a) -> Word32 -> IO ()+foreign import ccall unsafe "crypton_blake2sp_init_key"+    c_blake2sp_init_key :: Ptr (Context a) -> Word32 -> Ptr Word8 -> Word32 -> IO () foreign import ccall "crypton_blake2sp_update"     c_blake2sp_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "crypton_blake2sp_finalize"@@ -153,9 +185,16 @@     hashInternalUpdate        = c_blake2bp_update     hashInternalFinalize p    = c_blake2bp_finalize p (integralNatVal (Proxy :: Proxy bitlen)) +instance (IsDivisibleBy8 bitlen, KnownNat bitlen, IsAtLeast bitlen 8, IsAtMost bitlen 512)+      => HashBlake2 (Blake2bp bitlen)+      where+    blake2InternalKeyedInit p = c_blake2bp_init_key p outLen+        where outLen = integralNatVal (Proxy :: Proxy bitlen)  foreign import ccall unsafe "crypton_blake2bp_init"     c_blake2bp_init :: Ptr (Context a) -> Word32 -> IO ()+foreign import ccall unsafe "crypton_blake2bp_init_key"+    c_blake2bp_init_key :: Ptr (Context a) -> Word32 -> Ptr Word8 -> Word32 -> IO () foreign import ccall "crypton_blake2bp_update"     c_blake2bp_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "crypton_blake2bp_finalize"
+ Crypto/MAC/KeyedBlake2.hs view
@@ -0,0 +1,88 @@+-- |+-- Module      : Crypto.MAC.KeyedBlake2+-- License     : BSD-style+-- Maintainer  : Matthias Valvekens <dev@mvalvekens.be>+-- Stability   : experimental+-- Portability : unknown+--+-- Expose a MAC interface to the keyed Blake2 algorithms+-- defined in RFC 7693.+--+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE ScopedTypeVariables #-}++module Crypto.MAC.KeyedBlake2+    ( HashBlake2+    , KeyedBlake2(..)+    , keyedBlake2+    , keyedBlake2Lazy+    -- * Incremental+    , Context+    , initialize+    , update+    , updates+    , finalize+    ) where++import qualified Crypto.Hash as H+import qualified Crypto.Hash.Types as H+import           Crypto.Hash.Blake2+import           Crypto.Internal.DeepSeq (NFData)+import qualified Data.ByteArray as B+import           Data.ByteArray (ByteArrayAccess)+import qualified Data.ByteString.Lazy as L++import           Foreign.Ptr (Ptr)+++-- Keyed Blake2b++-- | Represent a Blake2b MAC that is a phantom type with the hash used to produce the+-- MAC.+--+-- The Eq instance is constant time.  No Show instance is provided, to avoid+-- printing by mistake.+newtype KeyedBlake2 a = KeyedBlake2 { keyedBlake2GetDigest :: H.Digest a }+    deriving (ByteArrayAccess,NFData)++instance Eq (KeyedBlake2 a) where+    KeyedBlake2 x == KeyedBlake2 y = B.constEq x y++-- | Represent an ongoing Blake2 state, that can be appended with 'update' and+-- finalized to a 'KeyedBlake2' with 'finalize'.+newtype Context a = Context (H.Context a)++-- | Initialize a new incremental keyed Blake2 context with the supplied key.+initialize :: forall a key . (HashBlake2 a, ByteArrayAccess key)+           => key -> Context a+initialize k = Context $ H.Context $ B.allocAndFreeze ctxSz performInit+    where ctxSz = H.hashInternalContextSize (undefined :: a)+          digestSz = H.hashDigestSize (undefined :: a)+          -- cap the number of key bytes at digestSz,+          -- since that's the maximal key size+          keyByteLen = min (B.length k) digestSz+          performInit :: Ptr (H.Context a) -> IO ()+          performInit ptr = B.withByteArray k+            $ \keyPtr -> blake2InternalKeyedInit ptr keyPtr (fromIntegral keyByteLen)++-- | Incrementally update a keyed Blake2 context.+update :: (HashBlake2 a, ByteArrayAccess ba) => Context a -> ba -> Context a+update (Context ctx) = Context . H.hashUpdate ctx++-- | Incrementally update a keyed Blake2 context with multiple inputs.+updates :: (HashBlake2 a, ByteArrayAccess ba) => Context a -> [ba] -> Context a+updates (Context ctx) = Context . H.hashUpdates ctx++-- | Finalize a keyed Blake2 context and return the computed MAC.+finalize :: HashBlake2 a => Context a -> KeyedBlake2 a+finalize (Context ctx) = KeyedBlake2 $ H.hashFinalize ctx++-- | Compute a Blake2 MAC using the supplied key.+keyedBlake2 :: (HashBlake2 a, ByteArrayAccess key, ByteArrayAccess ba)+            => key -> ba -> KeyedBlake2 a+keyedBlake2 key msg = finalize $ update (initialize key) msg++-- | Compute a Blake2 MAC using the supplied key, for a lazy input.+keyedBlake2Lazy :: (HashBlake2 a, ByteArrayAccess key)+            => key -> L.ByteString -> KeyedBlake2 a+keyedBlake2Lazy key msg = finalize $ updates (initialize key) (L.toChunks msg)
Crypto/Random.hs view
@@ -37,6 +37,7 @@ import Data.ByteArray (ByteArray, ByteArrayAccess, ScrubbedBytes) import qualified Data.ByteArray as B import Crypto.Internal.Imports+import Crypto.Hash (Digest, SHA512, hash)  import qualified Crypto.Number.Serialize as Serialize @@ -49,7 +50,13 @@  -- | Create a new Seed from system entropy seedNew :: MonadRandom randomly => randomly Seed-seedNew = Seed `fmap` getRandomBytes seedLength+-- The degree of its randomness depends on the source, e.g. for iOS we+-- have to compile with DoNotUseEntropy flag, as iOS doesn't allow+-- using getentropy, and on some other systems it can be also+-- potentially comprisable sources. Hashing of entropy before using+-- it as a seed is a common mitigation for attacks via RNG/entropy+-- source.+seedNew = (Seed . B.take seedLength . B.convert . (hash :: ScrubbedBytes -> Digest SHA512)) `fmap` getRandomBytes 64  -- | Convert a Seed to an integer seedToInteger :: Seed -> Integer
README.md view
@@ -29,10 +29,6 @@ Next version of `0.x` is `0.(x+1)`. There's no exceptions, or API related meaning behind the numbers. -Each versions of stackage (going back 3 stable LTS) has a crypton version-that we maintain with security fixes when necessary and are versioned with the-following `0.x.y` scheme.- Coding Style ------------ 
cbits/crypton_blake2b.c view
@@ -5,6 +5,11 @@ 	_crypton_blake2b_init(ctx, hashlen / 8); } +void crypton_blake2b_init_key(blake2b_ctx *ctx, uint32_t hashlen, const uint8_t *key, size_t keylen)+{+	_crypton_blake2b_init_key(ctx, hashlen / 8, (const void *) key, keylen);+}+ void crypton_blake2b_update(blake2b_ctx *ctx, const uint8_t *data, uint32_t len) { 	_crypton_blake2b_update(ctx, data, len);
cbits/crypton_blake2b.h view
@@ -6,6 +6,7 @@ typedef blake2b_state blake2b_ctx;  void crypton_blake2b_init(blake2b_ctx *ctx, uint32_t hashlen);+void crypton_blake2b_init_key(blake2b_ctx *ctx, uint32_t hashlen, const uint8_t *key, size_t keylen); void crypton_blake2b_update(blake2b_ctx *ctx, const uint8_t *data, uint32_t len); void crypton_blake2b_finalize(blake2b_ctx *ctx, uint32_t hashlen, uint8_t *out); 
cbits/crypton_blake2bp.c view
@@ -5,6 +5,11 @@ 	_crypton_blake2bp_init(ctx, hashlen / 8); } +void crypton_blake2bp_init_key(blake2bp_ctx *ctx, uint32_t hashlen, const uint8_t *key, size_t keylen)+{+	_crypton_blake2bp_init_key(ctx, hashlen / 8, (const void *) key, keylen);+}+ void crypton_blake2bp_update(blake2bp_ctx *ctx, const uint8_t *data, uint32_t len) { 	_crypton_blake2bp_update(ctx, data, len);
cbits/crypton_blake2bp.h view
@@ -6,6 +6,7 @@ typedef blake2bp_state blake2bp_ctx;  void crypton_blake2bp_init(blake2bp_ctx *ctx, uint32_t hashlen);+void crypton_blake2bp_init_key(blake2bp_ctx *ctx, uint32_t hashlen, const uint8_t *key, size_t keylen); void crypton_blake2bp_update(blake2bp_ctx *ctx, const uint8_t *data, uint32_t len); void crypton_blake2bp_finalize(blake2bp_ctx *ctx, uint32_t hashlen, uint8_t *out); 
cbits/crypton_blake2s.c view
@@ -5,6 +5,11 @@ 	_crypton_blake2s_init(ctx, hashlen / 8); } +void crypton_blake2s_init_key(blake2s_ctx *ctx, uint32_t hashlen, const uint8_t *key, size_t keylen)+{+	_crypton_blake2s_init_key(ctx, hashlen / 8, (const void *) key, keylen);+}+ void crypton_blake2s_update(blake2s_ctx *ctx, const uint8_t *data, uint32_t len) { 	_crypton_blake2s_update(ctx, data, len);
cbits/crypton_blake2s.h view
@@ -6,6 +6,7 @@ typedef blake2s_state blake2s_ctx;  void crypton_blake2s_init(blake2s_ctx *ctx, uint32_t hashlen);+void crypton_blake2s_init_key(blake2s_ctx *ctx, uint32_t hashlen, const uint8_t *key, size_t keylen); void crypton_blake2s_update(blake2s_ctx *ctx, const uint8_t *data, uint32_t len); void crypton_blake2s_finalize(blake2s_ctx *ctx, uint32_t hashlen, uint8_t *out); 
cbits/crypton_blake2sp.c view
@@ -5,6 +5,11 @@ 	_crypton_blake2sp_init(ctx, hashlen / 8); } +void crypton_blake2sp_init_key(blake2sp_ctx *ctx, uint32_t hashlen, const uint8_t *key, size_t keylen)+{+	_crypton_blake2sp_init_key(ctx, hashlen / 8, (const void *) key, keylen);+}+ void crypton_blake2sp_update(blake2sp_ctx *ctx, const uint8_t *data, uint32_t len) { 	_crypton_blake2sp_update(ctx, data, len);
cbits/crypton_blake2sp.h view
@@ -6,6 +6,7 @@ typedef blake2sp_state blake2sp_ctx;  void crypton_blake2sp_init(blake2sp_ctx *ctx, uint32_t hashlen);+void crypton_blake2sp_init_key(blake2sp_ctx *ctx, uint32_t hashlen, const uint8_t *key, size_t keylen); void crypton_blake2sp_update(blake2sp_ctx *ctx, const uint8_t *data, uint32_t len); void crypton_blake2sp_finalize(blake2sp_ctx *ctx, uint32_t hashlen, uint8_t *out); 
cbits/crypton_chacha.c view
@@ -92,11 +92,44 @@ 	out->d[15] = cpu_to_le32(x15); } -/* only 2 valids values are 256 (32) and 128 (16) */-void crypton_chacha_init_core(crypton_chacha_state *st,-                                 uint32_t keylen, const uint8_t *key,-                                 uint32_t ivlen, const uint8_t *iv)+static void hchacha_core(int rounds, uint32_t *out, const crypton_chacha_state *in) {+	uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;+	int i;++	x0 = in->d[0]; x1 = in->d[1]; x2 = in->d[2]; x3 = in->d[3];+	x4 = in->d[4]; x5 = in->d[5]; x6 = in->d[6]; x7 = in->d[7];+	x8 = in->d[8]; x9 = in->d[9]; x10 = in->d[10]; x11 = in->d[11];+	x12 = in->d[12]; x13 = in->d[13]; x14 = in->d[14]; x15 = in->d[15];++	for (i = rounds; i > 0; i -= 2) {+		QR(x0, x4, x8, x12);+		QR(x1, x5, x9, x13);+		QR(x2, x6, x10, x14);+		QR(x3, x7, x11, x15);++		QR(x0, x5, x10, x15);+		QR(x1, x6, x11, x12);+		QR(x2, x7, x8, x13);+		QR(x3, x4, x9, x14);+	}++	/* HChaCha doesn't perform the final addition */++	out[0] = cpu_to_le32(x0);+	out[1] = cpu_to_le32(x1);+	out[2] = cpu_to_le32(x2);+	out[3] = cpu_to_le32(x3);+	out[4] = cpu_to_le32(x12);+	out[5] = cpu_to_le32(x13);+	out[6] = cpu_to_le32(x14);+	out[7] = cpu_to_le32(x15);+}++/* Common initialization logic for ChaCha20 and HChaCha20 */+static void chacha_init_key_state(crypton_chacha_state *st,+                                  uint32_t keylen, const uint8_t *key)+{ 	const uint8_t *constants = (keylen == 32) ? sigma : tau;  	ASSERT_ALIGNMENT(constants, 4);@@ -117,6 +150,14 @@ 	st->d[9] = load_le32(key + 4); 	st->d[10] = load_le32(key + 8); 	st->d[11] = load_le32(key + 12);+}++/* only 2 valids values are 256 (32) and 128 (16) */+void crypton_chacha_init_core(crypton_chacha_state *st,+                              uint32_t keylen, const uint8_t *key,+                              uint32_t ivlen, const uint8_t *iv)+{+	chacha_init_key_state(st, keylen, key); 	st->d[12] = 0; 	switch (ivlen) { 	case 8:@@ -133,6 +174,19 @@ 	} } +void crypton_hchacha_init_core(crypton_chacha_state *st,+                                  const uint8_t *key,+                                  const uint8_t *iv)+{+	/* keylen is always 32 here */+	chacha_init_key_state(st, 32, key);+	/* fill the last 4 uint32s with the 128-bit nonce */+	st->d[12] = load_le32(iv + 0);+	st->d[13] = load_le32(iv + 4);+	st->d[14] = load_le32(iv + 8);+	st->d[15] = load_le32(iv + 12);+}+ void crypton_chacha_init(crypton_chacha_context *ctx, uint8_t nb_rounds,                             uint32_t keylen, const uint8_t *key,                             uint32_t ivlen, const uint8_t *iv)@@ -141,6 +195,39 @@ 	ctx->nb_rounds = nb_rounds; 	crypton_chacha_init_core(&ctx->st, keylen, key, ivlen, iv); }++void crypton_hchacha(uint8_t nb_rounds, const uint8_t *keyin, const uint8_t *iv,+                        uint8_t *keyout)+{+	crypton_chacha_state st;++	crypton_hchacha_init_core(&st, keyin, iv);+	/* output to uint32_t* and do a memcpy to avoid+	   violating the strict aliasing rule */+	uint32_t keyout32[8];+	hchacha_core(nb_rounds, keyout32, &st);+	memset(&st, 0, sizeof(st));+	memcpy(keyout, keyout32, 32);++	memset(keyout32, 0, 32);+}++/* XChaCha: 256-bit key, 192-bit nonce version of ChaCha.*/+void crypton_xchacha_init(crypton_chacha_context *ctx, uint8_t nb_rounds,+                             const uint8_t *key, const uint8_t *iv)+{+	memset(ctx, 0, sizeof(*ctx));+	ctx->nb_rounds = nb_rounds;++	/* perform HChaCha with the key and the first 16 bytes of the nonce+	to get the subkey */+	uint8_t subkey[32];+	crypton_hchacha(nb_rounds, key, iv, subkey);+	/* perform regular ChaCha with the generated subkey and the last 8 bytes+	of the input IV */+	crypton_chacha_init_core(&ctx->st, 32, subkey, 8, iv + 16);+}+  void crypton_chacha_combine(uint8_t *dst, crypton_chacha_context *ctx, const uint8_t *src, uint32_t bytes) {
cbits/crypton_chacha.h view
@@ -48,6 +48,7 @@  void crypton_chacha_init_core(crypton_chacha_state *st, uint32_t keylen, const uint8_t *key, uint32_t ivlen, const uint8_t *iv); void crypton_chacha_init(crypton_chacha_context *ctx, uint8_t nb_rounds, uint32_t keylen, const uint8_t *key, uint32_t ivlen, const uint8_t *iv);+void crypton_xchacha_init(crypton_chacha_context *ctx, uint8_t nb_rounds, const uint8_t *key, const uint8_t *iv); void crypton_chacha_combine(uint8_t *dst, crypton_chacha_context *st, const uint8_t *src, uint32_t bytes); void crypton_chacha_generate(uint8_t *dst, crypton_chacha_context *st, uint32_t bytes); 
crypton.cabal view
@@ -1,7 +1,17 @@-Name:                crypton-version:             0.33-Synopsis:            Cryptography Primitives sink-Description:+cabal-version:      1.18+name:               crypton+version:            0.34+license:            BSD3+license-file:       LICENSE+copyright:          Vincent Hanquez <vincent@snarc.org>+maintainer:         Kazu Yamamoto <kazu@iij.ad.jp>+author:             Vincent Hanquez <vincent@snarc.org>+stability:          experimental+tested-with:        ghc ==9.2.2 ghc ==9.0.2 ghc ==8.10.7 ghc ==8.8.4+homepage:           https://github.com/kazu-yamamoto/crypton+bug-reports:        https://github.com/kazu-yamamoto/crypton/issues+synopsis:           Cryptography Primitives sink+description:     A repository of cryptographic primitives.     .     * Symmetric ciphers: AES, DES, 3DES, CAST5, Blowfish, Twofish, Camellia, RC4, Salsa, XSalsa, ChaCha.@@ -25,463 +35,495 @@     Evaluate the security related to your requirements before using.     .     Read "Crypto.Tutorial" for a quick start guide.-License:             BSD3-License-file:        LICENSE-Copyright:           Vincent Hanquez <vincent@snarc.org>-Author:              Vincent Hanquez <vincent@snarc.org>-Maintainer:          Kazu Yamamoto <kazu@iij.ad.jp>-Category:            Cryptography-Stability:           experimental-Build-Type:          Simple-Homepage:            https://github.com/kazu-yamamoto/crypton-Bug-reports:         https://github.com/kazu-yamamoto/crypton/issues-Cabal-Version:       1.18-tested-with:         GHC==9.2.2, GHC==9.0.2, GHC==8.10.7, GHC==8.8.4-extra-doc-files:     README.md CHANGELOG.md-extra-source-files:  cbits/*.h-                     cbits/aes/*.h-                     cbits/ed25519/*.h-                     cbits/decaf/include/*.h-                     cbits/decaf/include/decaf/*.h-                     cbits/decaf/include/arch_32/*.h-                     cbits/decaf/include/arch_ref64/*.h-                     cbits/decaf/p448/arch_32/*.h-                     cbits/decaf/p448/arch_ref64/*.h-                     cbits/decaf/p448/*.h-                     cbits/decaf/ed448goldilocks/decaf_tables.c-                     cbits/decaf/ed448goldilocks/decaf.c-                     cbits/include32/p256/*.h-                     cbits/include64/p256/*.h-                     cbits/blake2/ref/*.h-                     cbits/blake2/sse/*.h-                     cbits/argon2/*.h-                     cbits/argon2/*.c-                     cbits/aes/x86ni_impl.c-                     cbits/crypton_hash_prefix.c-                     tests/*.hs +category:           Cryptography+build-type:         Simple+extra-source-files:+    cbits/*.h+    cbits/aes/*.h+    cbits/ed25519/*.h+    cbits/decaf/include/*.h+    cbits/decaf/include/decaf/*.h+    cbits/decaf/include/arch_32/*.h+    cbits/decaf/include/arch_ref64/*.h+    cbits/decaf/p448/arch_32/*.h+    cbits/decaf/p448/arch_ref64/*.h+    cbits/decaf/p448/*.h+    cbits/decaf/ed448goldilocks/decaf_tables.c+    cbits/decaf/ed448goldilocks/decaf.c+    cbits/include32/p256/*.h+    cbits/include64/p256/*.h+    cbits/blake2/ref/*.h+    cbits/blake2/sse/*.h+    cbits/argon2/*.h+    cbits/argon2/*.c+    cbits/aes/x86ni_impl.c+    cbits/crypton_hash_prefix.c+    tests/*.hs++extra-doc-files:+    README.md+    CHANGELOG.md+ source-repository head-  type: git-  location: https://github.com/kazu-yamamoto/crypton+    type:     git+    location: https://github.com/kazu-yamamoto/crypton -Flag support_aesni-  Description:       allow compilation with AESNI on system and architecture that supports it-  Default:           True-  Manual:            True+flag support_aesni+    description:+        allow compilation with AESNI on system and architecture that supports it -Flag support_rdrand-  Description:       allow compilation with RDRAND on system and architecture that supports it-  Default:           True-  Manual:            True+    manual:      True -Flag support_pclmuldq-  Description:       Allow compilation with pclmuldq on architecture that supports it-  Default:           True-  Manual:            True+flag support_rdrand+    description:+        allow compilation with RDRAND on system and architecture that supports it -Flag support_sse-  Description:       Use SSE optimized version of (BLAKE2, ARGON2)-  Default:           False-  Manual:            True+    manual:      True -Flag integer-gmp-  Description:       Whether or not to use GMP for some functions-  Default:           True-  Manual:            True+flag support_pclmuldq+    description:+        Allow compilation with pclmuldq on architecture that supports it -Flag support_deepseq-  Description:       add deepseq instances for cryptographic types-  Default:           True-  Manual:            True+    manual:      True -Flag old_toolchain_inliner-  Description:       use -fgnu89-inline to workaround an old compiler / linker / glibc issue.-  Default:           False-  Manual:            True+flag support_sse+    description: Use SSE optimized version of (BLAKE2, ARGON2)+    default:     False+    manual:      True -Flag check_alignment-  Description:       extra check on alignment in C layers, which cause lowlevel assert errors. for debugging only.-  Default:           False-  Manual:            True+flag integer-gmp+    description: Whether or not to use GMP for some functions+    manual:      True -Flag use_target_attributes-  Description:       use GCC / clang function attributes instead of global target options.-  Default:           True-  Manual:            True+flag support_deepseq+    description: add deepseq instances for cryptographic types+    manual:      True -Library-  Exposed-modules:   Crypto.Cipher.AES-                     Crypto.Cipher.AESGCMSIV-                     Crypto.Cipher.Blowfish-                     Crypto.Cipher.CAST5-                     Crypto.Cipher.Camellia-                     Crypto.Cipher.ChaCha-                     Crypto.Cipher.ChaChaPoly1305-                     Crypto.Cipher.DES-                     Crypto.Cipher.RC4-                     Crypto.Cipher.Salsa-                     Crypto.Cipher.TripleDES-                     Crypto.Cipher.Twofish-                     Crypto.Cipher.Types-                     Crypto.Cipher.Utils-                     Crypto.Cipher.XSalsa-                     Crypto.ConstructHash.MiyaguchiPreneel-                     Crypto.Data.AFIS-                     Crypto.Data.Padding-                     Crypto.ECC-                     Crypto.ECC.Edwards25519-                     Crypto.Error-                     Crypto.MAC.CMAC-                     Crypto.MAC.Poly1305-                     Crypto.MAC.HMAC-                     Crypto.MAC.KMAC-                     Crypto.Number.Basic-                     Crypto.Number.F2m-                     Crypto.Number.Generate-                     Crypto.Number.ModArithmetic-                     Crypto.Number.Nat-                     Crypto.Number.Prime-                     Crypto.Number.Serialize-                     Crypto.Number.Serialize.LE-                     Crypto.Number.Serialize.Internal-                     Crypto.Number.Serialize.Internal.LE-                     Crypto.KDF.Argon2-                     Crypto.KDF.PBKDF2-                     Crypto.KDF.Scrypt-                     Crypto.KDF.BCrypt-                     Crypto.KDF.BCryptPBKDF-                     Crypto.KDF.HKDF-                     Crypto.Hash-                     Crypto.Hash.IO-                     Crypto.Hash.Algorithms-                     Crypto.OTP-                     Crypto.PubKey.Curve25519-                     Crypto.PubKey.Curve448-                     Crypto.PubKey.MaskGenFunction-                     Crypto.PubKey.DH-                     Crypto.PubKey.DSA-                     Crypto.PubKey.ECC.Generate-                     Crypto.PubKey.ECC.Prim-                     Crypto.PubKey.ECC.DH-                     Crypto.PubKey.ECC.ECDSA-                     Crypto.PubKey.ECC.P256-                     Crypto.PubKey.ECC.Types-                     Crypto.PubKey.ECDSA-                     Crypto.PubKey.ECIES-                     Crypto.PubKey.Ed25519-                     Crypto.PubKey.Ed448-                     Crypto.PubKey.EdDSA-                     Crypto.PubKey.RSA-                     Crypto.PubKey.RSA.PKCS15-                     Crypto.PubKey.RSA.Prim-                     Crypto.PubKey.RSA.PSS-                     Crypto.PubKey.RSA.OAEP-                     Crypto.PubKey.RSA.Types-                     Crypto.PubKey.Rabin.OAEP-                     Crypto.PubKey.Rabin.Basic-                     Crypto.PubKey.Rabin.Modified-                     Crypto.PubKey.Rabin.RW-                     Crypto.PubKey.Rabin.Types-                     Crypto.Random-                     Crypto.Random.Types-                     Crypto.Random.Entropy-                     Crypto.Random.EntropyPool-                     Crypto.Random.Entropy.Unsafe-                     Crypto.System.CPU-                     Crypto.Tutorial-  Other-modules:     Crypto.Cipher.AES.Primitive-                     Crypto.Cipher.Blowfish.Box-                     Crypto.Cipher.Blowfish.Primitive-                     Crypto.Cipher.CAST5.Primitive-                     Crypto.Cipher.Camellia.Primitive-                     Crypto.Cipher.DES.Primitive-                     Crypto.Cipher.Twofish.Primitive-                     Crypto.Cipher.Types.AEAD-                     Crypto.Cipher.Types.Base-                     Crypto.Cipher.Types.Block-                     Crypto.Cipher.Types.GF-                     Crypto.Cipher.Types.Stream-                     Crypto.Cipher.Types.Utils-                     Crypto.Error.Types-                     Crypto.Number.Compat-                     Crypto.Hash.Types-                     Crypto.Hash.Blake2-                     Crypto.Hash.Blake2s-                     Crypto.Hash.Blake2sp-                     Crypto.Hash.Blake2b-                     Crypto.Hash.Blake2bp-                     Crypto.Hash.SHA1-                     Crypto.Hash.SHA224-                     Crypto.Hash.SHA256-                     Crypto.Hash.SHA384-                     Crypto.Hash.SHA512-                     Crypto.Hash.SHA512t-                     Crypto.Hash.SHA3-                     Crypto.Hash.SHAKE-                     Crypto.Hash.Keccak-                     Crypto.Hash.MD2-                     Crypto.Hash.MD4-                     Crypto.Hash.MD5-                     Crypto.Hash.RIPEMD160-                     Crypto.Hash.Skein256-                     Crypto.Hash.Skein512-                     Crypto.Hash.Tiger-                     Crypto.Hash.Whirlpool-                     Crypto.Random.Entropy.Source-                     Crypto.Random.Entropy.Backend-                     Crypto.Random.ChaChaDRG-                     Crypto.Random.SystemDRG-                     Crypto.Random.Probabilistic-                     Crypto.PubKey.Internal-                     Crypto.PubKey.ElGamal-                     Crypto.ECC.Simple.Types-                     Crypto.ECC.Simple.Prim-                     Crypto.Internal.Builder-                     Crypto.Internal.ByteArray-                     Crypto.Internal.Compat-                     Crypto.Internal.CompatPrim-                     Crypto.Internal.DeepSeq-                     Crypto.Internal.Imports-                     Crypto.Internal.Nat-                     Crypto.Internal.Words-                     Crypto.Internal.WordArray-  if impl(ghc < 8.8)-    Buildable: False-  else-    Build-depends:   base+flag old_toolchain_inliner+    description:+        use -fgnu89-inline to workaround an old compiler / linker / glibc issue. -  Build-depends:     bytestring-                   , memory >= 0.14.18-                   , basement >= 0.0.6-                   , ghc-prim-  ghc-options:       -Wall -fwarn-tabs -optc-O3-  if os(linux)-    extra-libraries: pthread-  default-language:  Haskell2010-  cc-options:        -std=gnu99-  if flag(old_toolchain_inliner)-    cc-options:      -fgnu89-inline-  C-sources:         cbits/crypton_chacha.c-                   , cbits/crypton_salsa.c-                   , cbits/crypton_xsalsa.c-                   , cbits/crypton_rc4.c-                   , cbits/crypton_cpu.c-                   , cbits/p256/p256.c-                   , cbits/p256/p256_ec.c-                   , cbits/crypton_blake2s.c-                   , cbits/crypton_blake2sp.c-                   , cbits/crypton_blake2b.c-                   , cbits/crypton_blake2bp.c-                   , cbits/crypton_poly1305.c-                   , cbits/crypton_sha1.c-                   , cbits/crypton_sha256.c-                   , cbits/crypton_sha512.c-                   , cbits/crypton_sha3.c-                   , cbits/crypton_md2.c-                   , cbits/crypton_md4.c-                   , cbits/crypton_md5.c-                   , cbits/crypton_ripemd.c-                   , cbits/crypton_skein256.c-                   , cbits/crypton_skein512.c-                   , cbits/crypton_tiger.c-                   , cbits/crypton_whirlpool.c-                   , cbits/crypton_scrypt.c-                   , cbits/crypton_pbkdf2.c-                   , cbits/ed25519/ed25519.c-  include-dirs:      cbits-                   , cbits/ed25519-                   , cbits/decaf/include-                   , cbits/decaf/p448+    default:     False+    manual:      True -  if arch(x86_64) || arch(aarch64)-    include-dirs:      cbits/include64-  else-    include-dirs:      cbits/include32+flag check_alignment+    description:+        extra check on alignment in C layers, which cause lowlevel assert errors. for debugging only. -  if arch(x86_64) || arch(aarch64)-    C-sources:         cbits/decaf/p448/arch_ref64/f_impl.c-                     , cbits/decaf/p448/f_generic.c-                     , cbits/decaf/p448/f_arithmetic.c-                     , cbits/decaf/utils.c-                     , cbits/decaf/ed448goldilocks/scalar.c-                     , cbits/decaf/ed448goldilocks/decaf_all.c-                     , cbits/decaf/ed448goldilocks/eddsa.c+    default:     False+    manual:      True -    include-dirs:      cbits/decaf/include/arch_ref64-                     , cbits/decaf/p448/arch_ref64-  else-    C-sources:         cbits/decaf/p448/arch_32/f_impl.c-                     , cbits/decaf/p448/f_generic.c-                     , cbits/decaf/p448/f_arithmetic.c-                     , cbits/decaf/utils.c-                     , cbits/decaf/ed448goldilocks/scalar.c-                     , cbits/decaf/ed448goldilocks/decaf_all.c-                     , cbits/decaf/ed448goldilocks/eddsa.c+flag use_target_attributes+    description:+        use GCC / clang function attributes instead of global target options. -    include-dirs:      cbits/decaf/include/arch_32-                     , cbits/decaf/p448/arch_32+    manual:      True -  if arch(x86_64) || arch(aarch64)-    C-sources: cbits/curve25519/curve25519-donna-c64.c-  else-    C-sources: cbits/curve25519/curve25519-donna.c+library+    exposed-modules:+        Crypto.Cipher.AES+        Crypto.Cipher.AESGCMSIV+        Crypto.Cipher.Blowfish+        Crypto.Cipher.CAST5+        Crypto.Cipher.Camellia+        Crypto.Cipher.ChaCha+        Crypto.Cipher.ChaChaPoly1305+        Crypto.Cipher.DES+        Crypto.Cipher.RC4+        Crypto.Cipher.Salsa+        Crypto.Cipher.TripleDES+        Crypto.Cipher.Twofish+        Crypto.Cipher.Types+        Crypto.Cipher.Utils+        Crypto.Cipher.XSalsa+        Crypto.ConstructHash.MiyaguchiPreneel+        Crypto.Data.AFIS+        Crypto.Data.Padding+        Crypto.ECC+        Crypto.ECC.Edwards25519+        Crypto.Error+        Crypto.MAC.CMAC+        Crypto.MAC.Poly1305+        Crypto.MAC.HMAC+        Crypto.MAC.KeyedBlake2+        Crypto.MAC.KMAC+        Crypto.Number.Basic+        Crypto.Number.F2m+        Crypto.Number.Generate+        Crypto.Number.ModArithmetic+        Crypto.Number.Nat+        Crypto.Number.Prime+        Crypto.Number.Serialize+        Crypto.Number.Serialize.LE+        Crypto.Number.Serialize.Internal+        Crypto.Number.Serialize.Internal.LE+        Crypto.KDF.Argon2+        Crypto.KDF.PBKDF2+        Crypto.KDF.Scrypt+        Crypto.KDF.BCrypt+        Crypto.KDF.BCryptPBKDF+        Crypto.KDF.HKDF+        Crypto.Hash+        Crypto.Hash.IO+        Crypto.Hash.Algorithms+        Crypto.OTP+        Crypto.PubKey.Curve25519+        Crypto.PubKey.Curve448+        Crypto.PubKey.MaskGenFunction+        Crypto.PubKey.DH+        Crypto.PubKey.DSA+        Crypto.PubKey.ECC.Generate+        Crypto.PubKey.ECC.Prim+        Crypto.PubKey.ECC.DH+        Crypto.PubKey.ECC.ECDSA+        Crypto.PubKey.ECC.P256+        Crypto.PubKey.ECC.Types+        Crypto.PubKey.ECDSA+        Crypto.PubKey.ECIES+        Crypto.PubKey.Ed25519+        Crypto.PubKey.Ed448+        Crypto.PubKey.EdDSA+        Crypto.PubKey.RSA+        Crypto.PubKey.RSA.PKCS15+        Crypto.PubKey.RSA.Prim+        Crypto.PubKey.RSA.PSS+        Crypto.PubKey.RSA.OAEP+        Crypto.PubKey.RSA.Types+        Crypto.PubKey.Rabin.OAEP+        Crypto.PubKey.Rabin.Basic+        Crypto.PubKey.Rabin.Modified+        Crypto.PubKey.Rabin.RW+        Crypto.PubKey.Rabin.Types+        Crypto.Random+        Crypto.Random.Types+        Crypto.Random.Entropy+        Crypto.Random.EntropyPool+        Crypto.Random.Entropy.Unsafe+        Crypto.System.CPU+        Crypto.Tutorial -  -- FIXME armel or mispel is also little endian.-  -- might be a good idea to also add a runtime autodetect mode.-  -- ARCH_ENDIAN_UNKNOWN-  if (arch(i386) || arch(x86_64))-    CPP-options: -DARCH_IS_LITTLE_ENDIAN+    cc-options:       -std=gnu99+    c-sources:+        cbits/crypton_chacha.c+        cbits/crypton_salsa.c+        cbits/crypton_xsalsa.c+        cbits/crypton_rc4.c+        cbits/crypton_cpu.c+        cbits/p256/p256.c+        cbits/p256/p256_ec.c+        cbits/crypton_blake2s.c+        cbits/crypton_blake2sp.c+        cbits/crypton_blake2b.c+        cbits/crypton_blake2bp.c+        cbits/crypton_poly1305.c+        cbits/crypton_sha1.c+        cbits/crypton_sha256.c+        cbits/crypton_sha512.c+        cbits/crypton_sha3.c+        cbits/crypton_md2.c+        cbits/crypton_md4.c+        cbits/crypton_md5.c+        cbits/crypton_ripemd.c+        cbits/crypton_skein256.c+        cbits/crypton_skein512.c+        cbits/crypton_tiger.c+        cbits/crypton_whirlpool.c+        cbits/crypton_scrypt.c+        cbits/crypton_pbkdf2.c+        cbits/ed25519/ed25519.c+        cbits/argon2/argon2.c -  if arch(i386)-    CPP-options: -DARCH_X86+    other-modules:+        Crypto.Cipher.AES.Primitive+        Crypto.Cipher.Blowfish.Box+        Crypto.Cipher.Blowfish.Primitive+        Crypto.Cipher.CAST5.Primitive+        Crypto.Cipher.Camellia.Primitive+        Crypto.Cipher.DES.Primitive+        Crypto.Cipher.Twofish.Primitive+        Crypto.Cipher.Types.AEAD+        Crypto.Cipher.Types.Base+        Crypto.Cipher.Types.Block+        Crypto.Cipher.Types.GF+        Crypto.Cipher.Types.Stream+        Crypto.Cipher.Types.Utils+        Crypto.Error.Types+        Crypto.Number.Compat+        Crypto.Hash.Types+        Crypto.Hash.Blake2+        Crypto.Hash.Blake2s+        Crypto.Hash.Blake2sp+        Crypto.Hash.Blake2b+        Crypto.Hash.Blake2bp+        Crypto.Hash.SHA1+        Crypto.Hash.SHA224+        Crypto.Hash.SHA256+        Crypto.Hash.SHA384+        Crypto.Hash.SHA512+        Crypto.Hash.SHA512t+        Crypto.Hash.SHA3+        Crypto.Hash.SHAKE+        Crypto.Hash.Keccak+        Crypto.Hash.MD2+        Crypto.Hash.MD4+        Crypto.Hash.MD5+        Crypto.Hash.RIPEMD160+        Crypto.Hash.Skein256+        Crypto.Hash.Skein512+        Crypto.Hash.Tiger+        Crypto.Hash.Whirlpool+        Crypto.Random.Entropy.Source+        Crypto.Random.Entropy.Backend+        Crypto.Random.ChaChaDRG+        Crypto.Random.SystemDRG+        Crypto.Random.Probabilistic+        Crypto.PubKey.Internal+        Crypto.PubKey.ElGamal+        Crypto.ECC.Simple.Types+        Crypto.ECC.Simple.Prim+        Crypto.Internal.Builder+        Crypto.Internal.ByteArray+        Crypto.Internal.Compat+        Crypto.Internal.CompatPrim+        Crypto.Internal.DeepSeq+        Crypto.Internal.Imports+        Crypto.Internal.Nat+        Crypto.Internal.Words+        Crypto.Internal.WordArray -  if arch(x86_64)-    CPP-options: -DARCH_X86_64+    default-language: Haskell2010+    include-dirs:+        cbits cbits/ed25519 cbits/decaf/include cbits/decaf/p448+        cbits/argon2 -  if flag(support_rdrand) && (arch(i386) || arch(x86_64)) && !os(windows)-    CPP-options:    -DSUPPORT_RDRAND-    Other-modules:  Crypto.Random.Entropy.RDRand-    c-sources:      cbits/crypton_rdrand.c+    ghc-options:      -Wall -fwarn-tabs -optc-O3+    build-depends:+        bytestring,+        memory >=0.14.18,+        basement >=0.0.6,+        ghc-prim -  if flag(support_aesni) && (os(linux) || os(freebsd) || os(osx)) && (arch(i386) || arch(x86_64))-    CC-options:     -DWITH_AESNI-    if !flag(use_target_attributes)-      CC-options:     -mssse3 -maes-    if flag(support_pclmuldq)-      CC-options:   -DWITH_PCLMUL-      if !flag(use_target_attributes)-        CC-options:     -msse4.1 -mpclmul-    C-sources:       cbits/aes/x86ni.c-                   , cbits/aes/generic.c-                   , cbits/aes/gf.c-                   , cbits/crypton_aes.c-  else-    C-sources:       cbits/aes/generic.c-                   , cbits/aes/gf.c-                   , cbits/crypton_aes.c+    if impl(ghc <8.8)+        buildable: False -  if arch(x86_64) || flag(support_sse)-    C-sources:      cbits/blake2/sse/blake2s.c-                  , cbits/blake2/sse/blake2sp.c-                  , cbits/blake2/sse/blake2b.c-                  , cbits/blake2/sse/blake2bp.c-    include-dirs: cbits/blake2/sse-  else-    C-sources:      cbits/blake2/ref/blake2s-ref.c-                  , cbits/blake2/ref/blake2sp-ref.c-                  , cbits/blake2/ref/blake2b-ref.c-                  , cbits/blake2/ref/blake2bp-ref.c-    include-dirs: cbits/blake2/ref+    else+        build-depends: base -  if arch(x86_64) || flag(support_sse)-    CPP-options:    -DSUPPORT_SSE+    if os(linux)+        extra-libraries: pthread++    if flag(old_toolchain_inliner)+        cc-options: -fgnu89-inline++    if (arch(x86_64) || arch(aarch64))+        include-dirs: cbits/include64++    else+        include-dirs: cbits/include32++    if (arch(x86_64) || arch(aarch64))+        c-sources:+            cbits/decaf/p448/arch_ref64/f_impl.c+            cbits/decaf/p448/f_generic.c+            cbits/decaf/p448/f_arithmetic.c+            cbits/decaf/utils.c+            cbits/decaf/ed448goldilocks/scalar.c+            cbits/decaf/ed448goldilocks/decaf_all.c+            cbits/decaf/ed448goldilocks/eddsa.c++        include-dirs: cbits/decaf/include/arch_ref64 cbits/decaf/p448/arch_ref64++    else+        c-sources:+            cbits/decaf/p448/arch_32/f_impl.c+            cbits/decaf/p448/f_generic.c+            cbits/decaf/p448/f_arithmetic.c+            cbits/decaf/utils.c+            cbits/decaf/ed448goldilocks/scalar.c+            cbits/decaf/ed448goldilocks/decaf_all.c+            cbits/decaf/ed448goldilocks/eddsa.c++        include-dirs: cbits/decaf/include/arch_32 cbits/decaf/p448/arch_32++    if (arch(x86_64) || arch(aarch64))+        c-sources: cbits/curve25519/curve25519-donna-c64.c++    else+        c-sources: cbits/curve25519/curve25519-donna.c++    if (arch(i386) || arch(x86_64))+        cpp-options: -DARCH_IS_LITTLE_ENDIAN+     if arch(i386)-      CC-options:   -msse2+        cpp-options: -DARCH_X86 -  C-sources:      cbits/argon2/argon2.c-  include-dirs:   cbits/argon2+    if arch(x86_64)+        cpp-options: -DARCH_X86_64 -  if os(windows)-    cpp-options:    -DWINDOWS-    Build-Depends:  Win32-    Other-modules:  Crypto.Random.Entropy.Windows-    extra-libraries: advapi32-  else-    Other-modules:  Crypto.Random.Entropy.Unix+    if ((flag(support_rdrand) && (arch(i386) || arch(x86_64))) && !os(windows))+        cpp-options:   -DSUPPORT_RDRAND+        c-sources:     cbits/crypton_rdrand.c+        other-modules: Crypto.Random.Entropy.RDRand -  if impl(ghc) && flag(integer-gmp)-    Build-depends:   integer-gmp+    if ((flag(support_aesni) && ((os(linux) || os(freebsd)) || os(osx))) && (arch(i386) || arch(x86_64)))+        cc-options: -DWITH_AESNI+        c-sources:+            cbits/aes/x86ni.c+            cbits/aes/generic.c+            cbits/aes/gf.c+            cbits/crypton_aes.c -  if flag(support_deepseq)-    CPP-options:     -DWITH_DEEPSEQ_SUPPORT-    Build-depends:   deepseq-  if flag(check_alignment)-    cc-options:     -DWITH_ASSERT_ALIGNMENT-  if flag(use_target_attributes)-    cc-options:     -DWITH_TARGET_ATTRIBUTES+        if !flag(use_target_attributes)+            cc-options: -mssse3 -maes -Test-Suite test-crypton-  type:              exitcode-stdio-1.0-  hs-source-dirs:    tests-  Main-is:           Tests.hs-  Other-modules:     BlockCipher-                     ChaCha-                     BCrypt-                     BCryptPBKDF-                     ECC-                     ECC.Edwards25519-                     ECDSA-                     Hash-                     Imports-                     KAT_AES.KATCBC-                     KAT_AES.KATECB-                     KAT_AES.KATGCM-                     KAT_AES.KATCCM-                     KAT_AES.KATOCB3-                     KAT_AES.KATXTS-                     KAT_AES-                     KAT_AESGCMSIV-                     KAT_AFIS-                     KAT_Argon2-                     KAT_Blowfish-                     KAT_CAST5-                     KAT_Camellia-                     KAT_Curve25519-                     KAT_Curve448-                     KAT_DES-                     KAT_Ed25519-                     KAT_Ed448-                     KAT_EdDSA-                     KAT_CMAC-                     KAT_HKDF-                     KAT_HMAC-                     KAT_KMAC-                     KAT_MiyaguchiPreneel-                     KAT_PBKDF2-                     KAT_OTP-                     KAT_PubKey.DSA-                     KAT_PubKey.ECC-                     KAT_PubKey.ECDSA-                     KAT_PubKey.OAEP-                     KAT_PubKey.PSS-                     KAT_PubKey.P256-                     KAT_PubKey.RSA-                     KAT_PubKey.Rabin-                     KAT_PubKey-                     KAT_RC4-                     KAT_Scrypt-                     KAT_TripleDES-                     KAT_Twofish-                     ChaChaPoly1305-                     Number-                     Number.F2m-                     Padding-                     Poly1305-                     Salsa-                     Utils-                     XSalsa-  Build-Depends:     base >= 0 && < 10-                   , bytestring-                   , memory-                   , tasty-                   , tasty-quickcheck-                   , tasty-hunit-                   , tasty-kat-                   , crypton-  ghc-options:       -Wall -fno-warn-orphans -fno-warn-missing-signatures -rtsopts-  default-language:  Haskell2010+        if flag(support_pclmuldq)+            cc-options: -DWITH_PCLMUL -Benchmark bench-crypton-  type:              exitcode-stdio-1.0-  hs-source-dirs:    benchs-  Main-is:           Bench.hs-  Other-modules:     Number.F2m-  Build-Depends:     base-                   , bytestring-                   , deepseq-                   , memory-                   , gauge-                   , random-                   , crypton-  ghc-options:       -Wall -fno-warn-missing-signatures-  default-language:  Haskell2010+            if !flag(use_target_attributes)+                cc-options: -msse4.1 -mpclmul++    else+        c-sources:+            cbits/aes/generic.c+            cbits/aes/gf.c+            cbits/crypton_aes.c++    if (arch(x86_64) || flag(support_sse))+        c-sources:+            cbits/blake2/sse/blake2s.c+            cbits/blake2/sse/blake2sp.c+            cbits/blake2/sse/blake2b.c+            cbits/blake2/sse/blake2bp.c++        include-dirs: cbits/blake2/sse++    else+        c-sources:+            cbits/blake2/ref/blake2s-ref.c+            cbits/blake2/ref/blake2sp-ref.c+            cbits/blake2/ref/blake2b-ref.c+            cbits/blake2/ref/blake2bp-ref.c++        include-dirs: cbits/blake2/ref++    if (arch(x86_64) || flag(support_sse))+        cpp-options: -DSUPPORT_SSE++        if arch(i386)+            cc-options: -msse2++    if os(windows)+        cpp-options:     -DWINDOWS+        other-modules:   Crypto.Random.Entropy.Windows+        extra-libraries: advapi32+        build-depends:   Win32++    else+        other-modules: Crypto.Random.Entropy.Unix++    if (impl(ghc >=0) && flag(integer-gmp))+        build-depends: integer-gmp++    if flag(support_deepseq)+        cpp-options:   -DWITH_DEEPSEQ_SUPPORT+        build-depends: deepseq++    if flag(check_alignment)+        cc-options: -DWITH_ASSERT_ALIGNMENT++    if flag(use_target_attributes)+        cc-options: -DWITH_TARGET_ATTRIBUTES++test-suite test-crypton+    type:             exitcode-stdio-1.0+    main-is:          Tests.hs+    hs-source-dirs:   tests+    other-modules:+        BlockCipher+        ChaCha+        BCrypt+        BCryptPBKDF+        ECC+        ECC.Edwards25519+        ECDSA+        Hash+        Imports+        KAT_AES.KATCBC+        KAT_AES.KATECB+        KAT_AES.KATGCM+        KAT_AES.KATCCM+        KAT_AES.KATOCB3+        KAT_AES.KATXTS+        KAT_AES+        KAT_AESGCMSIV+        KAT_AFIS+        KAT_Argon2+        KAT_Blowfish+        KAT_CAST5+        KAT_Camellia+        KAT_Curve25519+        KAT_Curve448+        KAT_DES+        KAT_Ed25519+        KAT_Ed448+        KAT_EdDSA+        KAT_Blake2+        KAT_CMAC+        KAT_HKDF+        KAT_HMAC+        KAT_KMAC+        KAT_MiyaguchiPreneel+        KAT_PBKDF2+        KAT_OTP+        KAT_PubKey.DSA+        KAT_PubKey.ECC+        KAT_PubKey.ECDSA+        KAT_PubKey.OAEP+        KAT_PubKey.PSS+        KAT_PubKey.P256+        KAT_PubKey.RSA+        KAT_PubKey.Rabin+        KAT_PubKey+        KAT_RC4+        KAT_Scrypt+        KAT_TripleDES+        KAT_Twofish+        ChaChaPoly1305+        Number+        Number.F2m+        Padding+        Poly1305+        Salsa+        Utils+        XSalsa++    default-language: Haskell2010+    ghc-options:+        -Wall -fno-warn-orphans -fno-warn-missing-signatures -rtsopts++    build-depends:+        base >=0 && <10,+        bytestring,+        memory,+        tasty,+        tasty-quickcheck,+        tasty-hunit,+        tasty-kat,+        crypton++benchmark bench-crypton+    type:             exitcode-stdio-1.0+    main-is:          Bench.hs+    hs-source-dirs:   benchs+    other-modules:    Number.F2m+    default-language: Haskell2010+    ghc-options:      -Wall -fno-warn-missing-signatures+    build-depends:+        base,+        bytestring,+        deepseq,+        memory,+        gauge,+        random,+        crypton
tests/ChaCha.hs view
@@ -23,6 +23,18 @@ b20_256_k0_i0 =     "\x76\xb8\xe0\xad\xa0\xf1\x3d\x90\x40\x5d\x6a\xe5\x53\x86\xbd\x28\xbd\xd2\x19\xb8\xa0\x8d\xed\x1a\xa8\x36\xef\xcc\x8b\x77\x0d\xc7\xda\x41\x59\x7c\x51\x57\x48\x8d\x77\x24\xe0\x3f\xb8\xd8\x4a\x37\x6a\x43\xb8\xf4\x15\x18\xa1\x1c\xc3\x87\xb6\x69\xb2\xee\x65\x86\x9f\x07\xe7\xbe\x55\x51\x38\x7a\x98\xba\x97\x7c\x73\x2d\x08\x0d\xcb\x0f\x29\xa0\x48\xe3\x65\x69\x12\xc6\x53\x3e\x32\xee\x7a\xed\x29\xb7\x21\x76\x9c\xe6\x4e\x43\xd5\x71\x33\xb0\x74\xd8\x39\xd5\x31\xed\x1f\x28\x51\x0a\xfb\x45\xac\xe1\x0a\x1f\x4b\x79\x4d\x6f" +-- XChaCha20 test vector from RFC draft: https://datatracker.ietf.org/doc/html/draft-arciszewski-xchacha++xChaCha20_ExampleKAT = expected @=? fst (ChaCha.combine initState plaintext)+    where iv = B.pack $ [0x40 .. 0x56] ++ [0x58]+          key = B.pack [0x80 .. 0x9f]+          initState = ChaCha.initializeX 20 key iv+          plaintext :: B.ByteString+          plaintext = "The dhole (pronounced \"dole\") is also known as the Asiatic wild dog, red dog, and whistling dog. It is about the size of a German shepherd but looks more like a long-legged fox. This highly elusive and skilled jumper is classified with wolves, coyotes, jackals, and foxes in the taxonomic family Canidae."+          expected :: B.ByteString+          expected = "\x45\x59\xab\xba\x4e\x48\xc1\x61\x02\xe8\xbb\x2c\x05\xe6\x94\x7f\x50\xa7\x86\xde\x16\x2f\x9b\x0b\x7e\x59\x2a\x9b\x53\xd0\xd4\xe9\x8d\x8d\x64\x10\xd5\x40\xa1\xa6\x37\x5b\x26\xd8\x0d\xac\xe4\xfa\xb5\x23\x84\xc7\x31\xac\xbf\x16\xa5\x92\x3c\x0c\x48\xd3\x57\x5d\x4d\x0d\x2c\x67\x3b\x66\x6f\xaa\x73\x10\x61\x27\x77\x01\x09\x3a\x6b\xf7\xa1\x58\xa8\x86\x42\x92\xa4\x1c\x48\xe3\xa9\xb4\xc0\xda\xec\xe0\xf8\xd9\x8d\x0d\x7e\x05\xb3\x7a\x30\x7b\xbb\x66\x33\x31\x64\xec\x9e\x1b\x24\xea\x0d\x6c\x3f\xfd\xdc\xec\x4f\x68\xe7\x44\x30\x56\x19\x3a\x03\xc8\x10\xe1\x13\x44\xca\x06\xd8\xed\x8a\x2b\xfb\x1e\x8d\x48\xcf\xa6\xbc\x0e\xb4\xe2\x46\x4b\x74\x81\x42\x40\x7c\x9f\x43\x1a\xee\x76\x99\x60\xe1\x5b\xa8\xb9\x68\x90\x46\x6e\xf2\x45\x75\x99\x85\x23\x85\xc6\x61\xf7\x52\xce\x20\xf9\xda\x0c\x09\xab\x6b\x19\xdf\x74\xe7\x6a\x95\x96\x74\x46\xf8\xd0\xfd\x41\x5e\x7b\xee\x2a\x12\xa1\x14\xc2\x0e\xb5\x29\x2a\xe7\xa3\x49\xae\x57\x78\x20\xd5\x52\x0a\x1f\x3f\xb6\x2a\x17\xce\x6a\x7e\x68\xfa\x7c\x79\x11\x1d\x88\x60\x92\x0b\xc0\x48\xef\x43\xfe\x84\x48\x6c\xcb\x87\xc2\x5f\x0a\xe0\x45\xf0\xcc\xe1\xe7\x98\x9a\x9a\xa2\x20\xa2\x8b\xdd\x48\x27\xe7\x51\xa2\x4a\x6d\x5c\x62\xd7\x90\xa6\x63\x93\xb9\x31\x11\xc1\xa5\x5d\xd7\x42\x1a\x10\x18\x49\x74\xc7\xc5"++ data Vector = Vector Int -- rounds                      ByteString -- key                      ByteString -- nonce@@ -38,6 +50,7 @@     , testCase "8-256-K0-I0"  (chachaRunSimple b8_256_k0_i0 8 32 8)     , testCase "12-256-K0-I0" (chachaRunSimple b12_256_k0_i0 12 32 8)     , testCase "20-256-K0-I0" (chachaRunSimple b20_256_k0_i0 20 32 8)+    , testCase "XChaCha20 example KAT" xChaCha20_ExampleKAT     , testProperty "generate-combine" chachaGenerateCombine     , testProperty "chunking-generate" chachaGenerateChunks     , testProperty "chunking-combine" chachaCombineChunks
tests/ChaChaPoly1305.hs view
@@ -9,14 +9,17 @@ import qualified Data.ByteString as B import qualified Data.ByteArray as B (convert) -plaintext, aad, key, iv, ciphertext, tag, nonce1, nonce2, nonce3, nonce4, nonce5, nonce6, nonce7, nonce8, nonce9, nonce10 :: B.ByteString+plaintext, aad, key, iv, ivX, ciphertext, ciphertextX, tag, tagX, nonce1, nonce2, nonce3, nonce4, nonce5, nonce6, nonce7, nonce8, nonce9, nonce10 :: B.ByteString plaintext = "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it." aad = "\x50\x51\x52\x53\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7" key = "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" iv = "\x40\x41\x42\x43\x44\x45\x46\x47"+ivX = B.pack [0x40 .. 0x57] constant = "\x07\x00\x00\x00" ciphertext = "\xd3\x1a\x8d\x34\x64\x8e\x60\xdb\x7b\x86\xaf\xbc\x53\xef\x7e\xc2\xa4\xad\xed\x51\x29\x6e\x08\xfe\xa9\xe2\xb5\xa7\x36\xee\x62\xd6\x3d\xbe\xa4\x5e\x8c\xa9\x67\x12\x82\xfa\xfb\x69\xda\x92\x72\x8b\x1a\x71\xde\x0a\x9e\x06\x0b\x29\x05\xd6\xa5\xb6\x7e\xcd\x3b\x36\x92\xdd\xbd\x7f\x2d\x77\x8b\x8c\x98\x03\xae\xe3\x28\x09\x1b\x58\xfa\xb3\x24\xe4\xfa\xd6\x75\x94\x55\x85\x80\x8b\x48\x31\xd7\xbc\x3f\xf4\xde\xf0\x8e\x4b\x7a\x9d\xe5\x76\xd2\x65\x86\xce\xc6\x4b\x61\x16"+ciphertextX = "\xbd\x6d\x17\x9d\x3e\x83\xd4\x3b\x95\x76\x57\x94\x93\xc0\xe9\x39\x57\x2a\x17\x00\x25\x2b\xfa\xcc\xbe\xd2\x90\x2c\x21\x39\x6c\xbb\x73\x1c\x7f\x1b\x0b\x4a\xa6\x44\x0b\xf3\xa8\x2f\x4e\xda\x7e\x39\xae\x64\xc6\x70\x8c\x54\xc2\x16\xcb\x96\xb7\x2e\x12\x13\xb4\x52\x2f\x8c\x9b\xa4\x0d\xb5\xd9\x45\xb1\x1b\x69\xb9\x82\xc1\xbb\x9e\x3f\x3f\xac\x2b\xc3\x69\x48\x8f\x76\xb2\x38\x35\x65\xd3\xff\xf9\x21\xf9\x66\x4c\x97\x63\x7d\xa9\x76\x88\x12\xf6\x15\xc6\x8b\x13\xb5\x2e" tag = "\x1a\xe1\x0b\x59\x4f\x09\xe2\x6a\x7e\x90\x2e\xcb\xd0\x60\x06\x91"+tagX = "\xc0\x87\x59\x24\xc1\xc7\x98\x79\x47\xde\xaf\xd8\x78\x0a\xcf\x49" nonce1  = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" nonce2  = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" nonce3  = "\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"@@ -31,6 +34,8 @@ tests = testGroup "ChaChaPoly1305"     [ testCase "V1" runEncrypt     , testCase "V1-decrypt" runDecrypt+    , testCase "V1-extended" runEncryptX+    , testCase "V1-extended-decrypt" runDecryptX     , testCase "nonce increment" runNonceInc     ]   where runEncrypt =@@ -41,6 +46,14 @@              in propertyHoldCase [ eqTest "ciphertext" ciphertext out                                  , eqTest "tag" tag (B.convert outtag)                                  ]+        runEncryptX =+            let ini                 = throwCryptoError $ AEAD.initializeX key (throwCryptoError $ AEAD.nonce24 ivX)+                afterAAD            = AEAD.finalizeAAD (AEAD.appendAAD aad ini)+                (out, afterEncrypt) = AEAD.encrypt plaintext afterAAD+                outtag              = AEAD.finalize afterEncrypt+             in propertyHoldCase [ eqTest "ciphertext" ciphertextX out+                                 , eqTest "tag" tagX (B.convert outtag)+                                 ]          runDecrypt =             let ini                 = throwCryptoError $ AEAD.initialize key (throwCryptoError $ AEAD.nonce8 constant iv)@@ -49,6 +62,15 @@                 outtag              = AEAD.finalize afterDecrypt              in propertyHoldCase [ eqTest "plaintext" plaintext out                                  , eqTest "tag" tag (B.convert outtag)+                                 ]++        runDecryptX =+            let ini                 = throwCryptoError $ AEAD.initializeX key (throwCryptoError $ AEAD.nonce24 ivX)+                afterAAD            = AEAD.finalizeAAD (AEAD.appendAAD aad ini)+                (out, afterDecrypt) = AEAD.decrypt ciphertextX afterAAD+                outtag              = AEAD.finalize afterDecrypt+             in propertyHoldCase [ eqTest "plaintext" plaintext out+                                 , eqTest "tag" tagX (B.convert outtag)                                  ]          runNonceInc =
+ tests/KAT_Blake2.hs view
@@ -0,0 +1,166 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}+module KAT_Blake2 (tests) where++import           Crypto.Hash (digestFromByteString)+import           Crypto.Hash.Algorithms+import qualified Crypto.MAC.KeyedBlake2 as KB++import qualified Data.ByteString as B++import Imports+++data MACVector hash = MACVector+    { macMessage :: ByteString+    , macKey    :: ByteString+    , macResult :: KB.KeyedBlake2 hash+    }++instance Show (KB.KeyedBlake2 hash) where+    show (KB.KeyedBlake2 d) = show d++digest :: KB.HashBlake2 hash => ByteString -> KB.KeyedBlake2 hash+digest = maybe (error "cannot get digest") KB.KeyedBlake2 . digestFromByteString+++-- From: https://github.com/BLAKE2/BLAKE2/blob/master/testvectors/+vectorsBlake2bKAT :: [MACVector (Blake2b 512)]+vectorsBlake2bKAT =+    [ MACVector+        { macMessage = ""+        , macKey     = fixedKey+        , macResult  = digest "\x10\xeb\xb6\x77\x00\xb1\x86\x8e\xfb\x44\x17\x98\x7a\xcf\x46\x90\xae\x9d\x97\x2f\xb7\xa5\x90\xc2\xf0\x28\x71\x79\x9a\xaa\x47\x86\xb5\xe9\x96\xe8\xf0\xf4\xeb\x98\x1f\xc2\x14\xb0\x05\xf4\x2d\x2f\xf4\x23\x34\x99\x39\x16\x53\xdf\x7a\xef\xcb\xc1\x3f\xc5\x15\x68"+        }+    , MACVector+        { macMessage = "\x00"+        , macKey     = fixedKey+        , macResult  = digest "\x96\x1f\x6d\xd1\xe4\xdd\x30\xf6\x39\x01\x69\x0c\x51\x2e\x78\xe4\xb4\x5e\x47\x42\xed\x19\x7c\x3c\x5e\x45\xc5\x49\xfd\x25\xf2\xe4\x18\x7b\x0b\xc9\xfe\x30\x49\x2b\x16\xb0\xd0\xbc\x4e\xf9\xb0\xf3\x4c\x70\x03\xfa\xc0\x9a\x5e\xf1\x53\x2e\x69\x43\x02\x34\xce\xbd"+        }+    , MACVector+        { macMessage = B.pack [ 0x00 .. 0xfe ]+        , macKey     = fixedKey+        , macResult  = digest "\x14\x27\x09\xd6\x2e\x28\xfc\xcc\xd0\xaf\x97\xfa\xd0\xf8\x46\x5b\x97\x1e\x82\x20\x1d\xc5\x10\x70\xfa\xa0\x37\x2a\xa4\x3e\x92\x48\x4b\xe1\xc1\xe7\x3b\xa1\x09\x06\xd5\xd1\x85\x3d\xb6\xa4\x10\x6e\x0a\x7b\xf9\x80\x0d\x37\x3d\x6d\xee\x2d\x46\xd6\x2e\xf2\xa4\x61"+        }+    ]+    where fixedKey = B.pack [ 0x00 .. 0x3f ]++vectorsBlake2bpKAT :: [MACVector (Blake2bp 512)]+vectorsBlake2bpKAT =+    [ MACVector+        { macMessage = ""+        , macKey     = fixedKey+        , macResult  = digest "\x9d\x94\x61\x07\x3e\x4e\xb6\x40\xa2\x55\x35\x7b\x83\x9f\x39\x4b\x83\x8c\x6f\xf5\x7c\x9b\x68\x6a\x3f\x76\x10\x7c\x10\x66\x72\x8f\x3c\x99\x56\xbd\x78\x5c\xbc\x3b\xf7\x9d\xc2\xab\x57\x8c\x5a\x0c\x06\x3b\x9d\x9c\x40\x58\x48\xde\x1d\xbe\x82\x1c\xd0\x5c\x94\x0a"+        }+    , MACVector+        { macMessage = "\x00"+        , macKey     = fixedKey+        , macResult  = digest "\xff\x8e\x90\xa3\x7b\x94\x62\x39\x32\xc5\x9f\x75\x59\xf2\x60\x35\x02\x9c\x37\x67\x32\xcb\x14\xd4\x16\x02\x00\x1c\xbb\x73\xad\xb7\x92\x93\xa2\xdb\xda\x5f\x60\x70\x30\x25\x14\x4d\x15\x8e\x27\x35\x52\x95\x96\x25\x1c\x73\xc0\x34\x5c\xa6\xfc\xcb\x1f\xb1\xe9\x7e"+        }+    , MACVector+        { macMessage = B.pack [ 0x00 .. 0xfe ]+        , macKey     = fixedKey+        , macResult  = digest "\x96\xfb\xcb\xb6\x0b\xd3\x13\xb8\x84\x50\x33\xe5\xbc\x05\x8a\x38\x02\x74\x38\x57\x2d\x7e\x79\x57\xf3\x68\x4f\x62\x68\xaa\xdd\x3a\xd0\x8d\x21\x76\x7e\xd6\x87\x86\x85\x33\x1b\xa9\x85\x71\x48\x7e\x12\x47\x0a\xad\x66\x93\x26\x71\x6e\x46\x66\x7f\x69\xf8\xd7\xe8"+        }+    ]+    where fixedKey = B.pack [ 0x00 .. 0x3f ]++vectorsBlake2sKAT :: [MACVector (Blake2s 256)]+vectorsBlake2sKAT =+    [ MACVector+        { macMessage = ""+        , macKey     = fixedKey+        , macResult  = digest "\x48\xa8\x99\x7d\xa4\x07\x87\x6b\x3d\x79\xc0\xd9\x23\x25\xad\x3b\x89\xcb\xb7\x54\xd8\x6a\xb7\x1a\xee\x04\x7a\xd3\x45\xfd\x2c\x49"+        }+    , MACVector+        { macMessage = "\x00"+        , macKey     = fixedKey+        , macResult  = digest "\x40\xd1\x5f\xee\x7c\x32\x88\x30\x16\x6a\xc3\xf9\x18\x65\x0f\x80\x7e\x7e\x01\xe1\x77\x25\x8c\xdc\x0a\x39\xb1\x1f\x59\x80\x66\xf1"+        }+    , MACVector+        { macMessage = B.pack [ 0x00 .. 0xfe ]+        , macKey     = fixedKey+        , macResult  = digest "\x3f\xb7\x35\x06\x1a\xbc\x51\x9d\xfe\x97\x9e\x54\xc1\xee\x5b\xfa\xd0\xa9\xd8\x58\xb3\x31\x5b\xad\x34\xbd\xe9\x99\xef\xd7\x24\xdd"+        }+    ]+    where fixedKey = B.pack [ 0x00 .. 0x1f ]++vectorsBlake2spKAT :: [MACVector (Blake2sp 256)]+vectorsBlake2spKAT =+    [ MACVector+        { macMessage = ""+        , macKey     = fixedKey+        , macResult  = digest "\x71\x5c\xb1\x38\x95\xae\xb6\x78\xf6\x12\x41\x60\xbf\xf2\x14\x65\xb3\x0f\x4f\x68\x74\x19\x3f\xc8\x51\xb4\x62\x10\x43\xf0\x9c\xc6"+        }+    , MACVector+        { macMessage = "\x00"+        , macKey     = fixedKey+        , macResult  = digest "\x40\x57\x8f\xfa\x52\xbf\x51\xae\x18\x66\xf4\x28\x4d\x3a\x15\x7f\xc1\xbc\xd3\x6a\xc1\x3c\xbd\xcb\x03\x77\xe4\xd0\xcd\x0b\x66\x03"+        }+    , MACVector+        { macMessage = B.pack [ 0x00 .. 0xfe ]+        , macKey     = fixedKey+        , macResult  = digest "\x0c\x8a\x36\x59\x7d\x74\x61\xc6\x3a\x94\x73\x28\x21\xc9\x41\x85\x6c\x66\x83\x76\x60\x6c\x86\xa5\x2d\xe0\xee\x41\x04\xc6\x15\xdb"+        }+    ]+    where fixedKey = B.pack [ 0x00 .. 0x1f ]++macTests :: [TestTree]+macTests =+    [ testGroup "Blake2b_512" (concatMap toMACTest $ zip is vectorsBlake2bKAT)+    , testGroup "Blake2bp_512" (concatMap toMACTest $ zip is vectorsBlake2bpKAT)+    , testGroup "Blake2s_512" (concatMap toMACTest $ zip is vectorsBlake2sKAT)+    , testGroup "Blake2sp_512" (concatMap toMACTest $ zip is vectorsBlake2spKAT)+    ]+    where toMACTest (i, MACVector{..}) =+            [ testCase (show i) (macResult @=? KB.keyedBlake2 macKey macMessage)+            , testCase ("incr-" ++ show i) (macResult @=?+                        KB.finalize (KB.update (KB.initialize macKey) macMessage))+            ]+          is :: [Int]+          is = [1..]++data MacIncremental a = MacIncremental ByteString ByteString (KB.KeyedBlake2 a)+    deriving (Show,Eq)++instance KB.HashBlake2 a => Arbitrary (MacIncremental a) where+    arbitrary = do+        key <- arbitraryBSof 32 64+        msg <- arbitraryBSof 1 99+        return $ MacIncremental key msg (KB.keyedBlake2 key msg)++data MacIncrementalList a = MacIncrementalList ByteString [ByteString] (KB.KeyedBlake2 a)+    deriving (Show,Eq)++instance KB.HashBlake2 a => Arbitrary (MacIncrementalList a) where+    arbitrary = do+        key <- arbitraryBSof 32 64+        msgs <- choose (1,20) >>= \n -> replicateM n (arbitraryBSof 1 99)+        return $ MacIncrementalList key msgs (KB.keyedBlake2 key (B.concat msgs))++macIncrementalTests :: [TestTree]+macIncrementalTests =+    [ testIncrProperties "Blake2b_512" (Blake2b :: Blake2b 512)+    , testIncrProperties "Blake2bp_512" (Blake2bp :: Blake2bp 512)+    , testIncrProperties "Blake2s_256" (Blake2s :: Blake2s 256)+    , testIncrProperties "Blake2sp_256" (Blake2sp :: Blake2sp 256)+    ]+  where+        testIncrProperties :: KB.HashBlake2 a => TestName -> a -> TestTree+        testIncrProperties name a = testGroup name+            [ testProperty "list-one" (prop_inc0 a)+            , testProperty "list-multi" (prop_inc1 a)+            ]++        prop_inc0 :: KB.HashBlake2 a => a -> MacIncremental a -> Bool+        prop_inc0 _ (MacIncremental secret msg result) =+            result `assertEq` KB.finalize (KB.update (KB.initialize secret) msg)++        prop_inc1 :: KB.HashBlake2 a => a -> MacIncrementalList a -> Bool+        prop_inc1 _ (MacIncrementalList secret msgs result) =+            result `assertEq` KB.finalize (foldl' KB.update (KB.initialize secret) msgs)++tests = testGroup "Blake2"+    [ testGroup "KATs" macTests+    , testGroup "properties" macIncrementalTests ]
tests/Tests.hs view
@@ -19,6 +19,7 @@ import qualified ChaCha import qualified ChaChaPoly1305 import qualified KAT_MiyaguchiPreneel+import qualified KAT_Blake2 import qualified KAT_CMAC import qualified KAT_HMAC import qualified KAT_KMAC@@ -60,6 +61,7 @@         ]     , testGroup "MAC"         [ Poly1305.tests+        , KAT_Blake2.tests         , KAT_CMAC.tests         , KAT_HMAC.tests         , KAT_KMAC.tests