From e10ef06885df90754e24c06bbb312e851d60587e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Ch=C3=A9ron?= Date: Sun, 14 Oct 2018 16:58:29 +0200 Subject: [PATCH 1/7] Remove unnecessary language extension --- Crypto/Hash/SHAKE.hs | 1 - tests/Hash.hs | 1 - 2 files changed, 2 deletions(-) diff --git a/Crypto/Hash/SHAKE.hs b/Crypto/Hash/SHAKE.hs index aa9d692..5d36228 100644 --- a/Crypto/Hash/SHAKE.hs +++ b/Crypto/Hash/SHAKE.hs @@ -12,7 +12,6 @@ {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE DataKinds #-} -{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE TypeFamilies #-} diff --git a/tests/Hash.hs b/tests/Hash.hs index f139bc1..5c699ef 100644 --- a/tests/Hash.hs +++ b/tests/Hash.hs @@ -1,5 +1,4 @@ {-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE ViewPatterns #-} {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE DataKinds #-} module Hash From 0ab1c41ac87b3a64d2270748d395706e6c5549e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Ch=C3=A9ron?= Date: Sun, 14 Oct 2018 16:58:29 +0200 Subject: [PATCH 2/7] Add missing Data instances --- Crypto/Hash/SHAKE.hs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Crypto/Hash/SHAKE.hs b/Crypto/Hash/SHAKE.hs index 5d36228..4eed297 100644 --- a/Crypto/Hash/SHAKE.hs +++ b/Crypto/Hash/SHAKE.hs @@ -22,6 +22,7 @@ module Crypto.Hash.SHAKE import Crypto.Hash.Types import Foreign.Ptr (Ptr) +import Data.Data import Data.Typeable import Data.Word (Word8, Word32) @@ -37,7 +38,7 @@ import Crypto.Internal.Nat -- correlated (one being a prefix of the other). Results are unrelated to -- 'SHAKE256' results. data SHAKE128 (bitlen :: Nat) = SHAKE128 - deriving (Show, Typeable) + deriving (Show, Data, Typeable) instance (IsDivisibleBy8 bitlen, KnownNat bitlen) => HashAlgorithm (SHAKE128 bitlen) where type HashBlockSize (SHAKE128 bitlen) = 168 @@ -58,7 +59,7 @@ instance (IsDivisibleBy8 bitlen, KnownNat bitlen) => HashAlgorithm (SHAKE128 bit -- correlated (one being a prefix of the other). Results are unrelated to -- 'SHAKE128' results. data SHAKE256 (bitlen :: Nat) = SHAKE256 - deriving (Show, Typeable) + deriving (Show, Data, Typeable) instance (IsDivisibleBy8 bitlen, KnownNat bitlen) => HashAlgorithm (SHAKE256 bitlen) where type HashBlockSize (SHAKE256 bitlen) = 136 From 455504b8e2f02bad2294a079057b0da41b5ab087 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Ch=C3=A9ron?= Date: Sun, 14 Oct 2018 16:58:29 +0200 Subject: [PATCH 3/7] Implement SHAKE output not divisible by 8 bits --- Crypto/Hash/SHAKE.hs | 33 ++++++++++++++++++++++----------- Crypto/Internal/Nat.hs | 4 ++-- tests/Hash.hs | 20 ++++++++++++++++++++ 3 files changed, 44 insertions(+), 13 deletions(-) diff --git a/Crypto/Hash/SHAKE.hs b/Crypto/Hash/SHAKE.hs index 4eed297..63d19d8 100644 --- a/Crypto/Hash/SHAKE.hs +++ b/Crypto/Hash/SHAKE.hs @@ -20,19 +20,21 @@ module Crypto.Hash.SHAKE ( SHAKE128 (..), SHAKE256 (..) ) where +import Control.Monad (when) import Crypto.Hash.Types -import Foreign.Ptr (Ptr) +import Foreign.Ptr (Ptr, castPtr) +import Foreign.Storable (Storable(..)) +import Data.Bits import Data.Data import Data.Typeable import Data.Word (Word8, Word32) import Data.Proxy (Proxy(..)) -import GHC.TypeLits (Nat, KnownNat, natVal) +import GHC.TypeLits (Nat, KnownNat, type (+)) import Crypto.Internal.Nat -- | SHAKE128 (128 bits) extendable output function. Supports an arbitrary --- digest size (multiple of 8 bits), to be specified as a type parameter --- of kind 'Nat'. +-- digest size, to be specified as a type parameter of kind 'Nat'. -- -- Note: outputs from @'SHAKE128' n@ and @'SHAKE128' m@ for the same input are -- correlated (one being a prefix of the other). Results are unrelated to @@ -40,9 +42,9 @@ import Crypto.Internal.Nat data SHAKE128 (bitlen :: Nat) = SHAKE128 deriving (Show, Data, Typeable) -instance (IsDivisibleBy8 bitlen, KnownNat bitlen) => HashAlgorithm (SHAKE128 bitlen) where +instance KnownNat bitlen => HashAlgorithm (SHAKE128 bitlen) where type HashBlockSize (SHAKE128 bitlen) = 168 - type HashDigestSize (SHAKE128 bitlen) = Div8 bitlen + type HashDigestSize (SHAKE128 bitlen) = Div8 (bitlen + 7) type HashInternalContextSize (SHAKE128 bitlen) = 376 hashBlockSize _ = 168 hashDigestSize _ = byteLen (Proxy :: Proxy bitlen) @@ -52,8 +54,7 @@ instance (IsDivisibleBy8 bitlen, KnownNat bitlen) => HashAlgorithm (SHAKE128 bit hashInternalFinalize = shakeFinalizeOutput (Proxy :: Proxy bitlen) -- | SHAKE256 (256 bits) extendable output function. Supports an arbitrary --- digest size (multiple of 8 bits), to be specified as a type parameter --- of kind 'Nat'. +-- digest size, to be specified as a type parameter of kind 'Nat'. -- -- Note: outputs from @'SHAKE256' n@ and @'SHAKE256' m@ for the same input are -- correlated (one being a prefix of the other). Results are unrelated to @@ -61,9 +62,9 @@ instance (IsDivisibleBy8 bitlen, KnownNat bitlen) => HashAlgorithm (SHAKE128 bit data SHAKE256 (bitlen :: Nat) = SHAKE256 deriving (Show, Data, Typeable) -instance (IsDivisibleBy8 bitlen, KnownNat bitlen) => HashAlgorithm (SHAKE256 bitlen) where +instance KnownNat bitlen => HashAlgorithm (SHAKE256 bitlen) where type HashBlockSize (SHAKE256 bitlen) = 136 - type HashDigestSize (SHAKE256 bitlen) = Div8 bitlen + type HashDigestSize (SHAKE256 bitlen) = Div8 (bitlen + 7) type HashInternalContextSize (SHAKE256 bitlen) = 344 hashBlockSize _ = 136 hashDigestSize _ = byteLen (Proxy :: Proxy bitlen) @@ -72,7 +73,7 @@ instance (IsDivisibleBy8 bitlen, KnownNat bitlen) => HashAlgorithm (SHAKE256 bit hashInternalUpdate = c_sha3_update hashInternalFinalize = shakeFinalizeOutput (Proxy :: Proxy bitlen) -shakeFinalizeOutput :: (IsDivisibleBy8 bitlen, KnownNat bitlen) +shakeFinalizeOutput :: KnownNat bitlen => proxy bitlen -> Ptr (Context a) -> Ptr (Digest a) @@ -80,6 +81,16 @@ shakeFinalizeOutput :: (IsDivisibleBy8 bitlen, KnownNat bitlen) shakeFinalizeOutput d ctx dig = do c_sha3_finalize_shake ctx c_sha3_output ctx dig (byteLen d) + shakeTruncate d (castPtr dig) + +shakeTruncate :: KnownNat bitlen => proxy bitlen -> Ptr Word8 -> IO () +shakeTruncate d ptr = + when (bits > 0) $ do + byte <- peekElemOff ptr index + pokeElemOff ptr index (byte .&. mask) + where + mask = (1 `shiftL` bits) - 1 + (index, bits) = integralNatVal d `divMod` 8 foreign import ccall unsafe "cryptonite_sha3_init" c_sha3_init :: Ptr (Context a) -> Word32 -> IO () diff --git a/Crypto/Internal/Nat.hs b/Crypto/Internal/Nat.hs index 39eae6f..3698a6b 100644 --- a/Crypto/Internal/Nat.hs +++ b/Crypto/Internal/Nat.hs @@ -15,8 +15,8 @@ module Crypto.Internal.Nat import GHC.TypeLits -byteLen :: (KnownNat bitlen, IsDivisibleBy8 bitlen, Num a) => proxy bitlen -> a -byteLen d = fromInteger (natVal d `div` 8) +byteLen :: (KnownNat bitlen, Num a) => proxy bitlen -> a +byteLen d = fromInteger ((natVal d + 7) `div` 8) integralNatVal :: (KnownNat bitlen, Num a) => proxy bitlen -> a integralNatVal = fromInteger . natVal diff --git a/tests/Hash.hs b/tests/Hash.hs index 5c699ef..d0f82c0 100644 --- a/tests/Hash.hs +++ b/tests/Hash.hs @@ -8,7 +8,9 @@ module Hash import Crypto.Hash import qualified Data.ByteString as B +import Data.ByteArray (convert) import qualified Data.ByteArray.Encoding as B (convertToBase, Base(..)) +import GHC.TypeLits import Imports v0,v1,v2 :: ByteString @@ -234,7 +236,25 @@ makeTestChunk (hashName, hashAlg, _) = runhash hashAlg inp `propertyEq` runhashinc hashAlg (chunkS ckLen inp) ] +-- SHAKE128 truncation example with expected byte at final position +-- +shake128TruncationBytes = [0x01, 0x03, 0x07, 0x0f, 0x0f, 0x2f, 0x6f, 0x6f] + +makeTestSHAKE128Truncation i byte = + testCase (show i) $ xof 4088 `B.snoc` byte @=? xof (4088 + i) + where + hashEmpty :: KnownNat n => proxy n -> Digest (SHAKE128 n) + hashEmpty _ = hash B.empty + + xof n = case someNatVal n of + Nothing -> error ("invalid Nat: " ++ show n) + Just (SomeNat p) -> convert (hashEmpty p) + tests = testGroup "hash" [ testGroup "KATs" (map makeTestAlg expected) , testGroup "Chunking" (concatMap makeTestChunk expected) + , testGroup "Truncating" + [ testGroup "SHAKE128" + (zipWith makeTestSHAKE128Truncation [1..] shake128TruncationBytes) + ] ] From 6a7594d2be3c388b9ad220f8f44230efa5d6c0f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Ch=C3=A9ron?= Date: Tue, 23 Oct 2018 19:32:23 +0200 Subject: [PATCH 4/7] Add GHC 8.6 to CI and bump LTS versions --- .haskell-ci | 12 ++++++------ .travis.yml | 12 ++++++++---- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/.haskell-ci b/.haskell-ci index 82d4a84..e0ccd0d 100644 --- a/.haskell-ci +++ b/.haskell-ci @@ -1,20 +1,20 @@ # compiler supported and their equivalent LTS compiler: ghc-8.0 lts-9.21 -compiler: ghc-8.2 lts-11.6 -compiler: ghc-8.4 ghc-8.4.2 +compiler: ghc-8.2 lts-11.22 +compiler: ghc-8.4 lts-12.14 +compiler: ghc-8.6 nightly-2018-10-21 # options # option: alias x=y z=v -option: testdeps extradep=QuickCheck-2.11.3 extradep=ansi-terminal-0.8.0.1 extradep=async-2.1.1.1 extradep=call-stack-0.1.0 extradep=clock-0.7.2 extradep=optparse-applicative-0.14.0.0 extradep=random-1.1 extradep=tagged-0.8.5 extradep=unbounded-delays-0.1.1.0 extradep=tasty-1.0.0.1 extradep=tasty-hunit-0.10.0.1 extradep=tasty-kat-0.0.3 extradep=tasty-quickcheck-0.9.2 extradep=ansi-wl-pprint-0.6.8.2 extradep=colour-2.3.4 extradep=tf-random-0.5 extradep=transformers-compat-0.5.1.4 extradep=primitive-0.6.3.0 allow-newer option: gaugedeps extradep=gauge-0.2.1 - option: basementmin extradep=basement-0.0.6 extradep=foundation-0.0.19 extradep=memory-0.14.14 # builds -build: ghc-8.2 basementmin gaugedeps +build: ghc-8.2 build: ghc-8.0 basementmin gaugedeps build: ghc-8.0 basementmin gaugedeps os=osx -build: ghc-8.4 basementmin testdeps gaugedeps extradep=vector-0.12.0.1 +build: ghc-8.4 +build: ghc-8.6 # packages package: '.' diff --git a/.travis.yml b/.travis.yml index eec4255..6b45760 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ -# ~*~ auto-generated by haskell-ci with config : 7d7fe90696706f37292f4d718fa1a63b938490d653e3abf049623087b2e6e901 ~*~ +# ~*~ auto-generated by haskell-ci with config : 7cb8db1c90854ae440aca1b3cde96895bf9153ceeddfe5fd39d82f8e300414c6 ~*~ # Use new container infrastructure to enable caching sudo: false @@ -16,6 +16,7 @@ matrix: - { env: BUILD=stack RESOLVER=ghc-8.0, compiler: ghc-8.0, language: generic, addons: { apt: { packages: [ libgmp-dev ] } } } - { env: BUILD=stack RESOLVER=ghc-8.0, compiler: ghc-8.0, language: generic, addons: { apt: { packages: [ libgmp-dev ] } }, os: osx } - { env: BUILD=stack RESOLVER=ghc-8.4, compiler: ghc-8.4, language: generic, addons: { apt: { packages: [ libgmp-dev ] } } } + - { env: BUILD=stack RESOLVER=ghc-8.6, compiler: ghc-8.6, language: generic, addons: { apt: { packages: [ libgmp-dev ] } } } - { env: BUILD=hlint, compiler: hlint, language: generic } - { env: BUILD=weeder, compiler: weeder, language: generic, addons: { apt: { packages: [ libgmp-dev ] } } } allow_failures: @@ -48,7 +49,7 @@ script: # create the build stack.yaml case "$RESOLVER" in ghc-8.2) - echo "{ resolver: lts-11.6, packages: [ '.' ], extra-deps: [ basement-0.0.6, foundation-0.0.19, memory-0.14.14, gauge-0.2.1 ], flags: {} }" > stack.yaml + echo "{ resolver: lts-11.22, packages: [ '.' ], extra-deps: [], flags: {} }" > stack.yaml stack --no-terminal build --install-ghc --coverage --test --bench --no-run-benchmarks --haddock --no-haddock-deps ;; ghc-8.0) @@ -60,7 +61,11 @@ script: stack --no-terminal build --install-ghc --coverage --test --bench --no-run-benchmarks --haddock --no-haddock-deps ;; ghc-8.4) - echo "{ resolver: ghc-8.4.2, packages: [ '.' ], extra-deps: [ vector-0.12.0.1, basement-0.0.6, foundation-0.0.19, memory-0.14.14, QuickCheck-2.11.3, ansi-terminal-0.8.0.1, async-2.1.1.1, call-stack-0.1.0, clock-0.7.2, optparse-applicative-0.14.0.0, random-1.1, tagged-0.8.5, unbounded-delays-0.1.1.0, tasty-1.0.0.1, tasty-hunit-0.10.0.1, tasty-kat-0.0.3, tasty-quickcheck-0.9.2, ansi-wl-pprint-0.6.8.2, colour-2.3.4, tf-random-0.5, transformers-compat-0.5.1.4, primitive-0.6.3.0, gauge-0.2.1 ], flags: {}, allow-newer: true }" > stack.yaml + echo "{ resolver: lts-12.14, packages: [ '.' ], extra-deps: [], flags: {} }" > stack.yaml + stack --no-terminal build --install-ghc --coverage --test --bench --no-run-benchmarks --haddock --no-haddock-deps + ;; + ghc-8.6) + echo "{ resolver: nightly-2018-10-21, packages: [ '.' ], extra-deps: [], flags: {} }" > stack.yaml stack --no-terminal build --install-ghc --coverage --test --bench --no-run-benchmarks --haddock --no-haddock-deps ;; esac @@ -75,4 +80,3 @@ script: esac set +ex - From 77bc512a8796a9043aaae227b807b8e76534d951 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Ch=C3=A9ron?= Date: Wed, 24 Oct 2018 21:25:14 +0200 Subject: [PATCH 5/7] Add a default stack.yaml Will be useful for the weeder build in CI. --- stack.yaml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 stack.yaml diff --git a/stack.yaml b/stack.yaml new file mode 100644 index 0000000..57f8c6b --- /dev/null +++ b/stack.yaml @@ -0,0 +1,3 @@ +# ~*~ auto-generated by haskell-ci with config : 7cb8db1c90854ae440aca1b3cde96895bf9153ceeddfe5fd39d82f8e300414c6 ~*~ +{ resolver: lts-12.14, packages: [ '.' ], extra-deps: [], flags: {} } + From ee9c485a4d589205479d1f767f54d624e05a1fb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Ch=C3=A9ron?= Date: Fri, 26 Oct 2018 18:31:29 +0200 Subject: [PATCH 6/7] Update tested-with --- cryptonite.cabal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cryptonite.cabal b/cryptonite.cabal index bbfebac..5d19c59 100644 --- a/cryptonite.cabal +++ b/cryptonite.cabal @@ -36,7 +36,7 @@ Build-Type: Simple Homepage: https://github.com/haskell-crypto/cryptonite Bug-reports: https://github.com/haskell-crypto/cryptonite/issues Cabal-Version: >=1.18 -tested-with: GHC==8.4.2, GHC==8.2.2, GHC==8.0.2 +tested-with: GHC==8.6.1, GHC==8.4.3, GHC==8.2.2, GHC==8.0.2 extra-doc-files: README.md CHANGELOG.md extra-source-files: cbits/*.h cbits/aes/*.h From d4bd9287f2d964368caf87bc24bc1d91499eee9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Ch=C3=A9ron?= Date: Sun, 28 Oct 2018 17:52:36 +0100 Subject: [PATCH 7/7] Test with GHC 8.4.4 --- .haskell-ci | 2 +- .travis.yml | 4 ++-- cryptonite.cabal | 2 +- stack.yaml | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.haskell-ci b/.haskell-ci index e0ccd0d..bb9bd3f 100644 --- a/.haskell-ci +++ b/.haskell-ci @@ -1,7 +1,7 @@ # compiler supported and their equivalent LTS compiler: ghc-8.0 lts-9.21 compiler: ghc-8.2 lts-11.22 -compiler: ghc-8.4 lts-12.14 +compiler: ghc-8.4 lts-12.15 compiler: ghc-8.6 nightly-2018-10-21 # options diff --git a/.travis.yml b/.travis.yml index 6b45760..e542406 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ -# ~*~ auto-generated by haskell-ci with config : 7cb8db1c90854ae440aca1b3cde96895bf9153ceeddfe5fd39d82f8e300414c6 ~*~ +# ~*~ auto-generated by haskell-ci with config : c5de1915986b17c62e2a4cbe1fb7b3d47a6b1dc45a8f4d4fa78654695dfd1f43 ~*~ # Use new container infrastructure to enable caching sudo: false @@ -61,7 +61,7 @@ script: stack --no-terminal build --install-ghc --coverage --test --bench --no-run-benchmarks --haddock --no-haddock-deps ;; ghc-8.4) - echo "{ resolver: lts-12.14, packages: [ '.' ], extra-deps: [], flags: {} }" > stack.yaml + echo "{ resolver: lts-12.15, packages: [ '.' ], extra-deps: [], flags: {} }" > stack.yaml stack --no-terminal build --install-ghc --coverage --test --bench --no-run-benchmarks --haddock --no-haddock-deps ;; ghc-8.6) diff --git a/cryptonite.cabal b/cryptonite.cabal index 5d19c59..f2fa323 100644 --- a/cryptonite.cabal +++ b/cryptonite.cabal @@ -36,7 +36,7 @@ Build-Type: Simple Homepage: https://github.com/haskell-crypto/cryptonite Bug-reports: https://github.com/haskell-crypto/cryptonite/issues Cabal-Version: >=1.18 -tested-with: GHC==8.6.1, GHC==8.4.3, GHC==8.2.2, GHC==8.0.2 +tested-with: GHC==8.6.1, GHC==8.4.4, GHC==8.2.2, GHC==8.0.2 extra-doc-files: README.md CHANGELOG.md extra-source-files: cbits/*.h cbits/aes/*.h diff --git a/stack.yaml b/stack.yaml index 57f8c6b..bd5b3a6 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1,3 +1,3 @@ -# ~*~ auto-generated by haskell-ci with config : 7cb8db1c90854ae440aca1b3cde96895bf9153ceeddfe5fd39d82f8e300414c6 ~*~ -{ resolver: lts-12.14, packages: [ '.' ], extra-deps: [], flags: {} } +# ~*~ auto-generated by haskell-ci with config : c5de1915986b17c62e2a4cbe1fb7b3d47a6b1dc45a8f4d4fa78654695dfd1f43 ~*~ +{ resolver: lts-12.15, packages: [ '.' ], extra-deps: [], flags: {} }