crypton-conduit 0.3.0 → 0.3.1
raw patch · 10 files changed
+442/−423 lines, 10 filessetup-changedPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- CHANGELOG.md +26/−22
- Crypto/Cipher/ChaChaPoly1305/Conduit.hs +103/−88
- Crypto/Hash/Conduit.hs +48/−48
- Crypto/MAC/HMAC/Conduit.hs +30/−30
- Crypto/PubKey/ECIES/Conduit.hs +72/−72
- LICENSE +27/−27
- README.md +13/−13
- Setup.hs +2/−2
- crypton-conduit.cabal +58/−58
- test/Spec.hs +63/−63
CHANGELOG.md view
@@ -1,22 +1,26 @@-## 0.3.0 - -* Depend on package `ram` (rather than `memory`) and, consequently, on - `crypton >= 1.1.0`. - -## 0.2.3 - -* Fork using `crypton` as the base library. -* Move away from deprecated `conduit` functions and types. - -## 0.2.1 - -* Add the `Crypto.Cipher.ChaChaPoly1305.Conduit` and - `Crypto.PubKey.ECIES.Conduit` modules. - -## 0.2.0 - -* Add HMAC sink. - -## 0.1 - -* Initial release. +## 0.3.1++* Fix dependency issues: https://github.com/psibi/crypton-conduit/issues/5++## 0.3.0++* Depend on package `ram` (rather than `memory`) and, consequently, on+ `crypton >= 1.1.0`.++## 0.2.3++* Fork using `crypton` as the base library.+* Move away from deprecated `conduit` functions and types.++## 0.2.1++* Add the `Crypto.Cipher.ChaChaPoly1305.Conduit` and+ `Crypto.PubKey.ECIES.Conduit` modules.++## 0.2.0++* Add HMAC sink.++## 0.1++* Initial release.
Crypto/Cipher/ChaChaPoly1305/Conduit.hs view
@@ -1,88 +1,103 @@-{-# LANGUAGE DeriveDataTypeable #-} -module Crypto.Cipher.ChaChaPoly1305.Conduit - ( encrypt - , decrypt - , ChaChaException (..) - ) where - -import Control.Exception (assert) -import Control.Monad.Catch (Exception, MonadThrow, throwM) -import qualified Crypto.Cipher.ChaChaPoly1305 as Cha -import qualified Crypto.Error as CE -import qualified Crypto.MAC.Poly1305 as Poly1305 -import qualified Data.ByteArray as BA -import Data.ByteString (ByteString) -import qualified Data.ByteString as B -import qualified Data.ByteString.Lazy as BL -import Data.Conduit (ConduitM, await, leftover, yield) -import qualified Data.Conduit.Binary as CB -import Data.Typeable (Typeable) - -cf :: MonadThrow m - => (CE.CryptoError -> ChaChaException) - -> CE.CryptoFailable a - -> m a -cf _ (CE.CryptoPassed x) = return x -cf f (CE.CryptoFailed e) = throwM (f e) - -data ChaChaException - = EncryptNonceException !CE.CryptoError - | EncryptKeyException !CE.CryptoError - | DecryptNonceException !CE.CryptoError - | DecryptKeyException !CE.CryptoError - | MismatchedAuth - deriving (Show, Typeable) -instance Exception ChaChaException - -encrypt - :: MonadThrow m - => ByteString -- ^ nonce (12 random bytes) - -> ByteString -- ^ symmetric key (32 bytes) - -> ConduitM ByteString ByteString m () -encrypt nonceBS key = do - nonce <- cf EncryptNonceException $ Cha.nonce12 nonceBS - state0 <- cf EncryptKeyException $ Cha.initialize key nonce - yield nonceBS - let loop state1 = do - mbs <- await - case mbs of - Nothing -> yield $ BA.convert $ Cha.finalize state1 - Just bs -> do - let (bs', state2) = Cha.encrypt bs state1 - yield bs' - loop state2 - loop $ Cha.finalizeAAD state0 - -decrypt - :: MonadThrow m - => ByteString -- ^ symmetric key (32 bytes) - -> ConduitM ByteString ByteString m () -decrypt key = do - nonceBS <- CB.take 12 - nonce <- cf DecryptNonceException $ Cha.nonce12 $ BL.toStrict nonceBS - state0 <- cf DecryptKeyException $ Cha.initialize key nonce - let loop state1 = do - ebs <- awaitExcept16 id - case ebs of - Left final -> - case Poly1305.authTag final of - CE.CryptoPassed final' | Cha.finalize state1 == final' -> return () - _ -> throwM MismatchedAuth - Right bs -> do - let (bs', state2) = Cha.decrypt bs state1 - yield bs' - loop state2 - loop $ Cha.finalizeAAD state0 - where - awaitExcept16 front = do - mbs <- await - case mbs of - Nothing -> return $ Left $ front B.empty - Just bs -> do - let bs' = front bs - if B.length bs' > 16 - then do - let (x, y) = B.splitAt (B.length bs' - 16) bs' - assert (B.length y == 16) leftover y - return $ Right x - else awaitExcept16 (B.append bs') +{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE CPP #-}++module Crypto.Cipher.ChaChaPoly1305.Conduit+ ( encrypt+ , decrypt+ , ChaChaException (..)+ ) where++import Control.Exception (assert)+import Control.Monad.Catch (Exception, MonadThrow, throwM)+import qualified Crypto.Cipher.ChaChaPoly1305 as Cha+import qualified Crypto.Error as CE+import qualified Crypto.MAC.Poly1305 as Poly1305+import qualified Data.ByteArray as BA+import Data.ByteString (ByteString)+import qualified Data.ByteString as B+import qualified Data.ByteString.Lazy as BL+import Data.Conduit (ConduitM, await, leftover, yield)+import qualified Data.Conduit.Binary as CB+import Data.Typeable (Typeable)++cf :: MonadThrow m+ => (CE.CryptoError -> ChaChaException)+ -> CE.CryptoFailable a+ -> m a+cf _ (CE.CryptoPassed x) = return x+cf f (CE.CryptoFailed e) = throwM (f e)++data ChaChaException+ = EncryptNonceException !CE.CryptoError+ | EncryptKeyException !CE.CryptoError+ | DecryptNonceException !CE.CryptoError+ | DecryptKeyException !CE.CryptoError+ | MismatchedAuth+ deriving (Show, Typeable)+instance Exception ChaChaException++initialize+ :: MonadThrow m+ => Cha.Nonce+ -> ByteString+ -> m Cha.State+initialize nonce key = do+#if MIN_VERSION_crypton(2,1,0)+ key' <- cf DecryptKeyException $ Cha.key key+ pure $ Cha.initialize key' nonce+#else+ cf EncryptKeyException $ Cha.initialize key nonce+#endif++encrypt+ :: MonadThrow m+ => ByteString -- ^ nonce (12 random bytes)+ -> ByteString -- ^ symmetric key (32 bytes)+ -> ConduitM ByteString ByteString m ()+encrypt nonceBS key = do+ nonce <- cf EncryptNonceException $ Cha.nonce12 nonceBS+ state0 <- initialize nonce key+ yield nonceBS+ let loop state1 = do+ mbs <- await+ case mbs of+ Nothing -> yield $ BA.convert $ Cha.finalize state1+ Just bs -> do+ let (bs', state2) = Cha.encrypt bs state1+ yield bs'+ loop state2+ loop $ Cha.finalizeAAD state0++decrypt+ :: MonadThrow m+ => ByteString -- ^ symmetric key (32 bytes)+ -> ConduitM ByteString ByteString m ()+decrypt key = do+ nonceBS <- CB.take 12+ nonce <- cf DecryptNonceException $ Cha.nonce12 $ BL.toStrict nonceBS+ state0 <- initialize nonce key+ let loop state1 = do+ ebs <- awaitExcept16 id+ case ebs of+ Left final ->+ case Poly1305.authTag final of+ CE.CryptoPassed final' | Cha.finalize state1 == final' -> return ()+ _ -> throwM MismatchedAuth+ Right bs -> do+ let (bs', state2) = Cha.decrypt bs state1+ yield bs'+ loop state2+ loop $ Cha.finalizeAAD state0+ where+ awaitExcept16 front = do+ mbs <- await+ case mbs of+ Nothing -> return $ Left $ front B.empty+ Just bs -> do+ let bs' = front bs+ if B.length bs' > 16+ then do+ let (x, y) = B.splitAt (B.length bs' - 16) bs'+ assert (B.length y == 16) leftover y+ return $ Right x+ else awaitExcept16 (B.append bs')
Crypto/Hash/Conduit.hs view
@@ -1,48 +1,48 @@-{-# LANGUAGE RankNTypes, BangPatterns #-} --- | --- Module : Crypto.Hash.Conduit --- License : BSD-style --- Maintainer : Vincent Hanquez <vincent@snarc.org> --- Stability : experimental --- Portability : unknown --- --- A module containing Conduit facilities for hash based functions. --- --- this module is vaguely similar to the crypto-conduit part related to hash --- on purpose, as to provide an upgrade path. The api documentation is pulled --- directly from this package and adapted, and thus are originally --- copyright Felipe Lessa. --- -module Crypto.Hash.Conduit - ( -- * Cryptographic hash functions - sinkHash - , hashFile - ) where - -import Crypto.Hash -import qualified Data.ByteString as B - -import Data.Conduit -import Data.Conduit.Binary (sourceFile) - -import Control.Monad.IO.Class (MonadIO, liftIO) - --- | A 'Sink' that hashes a stream of 'B.ByteString'@s@ and --- creates a digest @d@. -sinkHash :: (Monad m, HashAlgorithm hash) => ConduitT B.ByteString o m (Digest hash) -sinkHash = sink hashInit - where sink ctx = do - b <- await - case b of - Nothing -> return $! hashFinalize ctx - Just bs -> sink $! hashUpdate ctx bs - --- | Hashes the whole contents of the given file in constant --- memory. This function is just a convenient wrapper around --- 'sinkHash' defined as: --- --- @ --- hashFile fp = 'liftIO' $ 'runConduitRes' ('sourceFile' fp '.|' 'sinkHash') --- @ -hashFile :: (MonadIO m, HashAlgorithm hash) => FilePath -> m (Digest hash) -hashFile fp = liftIO $ runConduitRes (sourceFile fp .| sinkHash) +{-# LANGUAGE RankNTypes, BangPatterns #-}+-- |+-- Module : Crypto.Hash.Conduit+-- License : BSD-style+-- Maintainer : Vincent Hanquez <vincent@snarc.org>+-- Stability : experimental+-- Portability : unknown+--+-- A module containing Conduit facilities for hash based functions.+--+-- this module is vaguely similar to the crypto-conduit part related to hash+-- on purpose, as to provide an upgrade path. The api documentation is pulled+-- directly from this package and adapted, and thus are originally+-- copyright Felipe Lessa.+--+module Crypto.Hash.Conduit+ ( -- * Cryptographic hash functions+ sinkHash+ , hashFile+ ) where++import Crypto.Hash+import qualified Data.ByteString as B++import Data.Conduit+import Data.Conduit.Binary (sourceFile)++import Control.Monad.IO.Class (MonadIO, liftIO)++-- | A 'Sink' that hashes a stream of 'B.ByteString'@s@ and+-- creates a digest @d@.+sinkHash :: (Monad m, HashAlgorithm hash) => ConduitT B.ByteString o m (Digest hash)+sinkHash = sink hashInit+ where sink ctx = do+ b <- await+ case b of+ Nothing -> return $! hashFinalize ctx+ Just bs -> sink $! hashUpdate ctx bs++-- | Hashes the whole contents of the given file in constant+-- memory. This function is just a convenient wrapper around+-- 'sinkHash' defined as:+--+-- @+-- hashFile fp = 'liftIO' $ 'runConduitRes' ('sourceFile' fp '.|' 'sinkHash')+-- @+hashFile :: (MonadIO m, HashAlgorithm hash) => FilePath -> m (Digest hash)+hashFile fp = liftIO $ runConduitRes (sourceFile fp .| sinkHash)
Crypto/MAC/HMAC/Conduit.hs view
@@ -1,30 +1,30 @@-{-# LANGUAGE RankNTypes, BangPatterns #-} --- | --- Module : Crypto.MAC.HMAC.Conduit --- License : BSD-style --- Maintainer : Vincent Hanquez <vincent@snarc.org> --- Stability : experimental --- Portability : unknown --- --- A module containing Conduit facilities for hmac based functions. --- -module Crypto.MAC.HMAC.Conduit - ( -- * Cryptographic hash functions - sinkHMAC - ) where - -import Crypto.Hash -import Crypto.MAC.HMAC -import Data.ByteArray -import Data.Conduit -import qualified Data.ByteString as BS - --- | A 'Sink' that calculates HMAC of a stream of 'B.ByteString'@s@ and --- returns digest @d@. -sinkHMAC :: (Monad m, ByteArrayAccess key, HashAlgorithm hash) => key -> ConduitM BS.ByteString o m (HMAC hash) -sinkHMAC key = sink (initialize key) - where sink ctx = do - b <- await - case b of - Nothing -> return $! finalize ctx - Just bs -> sink $! update ctx bs +{-# LANGUAGE RankNTypes, BangPatterns #-}+-- |+-- Module : Crypto.MAC.HMAC.Conduit+-- License : BSD-style+-- Maintainer : Vincent Hanquez <vincent@snarc.org>+-- Stability : experimental+-- Portability : unknown+--+-- A module containing Conduit facilities for hmac based functions.+--+module Crypto.MAC.HMAC.Conduit+ ( -- * Cryptographic hash functions+ sinkHMAC+ ) where++import Crypto.Hash+import Crypto.MAC.HMAC+import Data.ByteArray+import Data.Conduit+import qualified Data.ByteString as BS++-- | A 'Sink' that calculates HMAC of a stream of 'B.ByteString'@s@ and+-- returns digest @d@.+sinkHMAC :: (Monad m, ByteArrayAccess key, HashAlgorithm hash) => key -> ConduitM BS.ByteString o m (HMAC hash)+sinkHMAC key = sink (initialize key)+ where sink ctx = do+ b <- await+ case b of+ Nothing -> return $! finalize ctx+ Just bs -> sink $! update ctx bs
Crypto/PubKey/ECIES/Conduit.hs view
@@ -1,72 +1,72 @@-{-# LANGUAGE CPP #-} -module Crypto.PubKey.ECIES.Conduit - ( encrypt - , decrypt - ) where - -import Control.Monad.Catch (MonadThrow, throwM) -import Control.Monad.Trans.Class (lift) -import qualified Crypto.Cipher.ChaCha as ChaCha -import qualified Crypto.Cipher.ChaChaPoly1305.Conduit as ChaCha -import qualified Crypto.ECC as ECC -import qualified Crypto.Error as CE -import Crypto.Hash (SHA512 (..), hashWith) -import Crypto.PubKey.ECIES (deriveDecrypt, - deriveEncrypt) -import Crypto.Random (MonadRandom) -import qualified Data.ByteArray as BA -import Data.ByteString (ByteString) -import qualified Data.ByteString as B -import qualified Data.ByteString.Lazy as BL -import Data.Conduit (ConduitM, yield) -import qualified Data.Conduit.Binary as CB -import Data.Proxy (Proxy (..)) -import System.IO.Unsafe (unsafePerformIO) - -getNonceKey :: ECC.SharedSecret -> (ByteString, ByteString) -getNonceKey shared = - let state1 = ChaCha.initializeSimple $ B.take 40 $ BA.convert $ hashWith SHA512 shared - (nonce, state2) = ChaCha.generateSimple state1 12 - (key, _) = ChaCha.generateSimple state2 32 - in (nonce, key) - -type Curve = ECC.Curve_P256R1 - -proxy :: Proxy Curve -proxy = Proxy - -pointBinarySize :: Int -pointBinarySize = B.length $ ECC.encodePoint proxy point - where - point = unsafePerformIO (ECC.keypairGetPublic <$> ECC.curveGenerateKeyPair proxy) -{-# NOINLINE pointBinarySize #-} - -throwOnFail :: MonadThrow m => CE.CryptoFailable a -> m a -throwOnFail (CE.CryptoPassed a) = pure a -throwOnFail (CE.CryptoFailed e) = throwM e - - -encrypt - :: (MonadThrow m, MonadRandom m) - => ECC.Point Curve - -> ConduitM ByteString ByteString m () -encrypt point = do - (point', shared) <- lift (deriveEncryptCompat proxy point) >>= throwOnFail - let (nonce, key) = getNonceKey shared - yield $ ECC.encodePoint proxy point' - ChaCha.encrypt nonce key - where - deriveEncryptCompat prx p = deriveEncrypt prx p - -decrypt - :: (MonadThrow m) - => ECC.Scalar Curve - -> ConduitM ByteString ByteString m () -decrypt scalar = do - pointBS <- fmap BL.toStrict $ CB.take pointBinarySize - point <- throwOnFail (ECC.decodePoint proxy pointBS) - shared <- throwOnFail (deriveDecryptCompat proxy point scalar) - let (_nonce, key) = getNonceKey shared - ChaCha.decrypt key - where - deriveDecryptCompat prx p s = deriveDecrypt prx p s +{-# LANGUAGE CPP #-}+module Crypto.PubKey.ECIES.Conduit+ ( encrypt+ , decrypt+ ) where++import Control.Monad.Catch (MonadThrow, throwM)+import Control.Monad.Trans.Class (lift)+import qualified Crypto.Cipher.ChaCha as ChaCha+import qualified Crypto.Cipher.ChaChaPoly1305.Conduit as ChaCha+import qualified Crypto.ECC as ECC+import qualified Crypto.Error as CE+import Crypto.Hash (SHA512 (..), hashWith)+import Crypto.PubKey.ECIES (deriveDecrypt,+ deriveEncrypt)+import Crypto.Random (MonadRandom)+import qualified Data.ByteArray as BA+import Data.ByteString (ByteString)+import qualified Data.ByteString as B+import qualified Data.ByteString.Lazy as BL+import Data.Conduit (ConduitM, yield)+import qualified Data.Conduit.Binary as CB+import Data.Proxy (Proxy (..))+import System.IO.Unsafe (unsafePerformIO)++getNonceKey :: ECC.SharedSecret -> (ByteString, ByteString)+getNonceKey shared =+ let state1 = ChaCha.initializeSimple $ B.take 40 $ BA.convert $ hashWith SHA512 shared+ (nonce, state2) = ChaCha.generateSimple state1 12+ (key, _) = ChaCha.generateSimple state2 32+ in (nonce, key)++type Curve = ECC.Curve_P256R1++proxy :: Proxy Curve+proxy = Proxy++pointBinarySize :: Int+pointBinarySize = B.length $ ECC.encodePoint proxy point+ where+ point = unsafePerformIO (ECC.keypairGetPublic <$> ECC.curveGenerateKeyPair proxy)+{-# NOINLINE pointBinarySize #-}++throwOnFail :: MonadThrow m => CE.CryptoFailable a -> m a+throwOnFail (CE.CryptoPassed a) = pure a+throwOnFail (CE.CryptoFailed e) = throwM e+++encrypt+ :: (MonadThrow m, MonadRandom m)+ => ECC.Point Curve+ -> ConduitM ByteString ByteString m ()+encrypt point = do+ (point', shared) <- lift (deriveEncryptCompat proxy point) >>= throwOnFail+ let (nonce, key) = getNonceKey shared+ yield $ ECC.encodePoint proxy point'+ ChaCha.encrypt nonce key+ where+ deriveEncryptCompat prx p = deriveEncrypt prx p++decrypt+ :: (MonadThrow m)+ => ECC.Scalar Curve+ -> ConduitM ByteString ByteString m ()+decrypt scalar = do+ pointBS <- fmap BL.toStrict $ CB.take pointBinarySize+ point <- throwOnFail (ECC.decodePoint proxy pointBS)+ shared <- throwOnFail (deriveDecryptCompat proxy point scalar)+ let (_nonce, key) = getNonceKey shared+ ChaCha.decrypt key+ where+ deriveDecryptCompat prx p s = deriveDecrypt prx p s
LICENSE view
@@ -1,27 +1,27 @@-Copyright (c) 2014 Vincent Hanquez <vincent@snarc.org> - -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. Neither the name of the author nor the names of his contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS AS IS'' AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -SUCH DAMAGE. +Copyright (c) 2014 Vincent Hanquez <vincent@snarc.org>++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:+1. Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.+2. Redistributions in binary form must reproduce the above copyright+ notice, this list of conditions and the following disclaimer in the+ documentation and/or other materials provided with the distribution.+3. Neither the name of the author nor the names of his contributors+ may be used to endorse or promote products derived from this software+ without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS AS IS'' AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+SUCH DAMAGE.
README.md view
@@ -1,13 +1,13 @@-crypton-conduit -================== - -[](https://hackage.haskell.org/package/crypton-conduit) -[](http://stackage.org/nightly/package/crypton-conduit) -[](http://stackage.org/lts/package/crypton-conduit) -[](https://github.com/psibi/crypton-conduit/actions/workflows/tests.yml) - -This is a fork of cryponite-conduit. For more details [see here](https://github.com/yesodweb/wai/pull/931). - -Simple conduit wrapper for crypton hashes, and maybe further construction as needed. +crypton-conduit+==================++[](https://hackage.haskell.org/package/crypton-conduit)+[](http://stackage.org/nightly/package/crypton-conduit)+[](http://stackage.org/lts/package/crypton-conduit)+[](https://github.com/psibi/crypton-conduit/actions/workflows/tests.yml)++This is a fork of cryponite-conduit. For more details [see here](https://github.com/yesodweb/wai/pull/931).++Simple conduit wrapper for crypton hashes, and maybe further construction as needed.
Setup.hs view
@@ -1,2 +1,2 @@-import Distribution.Simple -main = defaultMain +import Distribution.Simple+main = defaultMain
crypton-conduit.cabal view
@@ -1,58 +1,58 @@-Name: crypton-conduit -version: 0.3.0 -Synopsis: crypton conduit -Description: - Conduit bridge for crypton - . - For now only provide a conduit version for hash and hmac, but - with contribution, this could provide cipher conduits too, - and probably other things. -License: BSD3 -License-file: LICENSE -Copyright: Vincent Hanquez <vincent@snarc.org> -Author: Vincent Hanquez <vincent@snarc.org> -Maintainer: Sibi Prabakaran <sibi@psibi.in> -Category: Cryptography, Conduit -Stability: experimental -Build-Type: Simple -Homepage: https://github.com/psibi/crypton-conduit -Cabal-Version: >= 1.10 -Extra-source-files: README.md CHANGELOG.md - -Library - Exposed-modules: Crypto.Cipher.ChaChaPoly1305.Conduit - Crypto.MAC.HMAC.Conduit - Crypto.Hash.Conduit - Crypto.PubKey.ECIES.Conduit - Build-depends: base >= 4 && < 5 - , bytestring - , conduit - , conduit-extra - , crypton >= 1.1.0 - , exceptions - , ram - , resourcet - , transformers - ghc-options: -Wall -fwarn-tabs - default-language: Haskell2010 - -test-suite crypton-conduit-test - type: exitcode-stdio-1.0 - hs-source-dirs: test - main-is: Spec.hs - build-depends: base - , bytestring - , conduit - , conduit-combinators - , crypton >= 1.1.0 - , crypton-conduit - , ram - , tasty - , tasty-hunit - , tasty-quickcheck - ghc-options: -Wall - default-language: Haskell2010 - -source-repository head - type: git - location: https://github.com/psibi/crypton-conduit +Name: crypton-conduit+version: 0.3.1+Synopsis: crypton conduit+Description:+ Conduit bridge for crypton+ .+ For now only provide a conduit version for hash and hmac, but+ with contribution, this could provide cipher conduits too,+ and probably other things.+License: BSD3+License-file: LICENSE+Copyright: Vincent Hanquez <vincent@snarc.org>+Author: Vincent Hanquez <vincent@snarc.org>+Maintainer: Sibi Prabakaran <sibi@psibi.in>+Category: Cryptography, Conduit+Stability: experimental+Build-Type: Simple+Homepage: https://github.com/psibi/crypton-conduit+Cabal-Version: >= 1.10+Extra-source-files: README.md CHANGELOG.md++Library+ Exposed-modules: Crypto.Cipher.ChaChaPoly1305.Conduit+ Crypto.MAC.HMAC.Conduit+ Crypto.Hash.Conduit+ Crypto.PubKey.ECIES.Conduit+ Build-depends: base >= 4 && < 5+ , bytestring+ , conduit+ , conduit-extra+ , crypton >= 1.1.0+ , exceptions+ , ram+ , resourcet+ , transformers+ ghc-options: -Wall -fwarn-tabs+ default-language: Haskell2010++test-suite crypton-conduit-test+ type: exitcode-stdio-1.0+ hs-source-dirs: test+ main-is: Spec.hs+ build-depends: base+ , bytestring+ , conduit+ , conduit-combinators+ , crypton >= 1.1.0+ , crypton-conduit+ , ram+ , tasty+ , tasty-hunit+ , tasty-quickcheck+ ghc-options: -Wall+ default-language: Haskell2010++source-repository head+ type: git+ location: https://github.com/psibi/crypton-conduit
test/Spec.hs view
@@ -1,63 +1,63 @@-{-# Language OverloadedStrings #-} -import Conduit -import qualified Crypto.Cipher.ChaChaPoly1305.Conduit as ChaCha -import qualified Crypto.ECC as ECC -import Crypto.Hash -import Crypto.MAC.HMAC -import Crypto.MAC.HMAC.Conduit -import qualified Crypto.PubKey.ECIES.Conduit as PubKey -import Crypto.Random -import Data.ByteArray.Encoding -import Data.Proxy (Proxy (..)) -import Data.Word (Word8) -import Test.Tasty -import Test.Tasty.HUnit -import Test.Tasty.QuickCheck -import qualified Data.ByteString as BS -import qualified Data.ByteString.Lazy as BL - -main :: IO () -main = defaultMain tests - -tests :: TestTree -tests = testGroup "Crypton conduit tests" - [ testGroup "HMAC" - [ testCase "File HMAC is correct" testFileHMAC - ] - , testGroup "ChaChaPoly1305" - [ testProperty "encrypt/decrypt works" (ioProperty . propChaChaPoly1305) - ] - , testGroup "publicECC" - [ testProperty "encrypt/decrypt works" (ioProperty . propPublicECC) - ] - ] - -testFileHMAC :: Assertion -testFileHMAC = do - let source = BL.take (1024 * 1024 * 3 + 150) $ BL.iterate (+ 1) 0 - testhmac <- runConduit $ sourceLazy source .| sinkHMAC ("foobar" :: BS.ByteString) - let hexdump = convertToBase Base16 (testhmac :: HMAC SHA512t_256) - assertEqual "HMAC mismatch" "ab78ef7a3a7b02b2ef50ee1a17e43ae0c134e0bece468b047780626264301831" (hexdump :: BS.ByteString) - -propChaChaPoly1305 :: [[Word8]] -> IO Bool -propChaChaPoly1305 octets = do - let chunksIn = map BS.pack octets - nonce <- getRandomBytes 12 - key <- getRandomBytes 32 - chunksOut <- runConduit - $ mapM_ yield chunksIn - .| ChaCha.encrypt nonce key - .| ChaCha.decrypt key - .| sinkLazy - return $ BL.fromChunks chunksIn == chunksOut - -propPublicECC :: [[Word8]] -> IO Bool -propPublicECC octets = do - let chunksIn = map BS.pack octets - ECC.KeyPair point scalar <- ECC.curveGenerateKeyPair (Proxy :: Proxy ECC.Curve_P256R1) - chunksOut <- runConduit - $ mapM_ yield chunksIn - .| PubKey.encrypt point - .| PubKey.decrypt scalar - .| sinkLazy - return $ BL.fromChunks chunksIn == chunksOut +{-# Language OverloadedStrings #-}+import Conduit+import qualified Crypto.Cipher.ChaChaPoly1305.Conduit as ChaCha+import qualified Crypto.ECC as ECC+import Crypto.Hash+import Crypto.MAC.HMAC+import Crypto.MAC.HMAC.Conduit+import qualified Crypto.PubKey.ECIES.Conduit as PubKey+import Crypto.Random+import Data.ByteArray.Encoding+import Data.Proxy (Proxy (..))+import Data.Word (Word8)+import Test.Tasty+import Test.Tasty.HUnit+import Test.Tasty.QuickCheck+import qualified Data.ByteString as BS+import qualified Data.ByteString.Lazy as BL++main :: IO ()+main = defaultMain tests++tests :: TestTree+tests = testGroup "Crypton conduit tests"+ [ testGroup "HMAC"+ [ testCase "File HMAC is correct" testFileHMAC+ ]+ , testGroup "ChaChaPoly1305"+ [ testProperty "encrypt/decrypt works" (ioProperty . propChaChaPoly1305)+ ]+ , testGroup "publicECC"+ [ testProperty "encrypt/decrypt works" (ioProperty . propPublicECC)+ ]+ ]++testFileHMAC :: Assertion+testFileHMAC = do+ let source = BL.take (1024 * 1024 * 3 + 150) $ BL.iterate (+ 1) 0+ testhmac <- runConduit $ sourceLazy source .| sinkHMAC ("foobar" :: BS.ByteString)+ let hexdump = convertToBase Base16 (testhmac :: HMAC SHA512t_256)+ assertEqual "HMAC mismatch" "ab78ef7a3a7b02b2ef50ee1a17e43ae0c134e0bece468b047780626264301831" (hexdump :: BS.ByteString)++propChaChaPoly1305 :: [[Word8]] -> IO Bool+propChaChaPoly1305 octets = do+ let chunksIn = map BS.pack octets+ nonce <- getRandomBytes 12+ key <- getRandomBytes 32+ chunksOut <- runConduit+ $ mapM_ yield chunksIn+ .| ChaCha.encrypt nonce key+ .| ChaCha.decrypt key+ .| sinkLazy+ return $ BL.fromChunks chunksIn == chunksOut++propPublicECC :: [[Word8]] -> IO Bool+propPublicECC octets = do+ let chunksIn = map BS.pack octets+ ECC.KeyPair point scalar <- ECC.curveGenerateKeyPair (Proxy :: Proxy ECC.Curve_P256R1)+ chunksOut <- runConduit+ $ mapM_ yield chunksIn+ .| PubKey.encrypt point+ .| PubKey.decrypt scalar+ .| sinkLazy+ return $ BL.fromChunks chunksIn == chunksOut