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 - psimons@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/fu...
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
+-- 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...
+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
+ *
+ * Derived from public domain C code by Daniel J. Bernstein
+ *
+ * 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
+#include
+
+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
@@ -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