Hello community,
here is the log from the commit of package ghc-cryptonite-conduit for
openSUSE:Factory checked in at 2018-05-30 12:06:23
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-cryptonite-conduit (Old)
and /work/SRC/openSUSE:Factory/.ghc-cryptonite-conduit.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ghc-cryptonite-conduit"
Wed May 30 12:06:23 2018 rev:4 rq:607778 version:0.2.2
Changes:
--------
---
/work/SRC/openSUSE:Factory/ghc-cryptonite-conduit/ghc-cryptonite-conduit.changes
2017-09-15 21:29:49.991184475 +0200
+++
/work/SRC/openSUSE:Factory/.ghc-cryptonite-conduit.new/ghc-cryptonite-conduit.changes
2018-05-30 12:25:21.286232709 +0200
@@ -1,0 +2,7 @@
+Mon May 14 17:02:11 UTC 2018 - [email protected]
+
+- Update cryptonite-conduit to version 0.2.2.
+ * Add the `Crypto.Cipher.ChaChaPoly1305.Conduit` and
+ `Crypto.PubKey.ECIES.Conduit` modules
+
+-------------------------------------------------------------------
Old:
----
cryptonite-conduit-0.2.0.tar.gz
New:
----
cryptonite-conduit-0.2.2.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ ghc-cryptonite-conduit.spec ++++++
--- /var/tmp/diff_new_pack.9AFoVl/_old 2018-05-30 12:25:22.046207805 +0200
+++ /var/tmp/diff_new_pack.9AFoVl/_new 2018-05-30 12:25:22.050207674 +0200
@@ -1,7 +1,7 @@
#
# spec file for package ghc-cryptonite-conduit
#
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
%global pkg_name cryptonite-conduit
%bcond_with tests
Name: ghc-%{pkg_name}
-Version: 0.2.0
+Version: 0.2.2
Release: 0
Summary: Cryptonite conduit
License: BSD-3-Clause
@@ -31,6 +31,7 @@
BuildRequires: ghc-conduit-devel
BuildRequires: ghc-conduit-extra-devel
BuildRequires: ghc-cryptonite-devel
+BuildRequires: ghc-exceptions-devel
BuildRequires: ghc-memory-devel
BuildRequires: ghc-resourcet-devel
BuildRequires: ghc-rpm-macros
@@ -39,6 +40,7 @@
BuildRequires: ghc-conduit-combinators-devel
BuildRequires: ghc-tasty-devel
BuildRequires: ghc-tasty-hunit-devel
+BuildRequires: ghc-tasty-quickcheck-devel
%endif
%description
@@ -79,9 +81,9 @@
%ghc_pkg_recache
%files -f %{name}.files
-%doc LICENSE
+%license LICENSE
%files devel -f %{name}-devel.files
-%doc README.md
+%doc CHANGELOG.md README.md
%changelog
++++++ cryptonite-conduit-0.2.0.tar.gz -> cryptonite-conduit-0.2.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cryptonite-conduit-0.2.0/CHANGELOG.md
new/cryptonite-conduit-0.2.2/CHANGELOG.md
--- old/cryptonite-conduit-0.2.0/CHANGELOG.md 1970-01-01 01:00:00.000000000
+0100
+++ new/cryptonite-conduit-0.2.2/CHANGELOG.md 2017-07-10 19:03:17.000000000
+0200
@@ -0,0 +1,12 @@
+## 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
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/cryptonite-conduit-0.2.0/Crypto/Cipher/ChaChaPoly1305/Conduit.hs
new/cryptonite-conduit-0.2.2/Crypto/Cipher/ChaChaPoly1305/Conduit.hs
--- old/cryptonite-conduit-0.2.0/Crypto/Cipher/ChaChaPoly1305/Conduit.hs
1970-01-01 01:00:00.000000000 +0100
+++ new/cryptonite-conduit-0.2.2/Crypto/Cipher/ChaChaPoly1305/Conduit.hs
2017-07-10 19:03:17.000000000 +0200
@@ -0,0 +1,88 @@
+{-# 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')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/cryptonite-conduit-0.2.0/Crypto/PubKey/ECIES/Conduit.hs
new/cryptonite-conduit-0.2.2/Crypto/PubKey/ECIES/Conduit.hs
--- old/cryptonite-conduit-0.2.0/Crypto/PubKey/ECIES/Conduit.hs 1970-01-01
01:00:00.000000000 +0100
+++ new/cryptonite-conduit-0.2.2/Crypto/PubKey/ECIES/Conduit.hs 2017-07-10
19:03:17.000000000 +0200
@@ -0,0 +1,80 @@
+{-# 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
+#if MIN_VERSION_cryptonite(0,23,999)
+ deriveEncryptCompat prx p = deriveEncrypt prx p
+#else
+ deriveEncryptCompat prx p = CE.CryptoPassed <$> deriveEncrypt prx p
+#endif
+
+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
+#if MIN_VERSION_cryptonite(0,23,999)
+ deriveDecryptCompat prx p s = deriveDecrypt prx p s
+#else
+ deriveDecryptCompat prx p s = CE.CryptoPassed (deriveDecrypt prx p s)
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cryptonite-conduit-0.2.0/cryptonite-conduit.cabal
new/cryptonite-conduit-0.2.2/cryptonite-conduit.cabal
--- old/cryptonite-conduit-0.2.0/cryptonite-conduit.cabal 2017-02-06
10:34:29.000000000 +0100
+++ new/cryptonite-conduit-0.2.2/cryptonite-conduit.cabal 2017-11-17
10:06:42.000000000 +0100
@@ -1,5 +1,5 @@
Name: cryptonite-conduit
-Version: 0.2.0
+version: 0.2.2
Synopsis: cryptonite conduit
Description:
Conduit bridge for cryptonite
@@ -17,16 +17,19 @@
Build-Type: Simple
Homepage: https://github.com/haskell-crypto/cryptonite-conduit
Cabal-Version: >=1.8
-Extra-source-files: README.md
+Extra-source-files: README.md CHANGELOG.md
Library
- Exposed-modules: Crypto.MAC.HMAC.Conduit
+ 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
, cryptonite
+ , exceptions
, memory
, resourcet
, transformers
@@ -45,7 +48,8 @@
, memory
, tasty
, tasty-hunit
- ghc-options: -threaded -rtsopts -with-rtsopts=-N -W -Wall
+ , tasty-quickcheck
+ ghc-options: -Wall
source-repository head
type: git
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cryptonite-conduit-0.2.0/test/Spec.hs
new/cryptonite-conduit-0.2.2/test/Spec.hs
--- old/cryptonite-conduit-0.2.0/test/Spec.hs 2017-02-06 10:33:56.000000000
+0100
+++ new/cryptonite-conduit-0.2.2/test/Spec.hs 2017-07-10 19:03:17.000000000
+0200
@@ -1,11 +1,18 @@
{-# 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
@@ -17,6 +24,12 @@
[ 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
@@ -25,3 +38,26 @@
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