Hello community,

here is the log from the commit of package ghc-cryptonite for openSUSE:Factory 
checked in at 2016-10-19 13:03:28
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-cryptonite (Old)
 and      /work/SRC/openSUSE:Factory/.ghc-cryptonite.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ghc-cryptonite"

Changes:
--------
--- /work/SRC/openSUSE:Factory/ghc-cryptonite/ghc-cryptonite.changes    
2016-07-21 08:05:48.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.ghc-cryptonite.new/ghc-cryptonite.changes       
2016-10-19 13:03:30.000000000 +0200
@@ -1,0 +2,5 @@
+Thu Sep 15 06:34:53 UTC 2016 - psim...@suse.com
+
+- Update to version 0.19 revision 0 with cabal2obs.
+
+-------------------------------------------------------------------

Old:
----
  cryptonite-0.15.tar.gz

New:
----
  cryptonite-0.19.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ghc-cryptonite.spec ++++++
--- /var/tmp/diff_new_pack.xqhVDd/_old  2016-10-19 13:03:31.000000000 +0200
+++ /var/tmp/diff_new_pack.xqhVDd/_new  2016-10-19 13:03:31.000000000 +0200
@@ -19,15 +19,14 @@
 %global pkg_name cryptonite
 %bcond_with tests
 Name:           ghc-%{pkg_name}
-Version:        0.15
+Version:        0.19
 Release:        0
 Summary:        Cryptography Primitives sink
 License:        BSD-3-Clause
-Group:          System/Libraries
+Group:          Development/Languages/Other
 Url:            https://hackage.haskell.org/package/%{pkg_name}
 Source0:        
https://hackage.haskell.org/package/%{pkg_name}-%{version}/%{pkg_name}-%{version}.tar.gz
 BuildRequires:  ghc-Cabal-devel
-# Begin cabal-rpm deps:
 BuildRequires:  ghc-bytestring-devel
 BuildRequires:  ghc-deepseq-devel
 BuildRequires:  ghc-memory-devel
@@ -40,7 +39,6 @@
 BuildRequires:  ghc-tasty-kat-devel
 BuildRequires:  ghc-tasty-quickcheck-devel
 %endif
-# End cabal-rpm deps
 
 %description
 A repository of cryptographic primitives.
@@ -52,7 +50,7 @@
 
 * MAC: HMAC, Poly1305
 
-* Assymmetric crypto: DSA, RSA, DH, ECDH, ECDSA, ECC, Curve25519, Ed25519
+* Asymmetric crypto: DSA, RSA, DH, ECDH, ECDSA, ECC, Curve25519, Ed25519, Ed448
 
 * Key Derivation Function: PBKDF2, Scrypt, HKDF
 
@@ -67,6 +65,8 @@
 
 Evaluate the security related to your requirements before using.
 
+Read "Crypto.Tutorial" for a quick start guide.
+
 %package devel
 Summary:        Haskell %{pkg_name} library development files
 Group:          Development/Libraries/Other
@@ -81,21 +81,15 @@
 %prep
 %setup -q -n %{pkg_name}-%{version}
 
-
 %build
-%define cabal_configure_options -f"-support_aesni -support_rdrand 
-support_blake2_sse"
+%define cabal_configure_options -f-support_aesni -f-support_rdrand 
-f-support_blake2_sse
 %ghc_lib_build
 
-
 %install
 %ghc_lib_install
 
-
 %check
-%if %{with tests}
-%{cabal} test
-%endif
-
+%cabal_test
 
 %post devel
 %ghc_pkg_recache

++++++ cryptonite-0.15.tar.gz -> cryptonite-0.19.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cryptonite-0.15/CHANGELOG.md 
new/cryptonite-0.19/CHANGELOG.md
--- old/cryptonite-0.15/CHANGELOG.md    2016-04-09 18:16:13.000000000 +0200
+++ new/cryptonite-0.19/CHANGELOG.md    2016-08-12 08:14:25.000000000 +0200
@@ -1,3 +1,25 @@
+## 0.19
+
+* Add tutorial (Yann Esposito)
+* Derive Show instance for better interaction with Show pretty printer (Eric 
Mertens)
+
+## 0.18
+
+* Re-used standard rdrand instructions instead of bytedump of rdrand 
instruction
+* Improvement to F2m, including lots of tests (Andrew Lelechenko)
+
+## 0.17
+
+* Add Miyaguchi-Preneel construction (Kei Hibino)
+* Fix buffer length in scrypt (Luke Taylor)
+* build fixes for i686 and arm related to rdrand
+
+## 0.16
+
+* Fix basepoint for Ed448
+
+* Enable 64-bit Curve25519 implementation
+
 ## 0.15
 
 * Fix serialization of DH and ECDH
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cryptonite-0.15/Crypto/Cipher/Blowfish/Primitive.hs 
new/cryptonite-0.19/Crypto/Cipher/Blowfish/Primitive.hs
--- old/cryptonite-0.15/Crypto/Cipher/Blowfish/Primitive.hs     2016-04-09 
18:16:13.000000000 +0200
+++ new/cryptonite-0.19/Crypto/Cipher/Blowfish/Primitive.hs     2016-08-12 
08:14:25.000000000 +0200
@@ -79,7 +79,9 @@
 -- Cost must be between 4 and 31 inclusive
 -- See 
<https://www.usenix.org/conference/1999-usenix-annual-technical-conference/future-adaptable-password-scheme>
 eksBlowfish :: (ByteArrayAccess salt, ByteArrayAccess password) => Int -> salt 
-> password -> Context
-eksBlowfish cost salt key = makeKeySchedule key (Just (salt, cost))
+eksBlowfish cost salt key
+    | B.length salt /= 16 = error "bcrypt salt must be 16 bytes"
+    | otherwise           = makeKeySchedule key (Just (salt, cost))
 
 coreCrypto :: Context -> Word64 -> Word64
 coreCrypto (BF p s0 s1 s2 s3) input = doRound input 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/cryptonite-0.15/Crypto/ConstructHash/MiyaguchiPreneel.hs 
new/cryptonite-0.19/Crypto/ConstructHash/MiyaguchiPreneel.hs
--- old/cryptonite-0.15/Crypto/ConstructHash/MiyaguchiPreneel.hs        
1970-01-01 01:00:00.000000000 +0100
+++ new/cryptonite-0.19/Crypto/ConstructHash/MiyaguchiPreneel.hs        
2016-08-12 08:14:25.000000000 +0200
@@ -0,0 +1,68 @@
+-- |
+-- Module      : Crypto.ConstructHash.MiyaguchiPreneel
+-- License     : BSD-style
+-- Maintainer  : Kei Hibino <ex8k.hib...@gmail.com>
+-- Stability   : experimental
+-- Portability : unknown
+--
+-- provide the hash function construction method from block cipher
+-- <https://en.wikipedia.org/wiki/One-way_compression_function>
+--
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module Crypto.ConstructHash.MiyaguchiPreneel
+       ( compute, compute'
+       , MiyaguchiPreneel
+       ) where
+
+import           Data.List (foldl')
+
+import           Crypto.Data.Padding (pad, Format (ZERO))
+import           Crypto.Cipher.Types
+import           Crypto.Error (throwCryptoError)
+import           Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray, Bytes)
+import qualified Crypto.Internal.ByteArray as B
+
+
+newtype MiyaguchiPreneel a = MP Bytes
+    deriving (ByteArrayAccess)
+
+instance Eq (MiyaguchiPreneel a) where
+    MP b1 == MP b2  =  B.constEq b1 b2
+
+
+-- | Compute Miyaguchi-Preneel one way compress using the supplied block 
cipher.
+compute' :: (ByteArrayAccess bin, BlockCipher cipher)
+         => (Bytes -> cipher)       -- ^ key build function to compute 
Miyaguchi-Preneel. care about block-size and key-size
+         -> bin                     -- ^ input message
+         -> MiyaguchiPreneel cipher -- ^ output tag
+compute' g = MP . foldl' (step $ g) (B.replicate bsz 0) . chunks . pad (ZERO 
bsz) . B.convert
+  where
+    bsz = blockSize ( g B.empty {- dummy to get block size -} )
+    chunks msg
+      | B.null msg  =  []
+      | otherwise  =   (hd :: Bytes) : chunks tl
+      where
+        (hd, tl) = B.splitAt bsz msg
+
+-- | Compute Miyaguchi-Preneel one way compress using the infered block cipher.
+--   Only safe when KEY-SIZE equals to BLOCK-SIZE.
+--
+--   Simple usage /mp' msg :: MiyaguchiPreneel AES128/
+compute :: (ByteArrayAccess bin, BlockCipher cipher)
+        => bin                     -- ^ input message
+        -> MiyaguchiPreneel cipher -- ^ output tag
+compute = compute' $ throwCryptoError . cipherInit
+
+-- | computation step of Miyaguchi-Preneel
+step :: (ByteArray ba, BlockCipher k)
+     => (ba -> k)
+     -> ba
+     -> ba
+     -> ba
+step g iv msg =
+    ecbEncrypt k msg `bxor` iv `bxor` msg
+  where
+    k = g iv
+
+bxor :: ByteArray ba => ba -> ba -> ba
+bxor = B.xor
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cryptonite-0.15/Crypto/Data/Padding.hs 
new/cryptonite-0.19/Crypto/Data/Padding.hs
--- old/cryptonite-0.15/Crypto/Data/Padding.hs  2016-04-09 18:16:13.000000000 
+0200
+++ new/cryptonite-0.19/Crypto/Data/Padding.hs  2016-08-12 08:14:25.000000000 
+0200
@@ -21,6 +21,7 @@
 data Format =
       PKCS5     -- ^ PKCS5: PKCS7 with hardcoded size of 8
     | PKCS7 Int -- ^ PKCS7 with padding size between 1 and 255
+    | ZERO Int  -- ^ zero padding with block size
     deriving (Show, Eq)
 
 -- | Apply some pad to a bytearray
@@ -30,6 +31,15 @@
   where
     paddingString = B.replicate paddingByte (fromIntegral paddingByte)
     paddingByte   = sz - (B.length bin `mod` sz)
+pad (ZERO sz)  bin = bin `B.append` paddingString
+  where
+    paddingString = B.replicate paddingSz 0
+    paddingSz
+      | len == 0   =  sz
+      | m == 0     =  0
+      | otherwise  =  sz - m
+    m = len `mod` sz
+    len = B.length bin
 
 -- | Try to remove some padding from a bytearray.
 unpad :: ByteArray byteArray => Format -> byteArray -> Maybe byteArray
@@ -46,3 +56,10 @@
     paddingSz   = fromIntegral paddingByte
     (content, padding) = B.splitAt (len - paddingSz) bin
     paddingWitness     = B.replicate paddingSz paddingByte :: Bytes
+unpad (ZERO sz)  bin
+    | len == 0                           = Nothing
+    | (len `mod` sz) /= 0                = Nothing
+    | B.index bin (len - 1) /= 0         = Just bin
+    | otherwise                          = Nothing
+  where
+    len         = B.length bin
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cryptonite-0.15/Crypto/Error/Types.hs 
new/cryptonite-0.19/Crypto/Error/Types.hs
--- old/cryptonite-0.15/Crypto/Error/Types.hs   2016-04-09 18:16:13.000000000 
+0200
+++ new/cryptonite-0.19/Crypto/Error/Types.hs   2016-08-12 08:14:25.000000000 
+0200
@@ -52,10 +52,8 @@
 data CryptoFailable a =
       CryptoPassed a
     | CryptoFailed CryptoError
+    deriving (Show)
 
-instance Show a => Show (CryptoFailable a) where
-    show (CryptoPassed a)   = "CryptoPassed " ++ show a
-    show (CryptoFailed err) = "CryptoFailed " ++ show err
 instance Eq a => Eq (CryptoFailable a) where
     (==) (CryptoPassed a)  (CryptoPassed b)  = a == b
     (==) (CryptoFailed e1) (CryptoFailed e2) = e1 == e2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cryptonite-0.15/Crypto/KDF/Scrypt.hs 
new/cryptonite-0.19/Crypto/KDF/Scrypt.hs
--- old/cryptonite-0.15/Crypto/KDF/Scrypt.hs    2016-04-09 18:16:13.000000000 
+0200
+++ new/cryptonite-0.19/Crypto/KDF/Scrypt.hs    2016-08-12 08:14:25.000000000 
+0200
@@ -53,7 +53,7 @@
         let b = PBKDF2.generate prf (PBKDF2.Parameters 1 intLen) password salt 
:: B.Bytes
         newSalt <- B.copy b $ \bPtr ->
             allocaBytesAligned (128*(fromIntegral $ n params)*(r params)) 8 $ 
\v ->
-            allocaBytesAligned (256*r params) 8 $ \xy -> do
+            allocaBytesAligned (256*r params + 64) 8 $ \xy -> do
                 forM_ [0..(p params-1)] $ \i ->
                     ccryptonite_scrypt_smix (bPtr `plusPtr` (i * 128 * (r 
params)))
                                             (fromIntegral $ r params) (n 
params) v xy
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cryptonite-0.15/Crypto/Number/F2m.hs 
new/cryptonite-0.19/Crypto/Number/F2m.hs
--- old/cryptonite-0.15/Crypto/Number/F2m.hs    2016-04-09 18:16:13.000000000 
+0200
+++ new/cryptonite-0.19/Crypto/Number/F2m.hs    2016-08-12 08:14:25.000000000 
+0200
@@ -9,100 +9,133 @@
 -- not optimal and it doesn't provide protection against timing
 -- attacks. The 'm' parameter is implicitly derived from the irreducible
 -- polynomial where applicable.
+
 module Crypto.Number.F2m
     ( BinaryPolynomial
     , addF2m
     , mulF2m
+    , squareF2m'
     , squareF2m
     , modF2m
     , invF2m
     , divF2m
     ) where
 
-import Data.Bits ((.&.),(.|.),xor,shift,testBit)
-import Crypto.Number.Basic
+import Data.Bits (xor, shift, testBit, setBit)
+import Data.List
 import Crypto.Internal.Imports
+import Crypto.Number.Basic
 
 -- | Binary Polynomial represented by an integer
 type BinaryPolynomial = Integer
 
--- | Addition over F₂m. This is just a synonym of  'xor'.
-addF2m :: Integer -> Integer -> Integer
+-- | Addition over F₂m. This is just a synonym of 'xor'.
+addF2m :: Integer
+       -> Integer
+       -> Integer
 addF2m = xor
 {-# INLINE addF2m #-}
 
--- | Binary polynomial reduction modulo using long division algorithm.
-modF2m :: BinaryPolynomial -- ^ Irreducible binary polynomial
-       -> Integer -> Integer
-modF2m fx = go
-  where
-    lfx = log2 fx
-    go n | s == 0  = n `xor` fx
-         | s < 0 = n
-         | otherwise = go $ n `xor` shift fx s
+-- | Reduction by modulo over F₂m.
+--
+-- This function is undefined for negative arguments, because their bit
+-- representation is platform-dependent. Zero modulus is also prohibited.
+modF2m :: BinaryPolynomial -- ^ Modulus
+       -> Integer
+       -> Integer
+modF2m fx i
+    | fx < 0 || i < 0 = error "modF2m: negative number represent no binary 
polynomial"
+    | fx == 0         = error "modF2m: cannot divide by zero polynomial"
+    | fx == 1         = 0
+    | otherwise       = go i
       where
-        s = log2 n - lfx
+        lfx = log2 fx
+        go n | s == 0    = n `addF2m` fx
+             | s < 0     = n
+             | otherwise = go $ n `addF2m` shift fx s
+                where s = log2 n - lfx
 {-# INLINE modF2m #-}
 
 -- | Multiplication over F₂m.
 --
---     n1 * n2 (in F(2^m))
-mulF2m :: BinaryPolynomial  -- ^ Irreducible binary polynomial
-       -> Integer -> Integer -> Integer
-mulF2m fx n1 n2 = modF2m fx
-                $ go (if n2 `mod` 2 == 1 then n1 else 0) (log2 n2)
-  where
-    go n s | s == 0  = n
-           | otherwise = if testBit n2 s
-                            then go (n `xor` shift n1 s) (s - 1)
-                            else go n (s - 1)
+-- This function is undefined for negative arguments, because their bit
+-- representation is platform-dependent. Zero modulus is also prohibited.
+mulF2m :: BinaryPolynomial -- ^ Modulus
+       -> Integer
+       -> Integer
+       -> Integer
+mulF2m fx n1 n2
+    |    fx < 0
+      || n1 < 0
+      || n2 < 0 = error "mulF2m: negative number represent no binary binary 
polynomial"
+    | fx == 0   = error "modF2m: cannot multiply modulo zero polynomial"
+    | otherwise = modF2m fx $ go (if n2 `mod` 2 == 1 then n1 else 0) (log2 n2)
+      where
+        go n s | s == 0  = n
+               | otherwise = if testBit n2 s
+                                then go (n `addF2m` shift n1 s) (s - 1)
+                                else go n (s - 1)
 {-# INLINABLE mulF2m #-}
 
 -- | Squaring over F₂m.
--- TODO: This is still slower than @mulF2m@.
-
--- Multiplication table? C?
-squareF2m :: BinaryPolynomial  -- ^ Irreducible binary polynomial
-          -> Integer -> Integer
-squareF2m fx = modF2m fx . square
+--
+-- This function is undefined for negative arguments, because their bit
+-- representation is platform-dependent. Zero modulus is also prohibited.
+squareF2m :: BinaryPolynomial -- ^ Modulus
+          -> Integer
+          -> Integer
+squareF2m fx = modF2m fx . squareF2m'
 {-# INLINE squareF2m #-}
 
-square :: Integer -> Integer
-square n1 = go n1 ln1
+-- | Squaring over F₂m without reduction by modulo.
+--
+-- The implementation utilizes the fact that for binary polynomial S(x) we have
+-- S(x)^2 = S(x^2). In other words, insert a zero bit between every bits of 
argument: 1101 -> 1010001.
+--
+-- This function is undefined for negative arguments, because their bit
+-- representation is platform-dependent.
+squareF2m' :: Integer
+           -> Integer
+squareF2m' n
+    | n < 0     = error "mulF2m: negative number represent no binary binary 
polynomial"
+    | otherwise = foldl' (\acc s -> if testBit n s then setBit acc (2 * s) 
else acc) 0 [0 .. log2 n]
+{-# INLINE squareF2m' #-}
+
+-- | Extended GCD algorithm for polynomials. For @a@ and @b@ returns @(g, u, 
v)@ such that @a * u + b * v == g@.
+--
+-- Reference: 
https://en.wikipedia.org/wiki/Polynomial_greatest_common_divisor#B.C3.A9zout.27s_identity_and_extended_GCD_algorithm
+gcdF2m :: Integer
+       -> Integer
+       -> (Integer, Integer, Integer)
+gcdF2m a b = go (a, b, 1, 0, 0, 1)
   where
-    ln1 = log2 n1
-    go n s | s == 0 = n
-           | otherwise = go (x .|. y) (s - 1)
-      where
-        x = shift (shift n (2 * (s - ln1) - 1)) (2 * (ln1 - s) + 2)
-        y = n .&. (shift 1 (2 * (ln1 - s) + 1) - 1)
-{-# INLINE square #-}
-
--- | Inversion of @n over F₂m using extended Euclidean algorithm.
---
--- If @n doesn't have an inverse, Nothing is returned.
-invF2m :: BinaryPolynomial -- ^ Irreducible binary polynomial
-       -> Integer -> Maybe Integer
-invF2m _  0 = Nothing
-invF2m fx n
-    | n >= fx   = Nothing
-    | otherwise = go n fx 1 0
-    where
-      go u v g1 g2
-          | u == 1    = Just $ modF2m fx g1
-          | j < 0     = go u  (v  `xor` shift  u (-j)) g1 (g2 `xor` shift g1 
(-j))
-          | otherwise = go (u  `xor` shift v  j) v (g1 `xor` shift g2 j) g2
-        where
-          j = log2 u - log2 v
+    go (g, 0, u, _, v, _)
+        = (g, u, v)
+    go (r0, r1, s0, s1, t0, t1)
+        = go (r1, r0 `addF2m` shift r1 j, s1, s0 `addF2m` shift s1 j, t1, t0 
`addF2m` shift t1 j)
+            where j = max 0 (log2 r0 - log2 r1)
+
+-- | Modular inversion over F₂m.
+-- If @n@ doesn't have an inverse, 'Nothing' is returned.
+--
+-- This function is undefined for negative arguments, because their bit
+-- representation is platform-dependent. Zero modulus is also prohibited.
+invF2m :: BinaryPolynomial -- ^ Modulus
+       -> Integer
+       -> Maybe Integer
+invF2m fx n = if g == 1 then Just (modF2m fx u) else Nothing
+  where
+    (g, u, _) = gcdF2m n fx
 {-# INLINABLE invF2m #-}
 
 -- | Division over F₂m. If the dividend doesn't have an inverse it returns
 -- 'Nothing'.
 --
--- Compute n1 / n2
-divF2m :: BinaryPolynomial  -- ^ Irreducible binary polynomial
-       -> Integer  -- ^ Dividend
-       -> Integer  -- ^ Quotient
-       -> Maybe Integer
+-- This function is undefined for negative arguments, because their bit
+-- representation is platform-dependent. Zero modulus is also prohibited.
+divF2m :: BinaryPolynomial -- ^ Modulus
+       -> Integer          -- ^ Dividend
+       -> Integer          -- ^ Divisor
+       -> Maybe Integer    -- ^ Quotient
 divF2m fx n1 n2 = mulF2m fx n1 <$> invF2m fx n2
 {-# INLINE divF2m #-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cryptonite-0.15/Crypto/PubKey/ECC/Prim.hs 
new/cryptonite-0.19/Crypto/PubKey/ECC/Prim.hs
--- old/cryptonite-0.15/Crypto/PubKey/ECC/Prim.hs       2016-04-09 
18:16:13.000000000 +0200
+++ new/cryptonite-0.19/Crypto/PubKey/ECC/Prim.hs       2016-08-12 
08:14:25.000000000 +0200
@@ -26,6 +26,13 @@
 
 --TODO: Extract helper function for `fromMaybe PointO...`
 
+-- | Elliptic Curve point negation:
+-- @pointNegate c p@ returns point @q@ such that @pointAdd c p q == PointO@.
+pointNegate :: Curve -> Point -> Point
+pointNegate _           PointO     = PointO
+pointNegate CurveFP{}  (Point x y) = Point x (-y)
+pointNegate CurveF2m{} (Point x y) = Point x (x `addF2m` y)
+
 -- | Elliptic Curve point addition.
 --
 -- /WARNING:/ Vulnerable to timing attacks.
@@ -33,22 +40,21 @@
 pointAdd _ PointO PointO = PointO
 pointAdd _ PointO q = q
 pointAdd _ p PointO = p
-pointAdd c@(CurveFP (CurvePrime pr _)) p@(Point xp yp) q@(Point xq yq)
-    | p == Point xq (-yq) = PointO
-    | p == q = pointDouble c p
-    | otherwise = fromMaybe PointO $ do
-                      s <- divmod (yp - yq) (xp - xq) pr
-                      let xr = (s ^ (2::Int) - xp - xq) `mod` pr
-                          yr = (s * (xp - xr) - yp) `mod` pr
-                      return $ Point xr yr
-pointAdd c@(CurveF2m (CurveBinary fx cc)) p@(Point xp yp) q@(Point xq yq)
-    | p == Point xq (xq `addF2m` yq) = PointO
-    | p == q = pointDouble c p
-    | otherwise = fromMaybe PointO $ do
-                     s <- divF2m fx (yp `addF2m` yq) (xp `addF2m` xq)
-                     let xr = mulF2m fx s s `addF2m` s `addF2m` xp `addF2m` xq 
`addF2m` a
-                         yr = mulF2m fx s (xp `addF2m` xr) `addF2m` xr 
`addF2m` yp
-                     return $ Point xr yr
+pointAdd c p q
+  | p == q = pointDouble c p
+  | p == pointNegate c q = PointO
+pointAdd (CurveFP (CurvePrime pr _)) (Point xp yp) (Point xq yq)
+    = fromMaybe PointO $ do
+        s <- divmod (yp - yq) (xp - xq) pr
+        let xr = (s ^ (2::Int) - xp - xq) `mod` pr
+            yr = (s * (xp - xr) - yp) `mod` pr
+        return $ Point xr yr
+pointAdd (CurveF2m (CurveBinary fx cc)) (Point xp yp) (Point xq yq)
+    = fromMaybe PointO $ do
+        s <- divF2m fx (yp `addF2m` yq) (xp `addF2m` xq)
+        let xr = mulF2m fx s s `addF2m` s `addF2m` xp `addF2m` xq `addF2m` a
+            yr = mulF2m fx s (xp `addF2m` xr) `addF2m` xr `addF2m` yp
+        return $ Point xr yr
   where a = ecc_a cc
 
 -- | Elliptic Curve point doubling.
@@ -95,8 +101,8 @@
 -- /WARNING:/ Vulnerable to timing attacks.
 pointMul :: Curve -> Integer -> Point -> Point
 pointMul _ _ PointO = PointO
-pointMul c n p@(Point xp yp)
-    | n <  0 = pointMul c (-n) (Point xp (-yp))
+pointMul c n p
+    | n <  0 = pointMul c (-n) (pointNegate c p)
     | n == 0 = PointO
     | n == 1 = p
     | odd n = pointAdd c p (pointMul c (n - 1) p)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cryptonite-0.15/Crypto/PubKey/Ed448.hs 
new/cryptonite-0.19/Crypto/PubKey/Ed448.hs
--- old/cryptonite-0.15/Crypto/PubKey/Ed448.hs  2016-04-09 18:16:13.000000000 
+0200
+++ new/cryptonite-0.19/Crypto/PubKey/Ed448.hs  2016-08-12 08:14:25.000000000 
+0200
@@ -89,7 +89,7 @@
     withByteArray sec               $ \psec   ->
         ccryptonite_ed448 result psec basePoint
   where
-        basePoint = Ptr 
"\x05\x00\x00\x00\x00\x00\x00\x00\x00x00\x00\x00\x00\x00\x00\x00\x00x00\x00\x00\x00\x00\x00\x00\x00x00\x00\x00\x00\x00\x00\x00\x00x00\x00\x00\x00\x00\x00\x00\x00x00\x00\x00\x00\x00\x00\x00\x00x00\x00\x00\x00\x00\x00\x00"#
+        basePoint = Ptr 
"\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
 {-# NOINLINE toPublic #-}
 
 x448_bytes :: Int
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cryptonite-0.15/Crypto/Random/EntropyPool.hs 
new/cryptonite-0.19/Crypto/Random/EntropyPool.hs
--- old/cryptonite-0.15/Crypto/Random/EntropyPool.hs    2016-04-09 
18:16:13.000000000 +0200
+++ new/cryptonite-0.19/Crypto/Random/EntropyPool.hs    2016-08-12 
08:14:25.000000000 +0200
@@ -21,8 +21,8 @@
 import           Foreign.Marshal.Utils (copyBytes)
 import           Foreign.Ptr (plusPtr, Ptr)
 
--- | Pool of Entropy. contains a self mutating pool of entropy,
--- that is always guarantee to contains data.
+-- | Pool of Entropy. Contains a self-mutating pool of entropy,
+-- that is always guaranteed to contain data.
 data EntropyPool = EntropyPool [EntropyBackend] (MVar Int) ScrubbedBytes
 
 -- size of entropy pool by default
@@ -31,7 +31,8 @@
 
 -- | Create a new entropy pool of a specific size
 --
--- While you can create as many entropy pool as you want, the pool can be 
shared between multiples RNGs.
+-- While you can create as many entropy pools as you want,
+-- the pool can be shared between multiples RNGs.
 createEntropyPoolWith :: Int -> [EntropyBackend] -> IO EntropyPool
 createEntropyPoolWith poolSize backends = do
     m  <- newMVar 0
@@ -40,7 +41,8 @@
 
 -- | Create a new entropy pool with a default size.
 --
--- While you can create as many entropy pool as you want, the pool can be 
shared between multiples RNGs.
+-- While you can create as many entropy pools as you want,
+-- the pool can be shared between multiples RNGs.
 createEntropyPool :: IO EntropyPool
 createEntropyPool = do
     backends <- catMaybes `fmap` sequence supportedBackends
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cryptonite-0.15/Crypto/Tutorial.hs 
new/cryptonite-0.19/Crypto/Tutorial.hs
--- old/cryptonite-0.15/Crypto/Tutorial.hs      1970-01-01 01:00:00.000000000 
+0100
+++ new/cryptonite-0.19/Crypto/Tutorial.hs      2016-08-12 08:14:25.000000000 
+0200
@@ -0,0 +1,34 @@
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+{-| How to use @cryptonite@
+
+> -- | Beware MUST BE 256bits as we use AES256
+> import Data.ByteString (ByteString)
+> import Crypto.Cipher.AES (AES256)
+> import Crypto.Cipher.Types (BlockCipher(..), Cipher(..),nullIV)
+> import Crypto.Error (CryptoFailable(..))
+>
+> secretKey :: ByteString
+> secretKey = "012-456-89A-CDE-012-456-89A-CDE-"
+>
+> encrypt :: ByteString -> ByteString -> ByteString
+> encrypt secret = ctrCombine ctx nullIV
+>   where
+>     ctx = cipherInitNoErr (cipherMakeKey (undefined :: AES256) secret)
+>     cipherInitNoErr :: BlockCipher c => Key c -> c
+>     cipherInitNoErr (Key k) = case cipherInit k of
+>       CryptoPassed a -> a
+>       CryptoFailed e -> error (show e)
+>     cipherMakeKey :: Cipher cipher => cipher -> ByteString -> Key cipher
+>     cipherMakeKey _ = Key -- Yeah Lazyness!!!!!!
+>
+>
+> decrypt :: ByteString -> ByteString -> ByteString
+> decrypt = encrypt
+
+|-}
+
+module Crypto.Tutorial () where
+
+import Crypto.Cipher.Types
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cryptonite-0.15/README.md 
new/cryptonite-0.19/README.md
--- old/cryptonite-0.15/README.md       2016-04-09 18:16:13.000000000 +0200
+++ new/cryptonite-0.19/README.md       2016-08-12 08:14:25.000000000 +0200
@@ -2,27 +2,25 @@
 ==========
 
 [![Join the chat at 
https://gitter.im/vincenthz/cryptonite](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/vincenthz/cryptonite?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-[![Build 
Status](https://travis-ci.org/vincenthz/cryptonite.png?branch=master)](https://travis-ci.org/vincenthz/cryptonite)
+[![Build 
Status](https://travis-ci.org/haskell-crypto/cryptonite.png?branch=master)](https://travis-ci.org/haskell-crypto/cryptonite)
 
[![BSD](http://b.repl.ca/v1/license-BSD-blue.png)](http://en.wikipedia.org/wiki/BSD_licenses)
 
[![Haskell](http://b.repl.ca/v1/language-haskell-lightgrey.png)](http://haskell.org)
 
 Cryptonite is a haskell repository of cryptographic primitives. Each crypto
-algorithm have specificities, that are hard to wrap in common APIs and types,
-so instead of trying to provide a common ground for algorithms that wouldn't
-allow to provide all different usage or a really complicated system, this just
-provide a non-consistant low-level API.
+algorithm has specificities that are hard to wrap in common APIs and types,
+so instead of trying to provide a common ground for algorithms, this package
+provides a non-consistent low-level API.
 
-If you have no idea what're you doing, please do not use this directly, rely on
-higher level protocols or higher level implementation.
+If you have no idea what you're doing, please do not use this directly.
+Instead, rely on higher level protocols or implementations.
 
 Documentation: [cryptonite on 
hackage](http://hackage.haskell.org/package/cryptonite)
 
 Versioning
 ----------
 
-Development versions are an incremental number prefixed by 0.
-No specific meaning is associated with the versions, specially
-no API stability.
+Development versions are an incremental number prefixed by 0. There is no
+API stability between development versions.
 
 Production versions : TBD
 
@@ -35,7 +33,7 @@
 Support
 -------
 
-cryptonite supports the following platform:
+cryptonite supports the following platforms:
 
 * Windows >= 8
 * OSX >= 10.8
@@ -55,21 +53,22 @@
 * GHC 7.8.x
 * GHC 7.10.x
 
-Further platforms and architectures probably works too, but until 
maintainer(s) don't have regular
-access to them, we can't commit for further support
+Further platforms and architectures probably work too, but since the
+maintainer(s) don't have regular access to them, we can't commit to
+further support.
 
 Known Building Issues
 ---------------------
 
-on OSX <= 10.7, the system compiler doesn't understand the '-maes' option, and
+On OSX <= 10.7, the system compiler doesn't understand the '-maes' option, and
 with the lack of autodetection feature builtin in .cabal file, it is left on
 the user to disable the aesni. See the [Disabling AESNI] section
 
 Disabling AESNI
 ---------------
 
-It may be useful to disable AESNI (for building, testing or runtime purpose), 
and one can do that with the
-*support_aesni* flag.
+It may be useful to disable AESNI for building, testing or runtime purposes.
+This is achieved with the *support_aesni* flag.
 
 As part of configure of cryptonite:
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cryptonite-0.15/cbits/cryptonite_rdrand.c 
new/cryptonite-0.19/cbits/cryptonite_rdrand.c
--- old/cryptonite-0.15/cbits/cryptonite_rdrand.c       2016-04-09 
18:16:13.000000000 +0200
+++ new/cryptonite-0.19/cbits/cryptonite_rdrand.c       2016-08-12 
08:14:25.000000000 +0200
@@ -37,23 +37,15 @@
 int cryptonite_cpu_has_rdrand()
 {
        uint32_t ax,bx,cx,dx,func=1;
+#if defined(__PIC__) && defined(__i386__)
+       __asm__ volatile ("mov %%ebx, %%edi;" "cpuid;" "xchgl %%ebx, %%edi;"
+               : "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) : "a" (func));
+#else
        __asm__ volatile ("cpuid": "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) : 
"a" (func));
+#endif
        return (cx & 0x40000000);
 }
 
-/* sadly many people are still using an old binutils,
- * leading to report that instruction is not recognized.
- */
-#if 0
-/* Returns 1 on success */
-static inline int crypto_random_rdrand64_step(uint64_t *buffer)
-{
-       unsigned char err;
-       asm volatile ("rdrand %0; setc %1" : "=r" (*buffer), "=qm" (err));
-       return (int) err;
-}
-#endif
-
 /* inline encoding of 'rdrand %rax' to cover old binutils
  * - no inputs
  * - 'cc' to the clobber list as we modify condition code.
@@ -65,17 +57,51 @@
           : \
           : "cc")
 
+/* inline encoding of 'rdrand %eax' to cover old binutils
+ * - no inputs
+ * - 'cc' to the clobber list as we modify condition code.
+ * - output of rdrand in eax and have a 8 bit error condition
+ */
+#define inline_rdrand_eax(val, err) \
+       asm(".byte 0x0f,0xc7,0xf0; setc %1" \
+          : "=a" (val), "=q" (err) \
+          : \
+          : "cc")
+
+#ifdef __x86_64__
+# define RDRAND_SZ 8
+# define RDRAND_T  uint64_t
+#define inline_rdrand(val, err) err = cryptonite_rdrand_step(&val)
+#else
+# define RDRAND_SZ 4
+# define RDRAND_T  uint32_t
+#define inline_rdrand(val, err) err = cryptonite_rdrand_step(&val)
+#endif
+
+/* sadly many people are still using an old binutils,
+ * leading to report that instruction is not recognized.
+ */
+#if 1
+/* Returns 1 on success */
+static inline int cryptonite_rdrand_step(RDRAND_T *buffer)
+{
+       unsigned char err;
+       asm volatile ("rdrand %0; setc %1" : "=r" (*buffer), "=qm" (err));
+       return (int) err;
+}
+#endif
+
 /* Returns the number of bytes succesfully generated */
 int cryptonite_get_rand_bytes(uint8_t *buffer, size_t len)
 {
-       uint64_t tmp;
-       int aligned = (intptr_t) buffer % 8;
+       RDRAND_T tmp;
+       int aligned = (intptr_t) buffer % RDRAND_SZ;
        int orig_len = len;
-       int to_alignment = 8 - aligned;
+       int to_alignment = RDRAND_SZ - aligned;
        uint8_t ok;
 
        if (aligned != 0) {
-               inline_rdrand_rax(tmp, ok);
+               inline_rdrand(tmp, ok);
                if (!ok)
                        return 0;
                memcpy(buffer, (uint8_t *) &tmp, to_alignment);
@@ -83,15 +109,15 @@
                len -= to_alignment;
        }
 
-       for (; len >= 8; buffer += 8, len -= 8) {
-               inline_rdrand_rax(tmp, ok);
+       for (; len >= RDRAND_SZ; buffer += RDRAND_SZ, len -= RDRAND_SZ) {
+               inline_rdrand(tmp, ok);
                if (!ok)
                        return (orig_len - len);
-               *((uint64_t *) buffer) = tmp;
+               *((RDRAND_T *) buffer) = tmp;
        }
 
        if (len > 0) {
-               inline_rdrand_rax(tmp, ok);
+               inline_rdrand(tmp, ok);
                if (!ok)
                        return (orig_len - len);
                memcpy(buffer, (uint8_t *) &tmp, len);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/cryptonite-0.15/cbits/curve25519/curve25519-donna-c64.c 
new/cryptonite-0.19/cbits/curve25519/curve25519-donna-c64.c
--- old/cryptonite-0.15/cbits/curve25519/curve25519-donna-c64.c 1970-01-01 
01:00:00.000000000 +0100
+++ new/cryptonite-0.19/cbits/curve25519/curve25519-donna-c64.c 2016-08-12 
08:14:25.000000000 +0200
@@ -0,0 +1,447 @@
+/* Copyright 2008, Google Inc.
+ * All rights reserved.
+ *
+ * Code released into the public domain.
+ *
+ * curve25519-donna: Curve25519 elliptic curve, public key function
+ *
+ * http://code.google.com/p/curve25519-donna/
+ *
+ * Adam Langley <a...@imperialviolet.org>
+ *
+ * Derived from public domain C code by Daniel J. Bernstein <d...@cr.yp.to>
+ *
+ * More information about curve25519 can be found here
+ *   http://cr.yp.to/ecdh.html
+ *
+ * djb's sample implementation of curve25519 is written in a special assembly
+ * language called qhasm and uses the floating point registers.
+ *
+ * This is, almost, a clean room reimplementation from the curve25519 paper. It
+ * uses many of the tricks described therein. Only the crecip function is taken
+ * from the sample implementation.
+ */
+
+#include <string.h>
+#include <stdint.h>
+
+typedef uint8_t u8;
+typedef uint64_t limb;
+typedef limb felem[5];
+// This is a special gcc mode for 128-bit integers. It's implemented on 64-bit
+// platforms only as far as I know.
+typedef unsigned uint128_t __attribute__((mode(TI)));
+
+#undef force_inline
+#define force_inline __attribute__((always_inline))
+
+/* Sum two numbers: output += in */
+static inline void force_inline
+fsum(limb *output, const limb *in) {
+  output[0] += in[0];
+  output[1] += in[1];
+  output[2] += in[2];
+  output[3] += in[3];
+  output[4] += in[4];
+}
+
+/* Find the difference of two numbers: output = in - output
+ * (note the order of the arguments!)
+ *
+ * Assumes that out[i] < 2**52
+ * On return, out[i] < 2**55
+ */
+static inline void force_inline
+fdifference_backwards(felem out, const felem in) {
+  /* 152 is 19 << 3 */
+  static const limb two54m152 = (((limb)1) << 54) - 152;
+  static const limb two54m8 = (((limb)1) << 54) - 8;
+
+  out[0] = in[0] + two54m152 - out[0];
+  out[1] = in[1] + two54m8 - out[1];
+  out[2] = in[2] + two54m8 - out[2];
+  out[3] = in[3] + two54m8 - out[3];
+  out[4] = in[4] + two54m8 - out[4];
+}
+
+/* Multiply a number by a scalar: output = in * scalar */
+static inline void force_inline
+fscalar_product(felem output, const felem in, const limb scalar) {
+  uint128_t a;
+
+  a = ((uint128_t) in[0]) * scalar;
+  output[0] = ((limb)a) & 0x7ffffffffffff;
+
+  a = ((uint128_t) in[1]) * scalar + ((limb) (a >> 51));
+  output[1] = ((limb)a) & 0x7ffffffffffff;
+
+  a = ((uint128_t) in[2]) * scalar + ((limb) (a >> 51));
+  output[2] = ((limb)a) & 0x7ffffffffffff;
+
+  a = ((uint128_t) in[3]) * scalar + ((limb) (a >> 51));
+  output[3] = ((limb)a) & 0x7ffffffffffff;
+
+  a = ((uint128_t) in[4]) * scalar + ((limb) (a >> 51));
+  output[4] = ((limb)a) & 0x7ffffffffffff;
+
+  output[0] += (a >> 51) * 19;
+}
+
+/* Multiply two numbers: output = in2 * in
+ *
+ * output must be distinct to both inputs. The inputs are reduced coefficient
+ * form, the output is not.
+ *
+ * Assumes that in[i] < 2**55 and likewise for in2.
+ * On return, output[i] < 2**52
+ */
+static inline void force_inline
+fmul(felem output, const felem in2, const felem in) {
+  uint128_t t[5];
+  limb r0,r1,r2,r3,r4,s0,s1,s2,s3,s4,c;
+
+  r0 = in[0];
+  r1 = in[1];
+  r2 = in[2];
+  r3 = in[3];
+  r4 = in[4];
+
+  s0 = in2[0];
+  s1 = in2[1];
+  s2 = in2[2];
+  s3 = in2[3];
+  s4 = in2[4];
+
+  t[0]  =  ((uint128_t) r0) * s0;
+  t[1]  =  ((uint128_t) r0) * s1 + ((uint128_t) r1) * s0;
+  t[2]  =  ((uint128_t) r0) * s2 + ((uint128_t) r2) * s0 + ((uint128_t) r1) * 
s1;
+  t[3]  =  ((uint128_t) r0) * s3 + ((uint128_t) r3) * s0 + ((uint128_t) r1) * 
s2 + ((uint128_t) r2) * s1;
+  t[4]  =  ((uint128_t) r0) * s4 + ((uint128_t) r4) * s0 + ((uint128_t) r3) * 
s1 + ((uint128_t) r1) * s3 + ((uint128_t) r2) * s2;
+
+  r4 *= 19;
+  r1 *= 19;
+  r2 *= 19;
+  r3 *= 19;
+
+  t[0] += ((uint128_t) r4) * s1 + ((uint128_t) r1) * s4 + ((uint128_t) r2) * 
s3 + ((uint128_t) r3) * s2;
+  t[1] += ((uint128_t) r4) * s2 + ((uint128_t) r2) * s4 + ((uint128_t) r3) * 
s3;
+  t[2] += ((uint128_t) r4) * s3 + ((uint128_t) r3) * s4;
+  t[3] += ((uint128_t) r4) * s4;
+
+                  r0 = (limb)t[0] & 0x7ffffffffffff; c = (limb)(t[0] >> 51);
+  t[1] += c;      r1 = (limb)t[1] & 0x7ffffffffffff; c = (limb)(t[1] >> 51);
+  t[2] += c;      r2 = (limb)t[2] & 0x7ffffffffffff; c = (limb)(t[2] >> 51);
+  t[3] += c;      r3 = (limb)t[3] & 0x7ffffffffffff; c = (limb)(t[3] >> 51);
+  t[4] += c;      r4 = (limb)t[4] & 0x7ffffffffffff; c = (limb)(t[4] >> 51);
+  r0 +=   c * 19; c = r0 >> 51; r0 = r0 & 0x7ffffffffffff;
+  r1 +=   c;      c = r1 >> 51; r1 = r1 & 0x7ffffffffffff;
+  r2 +=   c;
+
+  output[0] = r0;
+  output[1] = r1;
+  output[2] = r2;
+  output[3] = r3;
+  output[4] = r4;
+}
+
+static inline void force_inline
+fsquare_times(felem output, const felem in, limb count) {
+  uint128_t t[5];
+  limb r0,r1,r2,r3,r4,c;
+  limb d0,d1,d2,d4,d419;
+
+  r0 = in[0];
+  r1 = in[1];
+  r2 = in[2];
+  r3 = in[3];
+  r4 = in[4];
+
+  do {
+    d0 = r0 * 2;
+    d1 = r1 * 2;
+    d2 = r2 * 2 * 19;
+    d419 = r4 * 19;
+    d4 = d419 * 2;
+
+    t[0] = ((uint128_t) r0) * r0 + ((uint128_t) d4) * r1 + (((uint128_t) d2) * 
(r3     ));
+    t[1] = ((uint128_t) d0) * r1 + ((uint128_t) d4) * r2 + (((uint128_t) r3) * 
(r3 * 19));
+    t[2] = ((uint128_t) d0) * r2 + ((uint128_t) r1) * r1 + (((uint128_t) d4) * 
(r3     ));
+    t[3] = ((uint128_t) d0) * r3 + ((uint128_t) d1) * r2 + (((uint128_t) r4) * 
(d419   ));
+    t[4] = ((uint128_t) d0) * r4 + ((uint128_t) d1) * r3 + (((uint128_t) r2) * 
(r2     ));
+
+                    r0 = (limb)t[0] & 0x7ffffffffffff; c = (limb)(t[0] >> 51);
+    t[1] += c;      r1 = (limb)t[1] & 0x7ffffffffffff; c = (limb)(t[1] >> 51);
+    t[2] += c;      r2 = (limb)t[2] & 0x7ffffffffffff; c = (limb)(t[2] >> 51);
+    t[3] += c;      r3 = (limb)t[3] & 0x7ffffffffffff; c = (limb)(t[3] >> 51);
+    t[4] += c;      r4 = (limb)t[4] & 0x7ffffffffffff; c = (limb)(t[4] >> 51);
+    r0 +=   c * 19; c = r0 >> 51; r0 = r0 & 0x7ffffffffffff;
+    r1 +=   c;      c = r1 >> 51; r1 = r1 & 0x7ffffffffffff;
+    r2 +=   c;
+  } while(--count);
+
+  output[0] = r0;
+  output[1] = r1;
+  output[2] = r2;
+  output[3] = r3;
+  output[4] = r4;
+}
+
+/* Load a little-endian 64-bit number  */
+static limb
+load_limb(const u8 *in) {
+  return
+    ((limb)in[0]) |
+    (((limb)in[1]) << 8) |
+    (((limb)in[2]) << 16) |
+    (((limb)in[3]) << 24) |
+    (((limb)in[4]) << 32) |
+    (((limb)in[5]) << 40) |
+    (((limb)in[6]) << 48) |
+    (((limb)in[7]) << 56);
+}
+
+static void
+store_limb(u8 *out, limb in) {
+  out[0] = in & 0xff;
+  out[1] = (in >> 8) & 0xff;
+  out[2] = (in >> 16) & 0xff;
+  out[3] = (in >> 24) & 0xff;
+  out[4] = (in >> 32) & 0xff;
+  out[5] = (in >> 40) & 0xff;
+  out[6] = (in >> 48) & 0xff;
+  out[7] = (in >> 56) & 0xff;
+}
+
+/* Take a little-endian, 32-byte number and expand it into polynomial form */
+static void
+fexpand(limb *output, const u8 *in) {
+  output[0] = load_limb(in) & 0x7ffffffffffff;
+  output[1] = (load_limb(in+6) >> 3) & 0x7ffffffffffff;
+  output[2] = (load_limb(in+12) >> 6) & 0x7ffffffffffff;
+  output[3] = (load_limb(in+19) >> 1) & 0x7ffffffffffff;
+  output[4] = (load_limb(in+24) >> 12) & 0x7ffffffffffff;
+}
+
+/* Take a fully reduced polynomial form number and contract it into a
+ * little-endian, 32-byte array
+ */
+static void
+fcontract(u8 *output, const felem input) {
+  uint128_t t[5];
+
+  t[0] = input[0];
+  t[1] = input[1];
+  t[2] = input[2];
+  t[3] = input[3];
+  t[4] = input[4];
+
+  t[1] += t[0] >> 51; t[0] &= 0x7ffffffffffff;
+  t[2] += t[1] >> 51; t[1] &= 0x7ffffffffffff;
+  t[3] += t[2] >> 51; t[2] &= 0x7ffffffffffff;
+  t[4] += t[3] >> 51; t[3] &= 0x7ffffffffffff;
+  t[0] += 19 * (t[4] >> 51); t[4] &= 0x7ffffffffffff;
+
+  t[1] += t[0] >> 51; t[0] &= 0x7ffffffffffff;
+  t[2] += t[1] >> 51; t[1] &= 0x7ffffffffffff;
+  t[3] += t[2] >> 51; t[2] &= 0x7ffffffffffff;
+  t[4] += t[3] >> 51; t[3] &= 0x7ffffffffffff;
+  t[0] += 19 * (t[4] >> 51); t[4] &= 0x7ffffffffffff;
+
+  /* now t is between 0 and 2^255-1, properly carried. */
+  /* case 1: between 0 and 2^255-20. case 2: between 2^255-19 and 2^255-1. */
+
+  t[0] += 19;
+
+  t[1] += t[0] >> 51; t[0] &= 0x7ffffffffffff;
+  t[2] += t[1] >> 51; t[1] &= 0x7ffffffffffff;
+  t[3] += t[2] >> 51; t[2] &= 0x7ffffffffffff;
+  t[4] += t[3] >> 51; t[3] &= 0x7ffffffffffff;
+  t[0] += 19 * (t[4] >> 51); t[4] &= 0x7ffffffffffff;
+
+  /* now between 19 and 2^255-1 in both cases, and offset by 19. */
+
+  t[0] += 0x8000000000000 - 19;
+  t[1] += 0x8000000000000 - 1;
+  t[2] += 0x8000000000000 - 1;
+  t[3] += 0x8000000000000 - 1;
+  t[4] += 0x8000000000000 - 1;
+
+  /* now between 2^255 and 2^256-20, and offset by 2^255. */
+
+  t[1] += t[0] >> 51; t[0] &= 0x7ffffffffffff;
+  t[2] += t[1] >> 51; t[1] &= 0x7ffffffffffff;
+  t[3] += t[2] >> 51; t[2] &= 0x7ffffffffffff;
+  t[4] += t[3] >> 51; t[3] &= 0x7ffffffffffff;
+  t[4] &= 0x7ffffffffffff;
+
+  store_limb(output,    t[0] | (t[1] << 51));
+  store_limb(output+8,  (t[1] >> 13) | (t[2] << 38));
+  store_limb(output+16, (t[2] >> 26) | (t[3] << 25));
+  store_limb(output+24, (t[3] >> 39) | (t[4] << 12));
+}
+
+/* Input: Q, Q', Q-Q'
+ * Output: 2Q, Q+Q'
+ *
+ *   x2 z3: long form
+ *   x3 z3: long form
+ *   x z: short form, destroyed
+ *   xprime zprime: short form, destroyed
+ *   qmqp: short form, preserved
+ */
+static void
+fmonty(limb *x2, limb *z2, /* output 2Q */
+       limb *x3, limb *z3, /* output Q + Q' */
+       limb *x, limb *z,   /* input Q */
+       limb *xprime, limb *zprime, /* input Q' */
+       const limb *qmqp /* input Q - Q' */) {
+  limb origx[5], origxprime[5], zzz[5], xx[5], zz[5], xxprime[5],
+        zzprime[5], zzzprime[5];
+
+  memcpy(origx, x, 5 * sizeof(limb));
+  fsum(x, z);
+  fdifference_backwards(z, origx);  // does x - z
+
+  memcpy(origxprime, xprime, sizeof(limb) * 5);
+  fsum(xprime, zprime);
+  fdifference_backwards(zprime, origxprime);
+  fmul(xxprime, xprime, z);
+  fmul(zzprime, x, zprime);
+  memcpy(origxprime, xxprime, sizeof(limb) * 5);
+  fsum(xxprime, zzprime);
+  fdifference_backwards(zzprime, origxprime);
+  fsquare_times(x3, xxprime, 1);
+  fsquare_times(zzzprime, zzprime, 1);
+  fmul(z3, zzzprime, qmqp);
+
+  fsquare_times(xx, x, 1);
+  fsquare_times(zz, z, 1);
+  fmul(x2, xx, zz);
+  fdifference_backwards(zz, xx);  // does zz = xx - zz
+  fscalar_product(zzz, zz, 121665);
+  fsum(zzz, xx);
+  fmul(z2, zz, zzz);
+}
+
+// 
-----------------------------------------------------------------------------
+// Maybe swap the contents of two limb arrays (@a and @b), each @len elements
+// long. Perform the swap iff @swap is non-zero.
+//
+// This function performs the swap without leaking any side-channel
+// information.
+// 
-----------------------------------------------------------------------------
+static void
+swap_conditional(limb a[5], limb b[5], limb iswap) {
+  unsigned i;
+  const limb swap = -iswap;
+
+  for (i = 0; i < 5; ++i) {
+    const limb x = swap & (a[i] ^ b[i]);
+    a[i] ^= x;
+    b[i] ^= x;
+  }
+}
+
+/* Calculates nQ where Q is the x-coordinate of a point on the curve
+ *
+ *   resultx/resultz: the x coordinate of the resulting curve point (short 
form)
+ *   n: a little endian, 32-byte number
+ *   q: a point of the curve (short form)
+ */
+static void
+cmult(limb *resultx, limb *resultz, const u8 *n, const limb *q) {
+  limb a[5] = {0}, b[5] = {1}, c[5] = {1}, d[5] = {0};
+  limb *nqpqx = a, *nqpqz = b, *nqx = c, *nqz = d, *t;
+  limb e[5] = {0}, f[5] = {1}, g[5] = {0}, h[5] = {1};
+  limb *nqpqx2 = e, *nqpqz2 = f, *nqx2 = g, *nqz2 = h;
+
+  unsigned i, j;
+
+  memcpy(nqpqx, q, sizeof(limb) * 5);
+
+  for (i = 0; i < 32; ++i) {
+    u8 byte = n[31 - i];
+    for (j = 0; j < 8; ++j) {
+      const limb bit = byte >> 7;
+
+      swap_conditional(nqx, nqpqx, bit);
+      swap_conditional(nqz, nqpqz, bit);
+      fmonty(nqx2, nqz2,
+             nqpqx2, nqpqz2,
+             nqx, nqz,
+             nqpqx, nqpqz,
+             q);
+      swap_conditional(nqx2, nqpqx2, bit);
+      swap_conditional(nqz2, nqpqz2, bit);
+
+      t = nqx;
+      nqx = nqx2;
+      nqx2 = t;
+      t = nqz;
+      nqz = nqz2;
+      nqz2 = t;
+      t = nqpqx;
+      nqpqx = nqpqx2;
+      nqpqx2 = t;
+      t = nqpqz;
+      nqpqz = nqpqz2;
+      nqpqz2 = t;
+
+      byte <<= 1;
+    }
+  }
+
+  memcpy(resultx, nqx, sizeof(limb) * 5);
+  memcpy(resultz, nqz, sizeof(limb) * 5);
+}
+
+
+// 
-----------------------------------------------------------------------------
+// Shamelessly copied from djb's code, tightened a little
+// 
-----------------------------------------------------------------------------
+static void
+crecip(felem out, const felem z) {
+  felem a,t0,b,c;
+
+  /* 2 */ fsquare_times(a, z, 1); // a = 2
+  /* 8 */ fsquare_times(t0, a, 2);
+  /* 9 */ fmul(b, t0, z); // b = 9
+  /* 11 */ fmul(a, b, a); // a = 11
+  /* 22 */ fsquare_times(t0, a, 1);
+  /* 2^5 - 2^0 = 31 */ fmul(b, t0, b);
+  /* 2^10 - 2^5 */ fsquare_times(t0, b, 5);
+  /* 2^10 - 2^0 */ fmul(b, t0, b);
+  /* 2^20 - 2^10 */ fsquare_times(t0, b, 10);
+  /* 2^20 - 2^0 */ fmul(c, t0, b);
+  /* 2^40 - 2^20 */ fsquare_times(t0, c, 20);
+  /* 2^40 - 2^0 */ fmul(t0, t0, c);
+  /* 2^50 - 2^10 */ fsquare_times(t0, t0, 10);
+  /* 2^50 - 2^0 */ fmul(b, t0, b);
+  /* 2^100 - 2^50 */ fsquare_times(t0, b, 50);
+  /* 2^100 - 2^0 */ fmul(c, t0, b);
+  /* 2^200 - 2^100 */ fsquare_times(t0, c, 100);
+  /* 2^200 - 2^0 */ fmul(t0, t0, c);
+  /* 2^250 - 2^50 */ fsquare_times(t0, t0, 50);
+  /* 2^250 - 2^0 */ fmul(t0, t0, b);
+  /* 2^255 - 2^5 */ fsquare_times(t0, t0, 5);
+  /* 2^255 - 21 */ fmul(out, t0, a);
+}
+
+int
+cryptonite_curve25519_donna(u8 *mypublic, const u8 *secret, const u8 
*basepoint) {
+  limb bp[5], x[5], z[5], zmone[5];
+  uint8_t e[32];
+  int i;
+
+  for (i = 0;i < 32;++i) e[i] = secret[i];
+  e[0] &= 248;
+  e[31] &= 127;
+  e[31] |= 64;
+
+  fexpand(bp, basepoint);
+  cmult(x, z, e, bp);
+  crecip(zmone, z);
+  fmul(z, x, zmone);
+  fcontract(mypublic, z);
+  return 0;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cryptonite-0.15/cryptonite.cabal 
new/cryptonite-0.19/cryptonite.cabal
--- old/cryptonite-0.15/cryptonite.cabal        2016-04-09 18:16:13.000000000 
+0200
+++ new/cryptonite-0.19/cryptonite.cabal        2016-08-12 08:14:25.000000000 
+0200
@@ -1,5 +1,5 @@
 Name:                cryptonite
-Version:             0.15
+Version:             0.19
 Synopsis:            Cryptography Primitives sink
 Description:
     A repository of cryptographic primitives.
@@ -10,7 +10,7 @@
     .
     * MAC: HMAC, Poly1305
     .
-    * Assymmetric crypto: DSA, RSA, DH, ECDH, ECDSA, ECC, Curve25519, Ed25519
+    * Asymmetric crypto: DSA, RSA, DH, ECDH, ECDSA, ECC, Curve25519, Ed25519, 
Ed448
     .
     * Key Derivation Function: PBKDF2, Scrypt, HKDF
     .
@@ -23,6 +23,8 @@
     cryptographic kitchen sink that provides cryptography for everyone.
     .
     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 <vinc...@snarc.org>
@@ -41,9 +43,7 @@
                      cbits/ed448/*.h
                      cbits/p256/*.h
                      cbits/blake2/ref/*.h
-                     cbits/blake2/ref/*.c
                      cbits/blake2/sse/*.h
-                     cbits/blake2/sse/*.c
                      cbits/aes/x86ni_impl.c
                      tests/*.hs
 
@@ -97,6 +97,7 @@
                      Crypto.Cipher.Salsa
                      Crypto.Cipher.TripleDES
                      Crypto.Cipher.Types
+                     Crypto.ConstructHash.MiyaguchiPreneel
                      Crypto.Data.AFIS
                      Crypto.Data.Padding
                      Crypto.Error
@@ -140,6 +141,7 @@
                      Crypto.Random.Entropy
                      Crypto.Random.EntropyPool
                      Crypto.Random.Entropy.Unsafe
+                     Crypto.Tutorial
   Other-modules:     Crypto.Cipher.AES.Primitive
                      Crypto.Cipher.Blowfish.Box
                      Crypto.Cipher.Blowfish.Primitive
@@ -201,7 +203,6 @@
                    , cbits/cryptonite_salsa.c
                    , cbits/cryptonite_rc4.c
                    , cbits/cryptonite_cpu.c
-                   , cbits/curve25519/curve25519-donna.c
                    , cbits/ed25519/ed25519.c
                    , cbits/ed448/x448.c
                    , cbits/p256/p256.c
@@ -227,6 +228,11 @@
                    , cbits/cryptonite_scrypt.c
   include-dirs:  cbits cbits/ed25519
 
+  if arch(x86_64)
+    C-sources: cbits/curve25519/curve25519-donna-c64.c
+  else
+    C-sources: cbits/curve25519/curve25519-donna.c
+
   -- FIXME armel or mispel is also little endian.
   -- might be a good idea to also add a runtime autodetect mode.
   -- ARCH_ENDIAN_UNKNOWN
@@ -236,8 +242,10 @@
   if arch(i386)
     CPP-options: -DARCH_X86
 
-  if flag(support_rdrand) && arch(x86_64)
-    CPP-options:    -DARCH_X86_64
+  if arch(x86_64)
+    CPP-options: -DARCH_X86_64
+
+  if flag(support_rdrand) && (arch(i386) || arch(x86_64))
     CPP-options:    -DSUPPORT_RDRAND
     Other-modules:  Crypto.Random.Entropy.RDRand
     c-sources:      cbits/cryptonite_rdrand.c
@@ -303,9 +311,12 @@
                      KAT_Camellia
                      KAT_Curve25519
                      KAT_DES
+                     KAT_Ed448
                      KAT_Ed25519
                      KAT_CMAC
+                     KAT_HKDF
                      KAT_HMAC
+                     KAT_MiyaguchiPreneel
                      KAT_PBKDF2
                      KAT_PubKey.DSA
                      KAT_PubKey.ECC
@@ -317,6 +328,10 @@
                      KAT_RC4
                      KAT_Scrypt
                      KAT_TripleDES
+                     ChaChaPoly1305
+                     Number
+                     Number.F2m
+                     Padding
                      Poly1305
                      Salsa
                      Utils
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cryptonite-0.15/tests/BCrypt.hs 
new/cryptonite-0.19/tests/BCrypt.hs
--- old/cryptonite-0.15/tests/BCrypt.hs 2016-04-09 18:16:13.000000000 +0200
+++ new/cryptonite-0.19/tests/BCrypt.hs 2016-08-12 08:14:25.000000000 +0200
@@ -74,4 +74,5 @@
 
 tests = testGroup "bcrypt"
     [ testGroup "KATs" makeKATs
+    , testCase "Invalid hash length" (assertEqual "" (Left "Invalid hash 
format") (validatePasswordEither B.empty 
("$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s" :: 
B.ByteString)))
     ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cryptonite-0.15/tests/KAT_Ed448.hs 
new/cryptonite-0.19/tests/KAT_Ed448.hs
--- old/cryptonite-0.15/tests/KAT_Ed448.hs      2016-04-09 18:16:13.000000000 
+0200
+++ new/cryptonite-0.19/tests/KAT_Ed448.hs      2016-08-12 08:14:25.000000000 
+0200
@@ -16,6 +16,8 @@
 katTests =
     [ testCase "0" (aliceMultBob @=? B.convert (Ed448.dh alicePublic 
bobPrivate))
     , testCase "1" (aliceMultBob @=? B.convert (Ed448.dh bobPublic 
alicePrivate))
+    , testCase "2" (alicePublic  @=? Ed448.toPublic alicePrivate)
+    , testCase "3" (bobPublic    @=? Ed448.toPublic bobPrivate)
     ]
 
 tests = testGroup "Ed448"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cryptonite-0.15/tests/KAT_MiyaguchiPreneel.hs 
new/cryptonite-0.19/tests/KAT_MiyaguchiPreneel.hs
--- old/cryptonite-0.15/tests/KAT_MiyaguchiPreneel.hs   1970-01-01 
01:00:00.000000000 +0100
+++ new/cryptonite-0.19/tests/KAT_MiyaguchiPreneel.hs   2016-08-12 
08:14:25.000000000 +0200
@@ -0,0 +1,50 @@
+
+module KAT_MiyaguchiPreneel (tests) where
+
+import           Crypto.Cipher.AES (AES128)
+import           Crypto.ConstructHash.MiyaguchiPreneel as MiyaguchiPreneel
+
+import           Imports
+
+import           Data.Char (digitToInt)
+import qualified Data.ByteString.Char8 as B8
+import qualified Data.ByteArray as B
+import Data.ByteArray.Encoding (Base (Base16), convertFromBase)
+
+
+runMP128 :: ByteString -> ByteString
+runMP128 s = B.convert (MiyaguchiPreneel.compute s :: MiyaguchiPreneel AES128)
+
+hxs :: String -> ByteString
+hxs = either (error . ("hxs:" ++)) id . convertFromBase Base16
+      . B8.pack . filter (/= ' ')
+
+gAES128 :: TestTree
+gAES128 =
+  igroup "aes128"
+  [ runMP128  B8.empty
+    @?=       hxs "66e94bd4 ef8a2c3b 884cfa59 ca342b2e"
+  , runMP128 (hxs "01000000 00000000 00000000 00000000")
+    @?=       hxs "46711816 e91d6ff0 59bbbf2b f58e0fd3"
+  , runMP128 (hxs "00000000 00000000 00000000 00000001")
+    @?=       hxs "58e2fcce fa7e3061 367f1d57 a4e7455b"
+  , runMP128     (hxs $
+                  "00000000 00000000 00000000 00000000" ++
+                  "01")
+    @?=       hxs "a5ff35ae 097adf5d 646abf5e bf4c16f4"
+  ]
+
+igroup :: TestName -> [Assertion] -> TestTree
+igroup nm = testGroup nm . zipWith (flip ($)) [1..] . map icase
+  where
+    icase c i = testCase (show (i :: Int)) c
+
+vectors :: TestTree
+vectors =
+  testGroup "KATs"
+  [ gAES128 ]
+
+tests :: TestTree
+tests =
+    testGroup "MiyaguchiPreneel"
+    [ vectors ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cryptonite-0.15/tests/Number/F2m.hs 
new/cryptonite-0.19/tests/Number/F2m.hs
--- old/cryptonite-0.15/tests/Number/F2m.hs     1970-01-01 01:00:00.000000000 
+0100
+++ new/cryptonite-0.19/tests/Number/F2m.hs     2016-08-12 08:14:25.000000000 
+0200
@@ -0,0 +1,83 @@
+module Number.F2m (tests) where
+
+import Imports hiding ((.&.))
+import Data.Bits
+import Crypto.Number.Basic (log2)
+import Crypto.Number.F2m
+
+addTests = testGroup "addF2m"
+    [ testProperty "commutative"
+        $ \a b -> a `addF2m` b == b `addF2m` a
+    , testProperty "associative"
+        $ \a b c -> (a `addF2m` b) `addF2m` c == a `addF2m` (b `addF2m` c)
+    , testProperty "0 is neutral"
+        $ \a -> a `addF2m` 0 == a
+    , testProperty "nullable"
+        $ \a -> a `addF2m` a == 0
+    , testProperty "works per bit"
+        $ \a b -> (a `addF2m` b) .&. b == (a .&. b) `addF2m` b
+    ]
+
+modTests = testGroup "modF2m"
+    [ testProperty "idempotent"
+        $ \(Positive m) (NonNegative a) -> modF2m m a == modF2m m (modF2m m a)
+    , testProperty "upper bound"
+        $ \(Positive m) (NonNegative a) -> modF2m m a < 2 ^ log2 m
+    , testProperty "reach upper"
+        $ \(Positive m) -> let a = 2 ^ log2 m - 1 in modF2m m (m `addF2m` a) 
== a
+    , testProperty "lower bound"
+        $ \(Positive m) (NonNegative a) -> modF2m m a >= 0
+    , testProperty "reach lower"
+        $ \(Positive m) -> modF2m m m == 0
+    , testProperty "additive"
+        $ \(Positive m) (NonNegative a) (NonNegative b)
+            -> modF2m m a `addF2m` modF2m m b == modF2m m (a `addF2m` b)
+    ]
+
+mulTests = testGroup "mulF2m"
+    [ testProperty "commutative"
+        $ \(Positive m) (NonNegative a) (NonNegative b) -> mulF2m m a b == 
mulF2m m b a
+    , testProperty "associative"
+        $ \(Positive m) (NonNegative a) (NonNegative b) (NonNegative c)
+            -> mulF2m m (mulF2m m a b) c == mulF2m m a (mulF2m m b c)
+    , testProperty "1 is neutral"
+        $ \(Positive m) (NonNegative a) -> mulF2m m a 1 == modF2m m a
+    , testProperty "0 is annihilator"
+        $ \(Positive m) (NonNegative a) -> mulF2m m a 0 == 0
+    , testProperty "distributive"
+        $ \(Positive m) (NonNegative a) (NonNegative b) (NonNegative c)
+            -> mulF2m m a (b `addF2m` c) == mulF2m m a b `addF2m` mulF2m m a c
+    ]
+
+squareTests = testGroup "squareF2m"
+    [ testProperty "sqr(a) == a * a"
+        $ \(Positive m) (NonNegative a) -> mulF2m m a a == squareF2m m a
+    ]
+
+invTests = testGroup "invF2m"
+    [ testProperty "1 / a * a == 1"
+        $ \(Positive m) (NonNegative a)
+            -> maybe True (\c -> mulF2m m c a == modF2m m 1) (invF2m m a)
+    , testProperty "1 / a == a (mod a^2-1)"
+        $ \(NonNegative a) -> a < 2 || invF2m (squareF2m' a `addF2m` 1) a == 
Just a
+    ]
+
+divTests = testGroup "divF2m"
+    [ testProperty "1 / a == inv a"
+        $ \(Positive m) (NonNegative a) -> divF2m m 1 a == invF2m m a
+    , testProperty "a / b == a * inv b"
+        $ \(Positive m) (NonNegative a) (NonNegative b)
+            -> divF2m m a b == (mulF2m m a <$> invF2m m b)
+    , testProperty "a * b / b == a"
+        $ \(Positive m) (NonNegative a) (NonNegative b)
+            -> invF2m m b == Nothing || divF2m m (mulF2m m a b) b == Just 
(modF2m m a)
+    ]
+
+tests = testGroup "number.F2m"
+    [ addTests
+    , modTests
+    , mulTests
+    , squareTests
+    , invTests
+    , divTests
+    ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cryptonite-0.15/tests/Padding.hs 
new/cryptonite-0.19/tests/Padding.hs
--- old/cryptonite-0.15/tests/Padding.hs        2016-04-09 18:16:13.000000000 
+0200
+++ new/cryptonite-0.19/tests/Padding.hs        2016-08-12 08:14:25.000000000 
+0200
@@ -13,6 +13,12 @@
     , ("xyze", 5, "xyze\x01")
     ]
 
+zeroCases =
+    [ ("", 4, "\NUL\NUL\NUL\NUL", Nothing)
+    , ("abcdef", 8, "abcdef\NUL\NUL", Nothing)
+    , ("0123456789abcdef", 16, "0123456789abcdef", Just "0123456789abcdef")
+    ]
+
 --instance Arbitrary where
 
 testPad :: Int -> (B.ByteString, Int, B.ByteString) -> TestTree
@@ -21,6 +27,13 @@
                                          , eqTest "unpadded" (Just inp) (unpad 
(PKCS7 sz) padded)
                                          ]
 
+testZeroPad :: Int -> (B.ByteString, Int, B.ByteString, Maybe B.ByteString) -> 
TestTree
+testZeroPad n (inp, sz, padded, unpadded) =
+    testCase (show n) $ propertyHoldCase [ eqTest "padded" padded (pad (ZERO 
sz) inp)
+                                         , eqTest "unpadded" unpadded (unpad 
(ZERO sz) padded)
+                                         ]
+
 tests = testGroup "Padding"
     [ testGroup "Cases" $ map (uncurry testPad) (zip [1..] cases)
+    , testGroup "ZeroCases" $ map (uncurry testZeroPad) (zip [1..] zeroCases)
     ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cryptonite-0.15/tests/Tests.hs 
new/cryptonite-0.19/tests/Tests.hs
--- old/cryptonite-0.15/tests/Tests.hs  2016-04-09 18:16:13.000000000 +0200
+++ new/cryptonite-0.19/tests/Tests.hs  2016-08-12 08:14:25.000000000 +0200
@@ -4,12 +4,14 @@
 import Imports
 
 import qualified Number
+import qualified Number.F2m
 import qualified BCrypt
 import qualified Hash
 import qualified Poly1305
 import qualified Salsa
 import qualified ChaCha
 import qualified ChaChaPoly1305
+import qualified KAT_MiyaguchiPreneel
 import qualified KAT_CMAC
 import qualified KAT_HMAC
 import qualified KAT_HKDF
@@ -32,8 +34,12 @@
 
 tests = testGroup "cryptonite"
     [ Number.tests
+    , Number.F2m.tests
     , Hash.tests
     , Padding.tests
+    , testGroup "ConstructHash"
+        [ KAT_MiyaguchiPreneel.tests
+        ]
     , testGroup "MAC"
         [ Poly1305.tests
         , KAT_CMAC.tests


Reply via email to