cryptohash-0.11.9/0000755000000000000000000000000012675272160012164 5ustar0000000000000000cryptohash-0.11.9/cryptohash.cabal0000644000000000000000000001020612675272160015333 0ustar0000000000000000Name: cryptohash Version: 0.11.9 Description: DEPRECATED: this library is still fully functional, but please use cryptonite for new projects and convert old one to use cryptonite. This is where things are at nowadays. . A collection of crypto hashes, with a practical incremental and one-pass, pure APIs, with performance close to the fastest implementations available in other languages. . The implementations are made in C with a haskell FFI wrapper that hide the C implementation. . Simple examples using the unified API: . > import Crypto.Hash > > sha1 :: ByteString -> Digest SHA1 > sha1 = hash > > hexSha3_512 :: ByteString -> String > hexSha3_512 bs = show (hash bs :: Digest SHA3_512) . Simple examples using the module API: . > import qualified Crypto.Hash.SHA1 as SHA1 > > main = putStrLn $ show $ SHA1.hash (Data.ByteString.pack [0..255]) . > import qualified Crypto.Hash.SHA3 as SHA3 > > main = putStrLn $ show $ digest > where digest = SHA3.finalize ctx > ctx = foldl' SHA3.update iCtx (map Data.ByteString.pack [ [1,2,3], [4,5,6] ] > iCtx = SHA3.init 224 License: BSD3 License-file: LICENSE Copyright: Vincent Hanquez Author: Vincent Hanquez Maintainer: Vincent Hanquez Synopsis: collection of crypto hashes, fast, pure and practical Category: Data, Cryptography Build-Type: Simple Cabal-Version: >=1.8 Homepage: http://github.com/vincenthz/hs-cryptohash extra-source-files: cbits/bitfn.h cbits/sha512.h cbits/sha3.h cbits/skein.h cbits/skein256.h cbits/skein512.h README.md Library Build-Depends: base >= 4 && < 6, bytestring, byteable, cryptonite >= 0.13, memory, ghc-prim if impl(ghc >= 7.2.1) Extensions: Trustworthy Extensions: ForeignFunctionInterface Exposed-modules: Crypto.Hash Crypto.Hash.Types Crypto.MAC Crypto.Hash.SHA1 Crypto.Hash.SHA224 Crypto.Hash.SHA256 Crypto.Hash.SHA384 Crypto.Hash.SHA512 Crypto.Hash.SHA512t Crypto.Hash.SHA3 Crypto.Hash.MD2 Crypto.Hash.MD4 Crypto.Hash.MD5 Crypto.Hash.RIPEMD160 Crypto.Hash.Skein256 Crypto.Hash.Skein512 Crypto.Hash.Tiger Crypto.Hash.Whirlpool Crypto.MAC.HMAC Crypto.MAC.SHA3 Other-modules: Crypto.Hash.Internal ghc-options: -Wall -optc-O3 -fno-cse -fwarn-tabs C-sources: cbits/sha512.c cbits/sha3.c cbits/skein256.c cbits/skein512.c Include-Dirs: cbits if (arch(i386) || arch(x86_64)) cpp-options: -DARCH_X86 Test-Suite test-kat type: exitcode-stdio-1.0 hs-source-dirs: Tests Main-Is: KAT.hs Build-depends: base >= 4 && < 5 , bytestring , byteable , HUnit , QuickCheck >= 2 , tasty , tasty-quickcheck , tasty-hunit , cryptohash Benchmark bench-hashes Main-Is: Bench.hs hs-source-dirs: Bench type: exitcode-stdio-1.0 Build-depends: base >= 4, bytestring, criterion, cryptohash Benchmark bench-hmac Main-Is: BenchHMAC.hs hs-source-dirs: Bench type: exitcode-stdio-1.0 Build-depends: base >= 4, bytestring, criterion, cryptohash, byteable Benchmark bench-api Main-Is: BenchAPI.hs hs-source-dirs: Bench type: exitcode-stdio-1.0 Build-depends: base >= 4, bytestring, criterion, cryptohash, byteable source-repository head type: git location: git://github.com/vincenthz/hs-cryptohash cryptohash-0.11.9/LICENSE0000644000000000000000000000273112675272160013174 0ustar0000000000000000Copyright (c) 2010-2014 Vincent Hanquez All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the author nor the names of his contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. cryptohash-0.11.9/README.md0000644000000000000000000000666412675272160013457 0ustar0000000000000000:warning: this library is now deprecated in favor of `cryptonite`, which is a superset of this, and also have more functionality. For new projects, you should *not* use this library anymore, and preferably you should convert old projects to `cryptonite` too. :warning: the SHA3 implementation available in Crypto.Hash.SHA3 is not SHA3 as standardized by NIST, but Keccak as submitted for the SHA3 contest. A matching implementation is available as Keccak in `cryptonite`, although I would recommend not to use unless you happens to really really need your digest value to be compatible. On the other hand, the centralized `Crypto.Hash` export a proper SHA3 implementation (as standardized by NIST) CryptoHash ========== `hs-cryptohash` provides many different secure digest algorithms, also called cryptographic hash functions or, simply, cryptohashes. The package exports common hash functions, as well as some more exotic ones, and provides a single API for them all. The general performance is comparable to the most optimised implementations available. Here is the complete list of supported algorithms: * MD2, MD4, MD5 * RIPEMD160 * SHA1 * SHA-2 family: 224, 256, 384, 512 and the newer 512t * SHA-3 (aka Keccak) * Skein: 256, 512 * Tiger * Whirlpool You can easily import any hash with the following: import qualified Crypto.Hash. as We recommend using `import qualified` because the APIs are similar and many of the modules reuse the same names. However, if you are ony using one module, there is no need to qualify the names. Incremental API --------------- it's based on 4 different functions, similar to the lowlevel operations of a typical hash: * init: create a new hash context * update: update non-destructively a new hash context with a strict bytestring * updates: same as update, except that it takes a list of strict bytestring * finalize: finalize the context and returns a digest bytestring. all those operations are completely pure, and instead of changing the context as usual in others language, it re-allocates a new context each time. One Pass API ------------ The one pass API use the incremental API under the hood, but expose common operations to create digests out of a bytestring and lazy bytestring. * hash: create a digest (init+update+finalize) from a strict bytestring * hashlazy: create a digest (init+update+finalize) from a lazy bytestring More Type safety ---------------- A more type safe API is also available from Crypto.Hash. The API provides all the supported hashes in the same namespace, through unified functions. It introduces 2 new types, the Context type and the Digest type. Both those types are parametrized with the HashAlgorithm used. The API is very similar to each single hash module, except the types are slightly different. import Crypto.Hash -- use the incremental API to hash the byte [1,2,3] with SHA1 -- and print the hexadecimal digest. example1 = do let ctx = hashInit ctx' = hashUpdates ctx [ Data.ByteString.pack [1,2,3] ] dgt = hashFinalize ctx' :: Digest SHA1 putStrLn $ show dgt -- use the one-pass API to hash the byte 1,2,3 with SHA3_512 -- and print the hexadecimal digest. example2 = do let dgt = hash (Data.ByteString.pack [1,2,3]) :: Digest SHA3_512 putStrLn $ show dgt Performance ----------- Cryptohash uses C implementations to provide maximum performance. see the cbits directory for more information cryptohash-0.11.9/Setup.hs0000644000000000000000000000005612675272160013621 0ustar0000000000000000import Distribution.Simple main = defaultMain cryptohash-0.11.9/Bench/0000755000000000000000000000000012675272160013203 5ustar0000000000000000cryptohash-0.11.9/Bench/Bench.hs0000644000000000000000000000664212675272160014566 0ustar0000000000000000{-# LANGUAGE BangPatterns #-} import Criterion.Main import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as L import qualified Crypto.Hash.MD2 as MD2 import qualified Crypto.Hash.MD4 as MD4 import qualified Crypto.Hash.MD5 as MD5 import qualified Crypto.Hash.SHA1 as SHA1 import qualified Crypto.Hash.SHA224 as SHA224 import qualified Crypto.Hash.SHA256 as SHA256 import qualified Crypto.Hash.SHA384 as SHA384 import qualified Crypto.Hash.SHA512 as SHA512 import qualified Crypto.Hash.SHA512t as SHA512t import qualified Crypto.Hash.SHA3 as SHA3 import qualified Crypto.Hash.RIPEMD160 as RIPEMD160 import qualified Crypto.Hash.Tiger as Tiger import qualified Crypto.Hash.Skein256 as Skein256 import qualified Crypto.Hash.Skein512 as Skein512 import qualified Crypto.Hash.Whirlpool as Whirlpool hashmany (i,u,f) = f . foldl u i allHashs = [ ("MD2",MD2.hash, hashmany (MD2.init,MD2.update,MD2.finalize)) , ("MD4",MD4.hash, hashmany (MD4.init,MD4.update,MD4.finalize)) , ("MD5",MD5.hash, hashmany (MD5.init,MD5.update,MD5.finalize)) , ("SHA1",SHA1.hash, hashmany (SHA1.init,SHA1.update,SHA1.finalize)) , ("SHA2-224",SHA224.hash, hashmany (SHA224.init,SHA224.update,SHA224.finalize)) , ("SHA2-256",SHA256.hash, hashmany (SHA256.init,SHA256.update,SHA256.finalize)) , ("SHA2-384",SHA384.hash, hashmany (SHA384.init,SHA384.update,SHA384.finalize)) , ("SHA2-512",SHA512.hash, hashmany (SHA512.init,SHA512.update,SHA512.finalize)) , ("SHA2-512t-512",SHA512t.hash 512, hashmany (SHA512t.init 512,SHA512t.update,SHA512t.finalize)) , ("SHA3-224",SHA3.hash 224, hashmany (SHA3.init 224,SHA3.update,SHA3.finalize)) , ("SHA3-256",SHA3.hash 256, hashmany (SHA3.init 256,SHA3.update,SHA3.finalize)) , ("SHA3-384",SHA3.hash 384, hashmany (SHA3.init 384,SHA3.update,SHA3.finalize)) , ("SHA3-512",SHA3.hash 512, hashmany (SHA3.init 512,SHA3.update,SHA3.finalize)) , ("RIPEMD160",RIPEMD160.hash, hashmany (RIPEMD160.init,RIPEMD160.update,RIPEMD160.finalize)) , ("Tiger",Tiger.hash, hashmany (Tiger.init,Tiger.update,Tiger.finalize)) , ("Skein256-256",Skein256.hash 256, hashmany (Skein256.init 256,Skein256.update,Skein256.finalize)) , ("Skein512-512",Skein512.hash 512, hashmany (Skein512.init 512,Skein512.update,Skein512.finalize)) , ("Whirlpool",Whirlpool.hash, hashmany (Whirlpool.init,Whirlpool.update,Whirlpool.finalize)) ] benchHash :: a -> (a -> B.ByteString) -> Pure benchHash bs f = whnf f bs withHashesFilter out f = map f $ filter (\(n,_,_) -> not (n `elem` out)) allHashs withHashes f = map f allHashs main = do let !bs32 = B.replicate 32 0 !bs256 = B.replicate 256 0 !bs4096 = B.replicate 4096 0 !bs1M = B.replicate (1*1024*1024) 0 let !lbs64x256 = (map (const (B.replicate 64 0)) [0..3]) !lbs64x4096 = (map (const (B.replicate 64 0)) [0..63]) defaultMain [ bgroup "hash-32b" (withHashes (\(name, f,_) -> bench name $ benchHash bs32 f)) , bgroup "hash-256b" (withHashes (\(name, f,_) -> bench name $ benchHash bs256 f)) , bgroup "hash-4Kb" (withHashes (\(name, f,_) -> bench name $ benchHash bs4096 f)) , bgroup "hash-1Mb" (withHashesFilter ["MD2"] (\(name, f,_) -> bench name $ benchHash bs1M f)) , bgroup "iuf-64x256" (withHashes (\(name, _,f) -> bench name $ benchHash lbs64x256 f)) , bgroup "iuf-64x4096" (withHashes (\(name, _,f) -> bench name $ benchHash lbs64x4096 f)) ] cryptohash-0.11.9/Bench/BenchAPI.hs0000644000000000000000000000410312675272160015106 0ustar0000000000000000{-# LANGUAGE BangPatterns #-} import Criterion.Main import Data.Byteable import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as L import qualified Crypto.Hash.SHA1 as SHA1 import qualified Crypto.Hash.SHA512 as SHA512 import qualified Crypto.Hash.SHA3 as SHA3 import Crypto.Hash sha1F = ( "sha1" , SHA1.hash , SHA1.finalize . SHA1.update SHA1.init , toBytes . (hash :: B.ByteString -> Digest SHA1) ) sha512F = ( "sha512" , SHA512.hash , SHA512.finalize . SHA512.update SHA512.init , toBytes . (hash :: B.ByteString -> Digest SHA512) ) main = do let !bs32 = B.replicate 32 0 !bs256 = B.replicate 256 0 !bs4096 = B.replicate 4096 0 !bs1M = B.replicate (1*1024*1024) 0 let !lbs64x256 = (map (const (B.replicate 64 0)) [0..3]) !lbs64x4096 = (map (const (B.replicate 64 0)) [0..63]) let (fname, fHash, fIncr, fAPI) = sha512F let benchName ty z = fname ++ "." ++ ty ++ " " ++ show z defaultMain [ bgroup "digest hex" [ bench "hex" $ whnf digestToHexByteString (hashsha1 B.empty) ] , bcompare [ bench (benchName "hash" 0) $ whnf fHash B.empty , bench (benchName "incr" 0) $ whnf fIncr B.empty , bench (benchName "api" 0) $ whnf fAPI B.empty ] , bcompare [ bench (benchName "hash" 32) $ whnf SHA1.hash bs32 , bench (benchName "incr" 32) $ whnf fIncr bs32 , bench (benchName "api" 32) $ whnf fAPI bs32 ] , bcompare [ bench (benchName "hash" 256) $ whnf SHA1.hash bs256 , bench (benchName "incr" 256) $ whnf fIncr bs256 , bench (benchName "api" 256) $ whnf fAPI bs256 ] , bcompare [ bench (benchName "hash" 4096) $ whnf SHA1.hash bs4096 , bench (benchName "incr" 4096) $ whnf fIncr bs4096 , bench (benchName "api" 4096) $ whnf fAPI bs4096 ] ] where hashsha1 = hash :: B.ByteString -> Digest SHA1 cryptohash-0.11.9/Bench/BenchHMAC.hs0000644000000000000000000000045712675272160015215 0ustar0000000000000000 import Criterion.Main import Crypto.Hash import qualified Data.ByteString as B import Data.Byteable main = do let b32 = B.replicate 32 0 defaultMain [ bench "hmac-md5" $ whnf (toBytes . hmacAlg MD5 b32) b32 , bench "hmac-sha1" $ whnf (toBytes . hmacAlg SHA1 b32) b32 ] cryptohash-0.11.9/cbits/0000755000000000000000000000000012675272160013270 5ustar0000000000000000cryptohash-0.11.9/cbits/bitfn.h0000644000000000000000000001531412675272160014547 0ustar0000000000000000/* * Copyright (C) 2006-2009 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef BITFN_H #define BITFN_H #include #ifndef NO_INLINE_ASM /**********************************************************/ # if (defined(__i386__)) # define ARCH_HAS_SWAP32 static inline uint32_t bitfn_swap32(uint32_t a) { asm ("bswap %0" : "=r" (a) : "0" (a)); return a; } /**********************************************************/ # elif (defined(__arm__)) # define ARCH_HAS_SWAP32 static inline uint32_t bitfn_swap32(uint32_t a) { uint32_t tmp = a; asm volatile ("eor %1, %0, %0, ror #16\n" "bic %1, %1, #0xff0000\n" "mov %0, %0, ror #8\n" "eor %0, %0, %1, lsr #8\n" : "=r" (a), "=r" (tmp) : "0" (a), "1" (tmp)); return a; } /**********************************************************/ # elif defined(__x86_64__) # define ARCH_HAS_SWAP32 # define ARCH_HAS_SWAP64 static inline uint32_t bitfn_swap32(uint32_t a) { asm ("bswap %0" : "=r" (a) : "0" (a)); return a; } static inline uint64_t bitfn_swap64(uint64_t a) { asm ("bswap %0" : "=r" (a) : "0" (a)); return a; } # endif #endif /* NO_INLINE_ASM */ /**********************************************************/ #ifndef ARCH_HAS_ROL32 static inline uint32_t rol32(uint32_t word, uint32_t shift) { return (word << shift) | (word >> (32 - shift)); } #endif #ifndef ARCH_HAS_ROR32 static inline uint32_t ror32(uint32_t word, uint32_t shift) { return (word >> shift) | (word << (32 - shift)); } #endif #ifndef ARCH_HAS_ROL64 static inline uint64_t rol64(uint64_t word, uint32_t shift) { return (word << shift) | (word >> (64 - shift)); } #endif #ifndef ARCH_HAS_ROR64 static inline uint64_t ror64(uint64_t word, uint32_t shift) { return (word >> shift) | (word << (64 - shift)); } #endif #ifndef ARCH_HAS_SWAP32 static inline uint32_t bitfn_swap32(uint32_t a) { return (a << 24) | ((a & 0xff00) << 8) | ((a >> 8) & 0xff00) | (a >> 24); } #endif #ifndef ARCH_HAS_ARRAY_SWAP32 static inline void array_swap32(uint32_t *d, uint32_t *s, uint32_t nb) { while (nb--) *d++ = bitfn_swap32(*s++); } #endif #ifndef ARCH_HAS_SWAP64 static inline uint64_t bitfn_swap64(uint64_t a) { return ((uint64_t) bitfn_swap32((uint32_t) (a >> 32))) | (((uint64_t) bitfn_swap32((uint32_t) a)) << 32); } #endif #ifndef ARCH_HAS_ARRAY_SWAP64 static inline void array_swap64(uint64_t *d, uint64_t *s, uint32_t nb) { while (nb--) *d++ = bitfn_swap64(*s++); } #endif #ifndef ARCH_HAS_MEMORY_ZERO static inline void memory_zero(void *ptr, uint32_t len) { uint32_t *ptr32 = ptr; uint8_t *ptr8; int i; for (i = 0; i < len / 4; i++) *ptr32++ = 0; if (len % 4) { ptr8 = (uint8_t *) ptr32; for (i = len % 4; i >= 0; i--) ptr8[i] = 0; } } #endif #ifndef ARCH_HAS_ARRAY_COPY32 static inline void array_copy32(uint32_t *d, uint32_t *s, uint32_t nb) { while (nb--) *d++ = *s++; } #endif #ifndef ARCH_HAS_ARRAY_COPY64 static inline void array_copy64(uint64_t *d, uint64_t *s, uint32_t nb) { while (nb--) *d++ = *s++; } #endif #ifdef __MINGW32__ # define LITTLE_ENDIAN 1234 # define BYTE_ORDER LITTLE_ENDIAN #elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__) # include #elif defined(__OpenBSD__) || defined(__SVR4) # include #elif defined(__APPLE__) # include #elif defined( BSD ) && ( BSD >= 199103 ) # include #elif defined( __QNXNTO__ ) && defined( __LITTLEENDIAN__ ) # define LITTLE_ENDIAN 1234 # define BYTE_ORDER LITTLE_ENDIAN #elif defined( __QNXNTO__ ) && defined( __BIGENDIAN__ ) # define BIG_ENDIAN 1234 # define BYTE_ORDER BIG_ENDIAN #elif defined( _AIX ) # include #else # include #endif /* big endian to cpu */ #if LITTLE_ENDIAN == BYTE_ORDER # define be32_to_cpu(a) bitfn_swap32(a) # define cpu_to_be32(a) bitfn_swap32(a) # define le32_to_cpu(a) (a) # define cpu_to_le32(a) (a) # define be64_to_cpu(a) bitfn_swap64(a) # define cpu_to_be64(a) bitfn_swap64(a) # define le64_to_cpu(a) (a) # define cpu_to_le64(a) (a) # define cpu_to_le32_array(d, s, l) array_copy32(d, s, l) # define le32_to_cpu_array(d, s, l) array_copy32(d, s, l) # define cpu_to_be32_array(d, s, l) array_swap32(d, s, l) # define be32_to_cpu_array(d, s, l) array_swap32(d, s, l) # define cpu_to_le64_array(d, s, l) array_copy64(d, s, l) # define le64_to_cpu_array(d, s, l) array_copy64(d, s, l) # define cpu_to_be64_array(d, s, l) array_swap64(d, s, l) # define be64_to_cpu_array(d, s, l) array_swap64(d, s, l) # define ror32_be(a, s) rol32(a, s) # define rol32_be(a, s) ror32(a, s) # define ARCH_IS_LITTLE_ENDIAN #elif BIG_ENDIAN == BYTE_ORDER # define be32_to_cpu(a) (a) # define cpu_to_be32(a) (a) # define be64_to_cpu(a) (a) # define cpu_to_be64(a) (a) # define le64_to_cpu(a) bitfn_swap64(a) # define cpu_to_le64(a) bitfn_swap64(a) # define le32_to_cpu(a) bitfn_swap32(a) # define cpu_to_le32(a) bitfn_swap32(a) # define cpu_to_le32_array(d, s, l) array_swap32(d, s, l) # define le32_to_cpu_array(d, s, l) array_swap32(d, s, l) # define cpu_to_be32_array(d, s, l) array_copy32(d, s, l) # define be32_to_cpu_array(d, s, l) array_copy32(d, s, l) # define cpu_to_le64_array(d, s, l) array_swap64(d, s, l) # define le64_to_cpu_array(d, s, l) array_swap64(d, s, l) # define cpu_to_be64_array(d, s, l) array_copy64(d, s, l) # define be64_to_cpu_array(d, s, l) array_copy64(d, s, l) # define ror32_be(a, s) ror32(a, s) # define rol32_be(a, s) rol32(a, s) # define ARCH_IS_BIG_ENDIAN #else # error "endian not supported" #endif #endif /* !BITFN_H */ cryptohash-0.11.9/cbits/sha3.c0000644000000000000000000001176012675272160014277 0ustar0000000000000000/* * Copyright (C) 2012 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include "bitfn.h" #include "sha3.h" #define KECCAK_NB_ROUNDS 24 /* rounds constants */ static const uint64_t keccak_rndc[24] = { 0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808aULL, 0x8000000080008000ULL, 0x000000000000808bULL, 0x0000000080000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL, 0x000000000000008aULL, 0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000aULL, 0x000000008000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL, 0x8000000000008002ULL, 0x8000000000000080ULL, 0x000000000000800aULL, 0x800000008000000aULL, 0x8000000080008081ULL, 0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL, }; /* triangular numbers constants */ static const int keccak_rotc[24] = { 1,3,6,10,15,21,28,36,45,55,2,14,27,41,56,8,25,43,62,18,39,61,20,44 }; static const int keccak_piln[24] = { 10,7,11,17,18,3,5,16,8,21,24,4,15,23,19,13,12,2,20,14,22,9,6,1 }; static inline void sha3_do_chunk(uint64_t state[25], uint64_t buf[], int bufsz) { int i, j, r; uint64_t tmp, bc[5]; /* merge buf with state */ for (i = 0; i < bufsz; i++) state[i] ^= le64_to_cpu(buf[i]); /* run keccak rounds */ for (r = 0; r < KECCAK_NB_ROUNDS; r++) { /* compute the parity of each columns */ for (i = 0; i < 5; i++) bc[i] = state[i] ^ state[i+5] ^ state[i+10] ^ state[i+15] ^ state[i+20]; for (i = 0; i < 5; i++) { tmp = bc[(i + 4) % 5] ^ rol64(bc[(i + 1) % 5], 1); for (j = 0; j < 25; j += 5) state[j + i] ^= tmp; } /* rho pi */ tmp = state[1]; for (i = 0; i < 24; i++) { j = keccak_piln[i]; bc[0] = state[j]; state[j] = rol64(tmp, keccak_rotc[i]); tmp = bc[0]; } /* bitwise combine along rows using a = a xor (not b and c) */ for (j = 0; j < 25; j += 5) { for (i = 0; i < 5; i++) bc[i] = state[j + i]; #define andn(b,c) (~(b) & (c)) state[j + 0] ^= andn(bc[1], bc[2]); state[j + 1] ^= andn(bc[2], bc[3]); state[j + 2] ^= andn(bc[3], bc[4]); state[j + 3] ^= andn(bc[4], bc[0]); state[j + 4] ^= andn(bc[0], bc[1]); #undef andn } /* xor the round constant */ state[0] ^= keccak_rndc[r]; } } void cryptohash_sha3_init(struct sha3_ctx *ctx, uint32_t hashlen) { memset(ctx, 0, sizeof(*ctx)); ctx->hashlen = hashlen / 8; ctx->bufsz = 200 - 2 * ctx->hashlen; } void cryptohash_sha3_update(struct sha3_ctx *ctx, uint8_t *data, uint32_t len) { uint32_t to_fill; to_fill = ctx->bufsz - ctx->bufindex; if (ctx->bufindex == ctx->bufsz) { sha3_do_chunk(ctx->state, (uint64_t *) ctx->buf, ctx->bufsz / 8); ctx->bufindex = 0; } /* process partial buffer if there's enough data to make a block */ if (ctx->bufindex && len >= to_fill) { memcpy(ctx->buf + ctx->bufindex, data, to_fill); sha3_do_chunk(ctx->state, (uint64_t *) ctx->buf, ctx->bufsz / 8); len -= to_fill; data += to_fill; ctx->bufindex = 0; } /* process as much ctx->bufsz-block */ for (; len >= ctx->bufsz; len -= ctx->bufsz, data += ctx->bufsz) sha3_do_chunk(ctx->state, (uint64_t *) data, ctx->bufsz / 8); /* append data into buf */ if (len) { memcpy(ctx->buf + ctx->bufindex, data, len); ctx->bufindex += len; } } void cryptohash_sha3_finalize(struct sha3_ctx *ctx, uint8_t *out) { uint64_t w[25]; /* process full buffer if needed */ if (ctx->bufindex == ctx->bufsz) { sha3_do_chunk(ctx->state, (uint64_t *) ctx->buf, ctx->bufsz / 8); ctx->bufindex = 0; } /* add the 10*1 padding */ ctx->buf[ctx->bufindex++] = 1; memset(ctx->buf + ctx->bufindex, 0, ctx->bufsz - ctx->bufindex); ctx->buf[ctx->bufsz - 1] |= 0x80; /* process */ sha3_do_chunk(ctx->state, (uint64_t *) ctx->buf, ctx->bufsz / 8); /* output */ cpu_to_le64_array(w, ctx->state, 25); memcpy(out, w, ctx->hashlen); } cryptohash-0.11.9/cbits/sha3.h0000644000000000000000000000351512675272160014303 0ustar0000000000000000/* * Copyright (C) 2012 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef CRYPTOHASH_SHA3_H #define CRYPTOHASH_SHA3_H #include struct sha3_ctx { uint32_t hashlen; /* in bytes */ uint32_t bufindex; uint64_t state[25]; uint32_t bufsz; uint32_t _padding; uint8_t buf[144]; /* minimum SHA3-224, otherwise buffer need increases */ }; #define SHA3_CTX_SIZE sizeof(struct sha3_ctx) void cryptohash_sha3_init(struct sha3_ctx *ctx, uint32_t hashlen); void cryptohash_sha3_update(struct sha3_ctx *ctx, uint8_t *data, uint32_t len); void cryptohash_sha3_finalize(struct sha3_ctx *ctx, uint8_t *out); #endif cryptohash-0.11.9/cbits/sha512.c0000644000000000000000000002043612675272160014444 0ustar0000000000000000/* * Copyright (C) 2006-2009 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "bitfn.h" #include "sha512.h" void cryptohash_sha384_init(struct sha512_ctx *ctx) { memset(ctx, 0, sizeof(*ctx)); ctx->h[0] = 0xcbbb9d5dc1059ed8ULL; ctx->h[1] = 0x629a292a367cd507ULL; ctx->h[2] = 0x9159015a3070dd17ULL; ctx->h[3] = 0x152fecd8f70e5939ULL; ctx->h[4] = 0x67332667ffc00b31ULL; ctx->h[5] = 0x8eb44a8768581511ULL; ctx->h[6] = 0xdb0c2e0d64f98fa7ULL; ctx->h[7] = 0x47b5481dbefa4fa4ULL; } void cryptohash_sha512_init(struct sha512_ctx *ctx) { memset(ctx, 0, sizeof(*ctx)); ctx->h[0] = 0x6a09e667f3bcc908ULL; ctx->h[1] = 0xbb67ae8584caa73bULL; ctx->h[2] = 0x3c6ef372fe94f82bULL; ctx->h[3] = 0xa54ff53a5f1d36f1ULL; ctx->h[4] = 0x510e527fade682d1ULL; ctx->h[5] = 0x9b05688c2b3e6c1fULL; ctx->h[6] = 0x1f83d9abfb41bd6bULL; ctx->h[7] = 0x5be0cd19137e2179ULL; } /* 232 times the cube root of the first 64 primes 2..311 */ static const uint64_t k[] = { 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL, }; #define e0(x) (ror64(x, 28) ^ ror64(x, 34) ^ ror64(x, 39)) #define e1(x) (ror64(x, 14) ^ ror64(x, 18) ^ ror64(x, 41)) #define s0(x) (ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7)) #define s1(x) (ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6)) static void sha512_do_chunk(struct sha512_ctx *ctx, uint64_t *buf) { uint64_t a, b, c, d, e, f, g, h, t1, t2; int i; uint64_t w[80]; cpu_to_be64_array(w, buf, 16); for (i = 16; i < 80; i++) w[i] = s1(w[i - 2]) + w[i - 7] + s0(w[i - 15]) + w[i - 16]; a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3]; e = ctx->h[4]; f = ctx->h[5]; g = ctx->h[6]; h = ctx->h[7]; #define R(a, b, c, d, e, f, g, h, k, w) \ t1 = h + e1(e) + (g ^ (e & (f ^ g))) + k + w; \ t2 = e0(a) + ((a & b) | (c & (a | b))); \ d += t1; \ h = t1 + t2 for (i = 0; i < 80; i += 8) { R(a, b, c, d, e, f, g, h, k[i + 0], w[i + 0]); R(h, a, b, c, d, e, f, g, k[i + 1], w[i + 1]); R(g, h, a, b, c, d, e, f, k[i + 2], w[i + 2]); R(f, g, h, a, b, c, d, e, k[i + 3], w[i + 3]); R(e, f, g, h, a, b, c, d, k[i + 4], w[i + 4]); R(d, e, f, g, h, a, b, c, k[i + 5], w[i + 5]); R(c, d, e, f, g, h, a, b, k[i + 6], w[i + 6]); R(b, c, d, e, f, g, h, a, k[i + 7], w[i + 7]); } #undef R ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d; ctx->h[4] += e; ctx->h[5] += f; ctx->h[6] += g; ctx->h[7] += h; } void cryptohash_sha384_update(struct sha384_ctx *ctx, uint8_t *data, uint32_t len) { return cryptohash_sha512_update(ctx, data, len); } void cryptohash_sha512_update(struct sha512_ctx *ctx, uint8_t *data, uint32_t len) { unsigned int index, to_fill; /* check for partial buffer */ index = (unsigned int) (ctx->sz[0] & 0x7f); to_fill = 128 - index; ctx->sz[0] += len; if (ctx->sz[0] < len) ctx->sz[1]++; /* process partial buffer if there's enough data to make a block */ if (index && len >= to_fill) { memcpy(ctx->buf + index, data, to_fill); sha512_do_chunk(ctx, (uint64_t *) ctx->buf); len -= to_fill; data += to_fill; index = 0; } /* process as much 128-block as possible */ for (; len >= 128; len -= 128, data += 128) sha512_do_chunk(ctx, (uint64_t *) data); /* append data into buf */ if (len) memcpy(ctx->buf + index, data, len); } void cryptohash_sha384_finalize(struct sha384_ctx *ctx, uint8_t *out) { uint8_t intermediate[SHA512_DIGEST_SIZE]; cryptohash_sha512_finalize(ctx, intermediate); memcpy(out, intermediate, SHA384_DIGEST_SIZE); } void cryptohash_sha512_finalize(struct sha512_ctx *ctx, uint8_t *out) { static uint8_t padding[128] = { 0x80, }; uint32_t i, index, padlen; uint64_t bits[2]; uint64_t *p = (uint64_t *) out; /* cpu -> big endian */ bits[0] = cpu_to_be64((ctx->sz[1] << 3 | ctx->sz[0] >> 61)); bits[1] = cpu_to_be64((ctx->sz[0] << 3)); /* pad out to 56 */ index = (unsigned int) (ctx->sz[0] & 0x7f); padlen = (index < 112) ? (112 - index) : ((128 + 112) - index); cryptohash_sha512_update(ctx, padding, padlen); /* append length */ cryptohash_sha512_update(ctx, (uint8_t *) bits, sizeof(bits)); /* store to digest */ for (i = 0; i < 8; i++) p[i] = cpu_to_be64(ctx->h[i]); } #include void cryptohash_sha512_init_t(struct sha512_ctx *ctx, int t) { memset(ctx, 0, sizeof(*ctx)); if (t >= 512) return; switch (t) { case 224: ctx->h[0] = 0x8c3d37c819544da2ULL; ctx->h[1] = 0x73e1996689dcd4d6ULL; ctx->h[2] = 0x1dfab7ae32ff9c82ULL; ctx->h[3] = 0x679dd514582f9fcfULL; ctx->h[4] = 0x0f6d2b697bd44da8ULL; ctx->h[5] = 0x77e36f7304c48942ULL; ctx->h[6] = 0x3f9d85a86a1d36c8ULL; ctx->h[7] = 0x1112e6ad91d692a1ULL; break; case 256: ctx->h[0] = 0x22312194fc2bf72cULL; ctx->h[1] = 0x9f555fa3c84c64c2ULL; ctx->h[2] = 0x2393b86b6f53b151ULL; ctx->h[3] = 0x963877195940eabdULL; ctx->h[4] = 0x96283ee2a88effe3ULL; ctx->h[5] = 0xbe5e1e2553863992ULL; ctx->h[6] = 0x2b0199fc2c85b8aaULL; ctx->h[7] = 0x0eb72ddc81c52ca2ULL; break; default: { char buf[8+4]; uint8_t out[64]; int i; cryptohash_sha512_init(ctx); for (i = 0; i < 8; i++) ctx->h[i] ^= 0xa5a5a5a5a5a5a5a5ULL; i = sprintf(buf, "SHA-512/%d", t); cryptohash_sha512_update(ctx, (uint8_t *) buf, i); cryptohash_sha512_finalize(ctx, out); /* re-init the context, otherwise len is changed */ memset(ctx, 0, sizeof(*ctx)); for (i = 0; i < 8; i++) ctx->h[i] = cpu_to_be64(((uint64_t *) out)[i]); } } } cryptohash-0.11.9/cbits/sha512.h0000644000000000000000000000415612675272160014452 0ustar0000000000000000/* * Copyright (C) 2006-2009 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef CRYPTOHASH_SHA512_H #define CRYPTOHASH_SHA512_H #include struct sha512_ctx { uint64_t sz[2]; uint8_t buf[128]; uint64_t h[8]; }; #define sha384_ctx sha512_ctx #define SHA384_DIGEST_SIZE 48 #define SHA384_CTX_SIZE sizeof(struct sha384_ctx) #define SHA512_DIGEST_SIZE 64 #define SHA512_CTX_SIZE sizeof(struct sha512_ctx) void cryptohash_sha384_init(struct sha384_ctx *ctx); void cryptohash_sha384_update(struct sha384_ctx *ctx, uint8_t *data, uint32_t len); void cryptohash_sha384_finalize(struct sha384_ctx *ctx, uint8_t *out); void cryptohash_sha512_init(struct sha512_ctx *ctx); void cryptohash_sha512_update(struct sha512_ctx *ctx, uint8_t *data, uint32_t len); void cryptohash_sha512_finalize(struct sha512_ctx *ctx, uint8_t *out); void cryptohash_sha512_init_t(struct sha512_ctx *ctx, int t); #endif cryptohash-0.11.9/cbits/skein.h0000644000000000000000000000353212675272160014555 0ustar0000000000000000/* * Copyright (C) 2006-2010 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef CRYPTOHASH_SKEIN_H #define CRYPTOHASH_SKEIN_H #define SKEIN_VERSION 1ULL #define SKEIN_IDSTRING 0x33414853ULL /* t0 0-63 || t1 64-127 0-95 96-111 112-118 119 120-125 126 127 Position reserved TreeLevel BitPad Type First Final */ #define FLAG_FIRST (1ULL << 62) #define FLAG_FINAL (1ULL << 63) #define FLAG_TYPE(x) (((uint64_t) ((x) & 0x3f)) << 56) #define TYPE_KEY 0x00 #define TYPE_CFG 0x04 #define TYPE_MSG 0x30 #define TYPE_OUT 0x3f #define SET_TYPE(ctx, ty) ctx->t0 = 0; ctx->t1 = (ty) #endif cryptohash-0.11.9/cbits/skein256.c0000644000000000000000000001322112675272160015001 0ustar0000000000000000/* * Copyright (C) 2006-2010 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "skein.h" #include "skein256.h" #include "bitfn.h" static const uint8_t K256_0[2] = { 14, 16, }; static const uint8_t K256_1[2] = { 52, 57, }; static const uint8_t K256_2[2] = { 23, 40, }; static const uint8_t K256_3[2] = { 5, 37, }; static const uint8_t K256_4[2] = { 25, 33, }; static const uint8_t K256_5[2] = { 46, 12, }; static const uint8_t K256_6[2] = { 58, 22, }; static const uint8_t K256_7[2] = { 32, 32, }; static inline void skein256_do_chunk(struct skein256_ctx *ctx, uint64_t *buf, uint32_t len) { uint64_t x[4]; uint64_t ts[3]; uint64_t ks[4+1]; ks[4] = 0x1bd11bdaa9fc1a22ULL; ks[0] = ctx->h[0]; ks[4] ^= ctx->h[0]; ks[1] = ctx->h[1]; ks[4] ^= ctx->h[1]; ks[2] = ctx->h[2]; ks[4] ^= ctx->h[2]; ks[3] = ctx->h[3]; ks[4] ^= ctx->h[3]; ts[0] = ctx->t0; ts[1] = ctx->t1; ts[0] += len; ts[2] = ts[0] ^ ts[1]; #define INJECTKEY(r) \ x[0] += ks[((r)+0) % (4+1)]; \ x[1] += ks[((r)+1) % (4+1)] + ts[((r)+0) % 3]; \ x[2] += ks[((r)+2) % (4+1)] + ts[((r)+1) % 3]; \ x[3] += ks[((r)+3) % (4+1)] + (r) #define ROUND(a,b,c,d,k) \ x[a] += x[b]; x[b] = rol64(x[b],k[0]); x[b] ^= x[a]; \ x[c] += x[d]; x[d] = rol64(x[d],k[1]); x[d] ^= x[c]; #define PASS(i) \ ROUND(0,1,2,3,K256_0); \ ROUND(0,3,2,1,K256_1); \ ROUND(0,1,2,3,K256_2); \ ROUND(0,3,2,1,K256_3); \ INJECTKEY((i*2) + 1); \ ROUND(0,1,2,3,K256_4); \ ROUND(0,3,2,1,K256_5); \ ROUND(0,1,2,3,K256_6); \ ROUND(0,3,2,1,K256_7); \ INJECTKEY((i*2) + 2) x[0] = le64_to_cpu(buf[0]) + ks[0]; x[1] = le64_to_cpu(buf[1]) + ks[1] + ts[0]; x[2] = le64_to_cpu(buf[2]) + ks[2] + ts[1]; x[3] = le64_to_cpu(buf[3]) + ks[3]; /* 9 pass of 8 rounds = 72 rounds */ PASS(0); PASS(1); PASS(2); PASS(3); PASS(4); PASS(5); PASS(6); PASS(7); PASS(8); ts[1] &= ~FLAG_FIRST; ctx->t0 = ts[0]; ctx->t1 = ts[1]; ctx->h[0] = x[0] ^ cpu_to_le64(buf[0]); ctx->h[1] = x[1] ^ cpu_to_le64(buf[1]); ctx->h[2] = x[2] ^ cpu_to_le64(buf[2]); ctx->h[3] = x[3] ^ cpu_to_le64(buf[3]); } void cryptohash_skein256_init(struct skein256_ctx *ctx, uint32_t hashlen) { uint64_t buf[4]; memset(ctx, 0, sizeof(*ctx)); ctx->hashlen = (hashlen + 7) >> 3; SET_TYPE(ctx, FLAG_FIRST | FLAG_FINAL | FLAG_TYPE(TYPE_CFG)); memset(buf, '\0', sizeof(buf)); buf[0] = cpu_to_le64((SKEIN_VERSION << 32) | SKEIN_IDSTRING); buf[1] = cpu_to_le64(hashlen); buf[2] = 0; /* tree info, not implemented */ skein256_do_chunk(ctx, buf, 4*8); SET_TYPE(ctx, FLAG_FIRST | FLAG_TYPE(TYPE_MSG)); } void cryptohash_skein256_update(struct skein256_ctx *ctx, uint8_t *data, uint32_t len) { uint32_t to_fill; if (!len) return; to_fill = 32 - ctx->bufindex; if (ctx->bufindex == 32) { skein256_do_chunk(ctx, (uint64_t *) ctx->buf, 32); ctx->bufindex = 0; } /* process partial buffer if there's enough data to make a block * and there's without doubt further blocks */ if (ctx->bufindex && len > to_fill) { memcpy(ctx->buf + ctx->bufindex, data, to_fill); skein256_do_chunk(ctx, (uint64_t *) ctx->buf, 32); len -= to_fill; data += to_fill; ctx->bufindex = 0; } /* process as much 32-block as possible except the last one in case we finalize */ for (; len > 32; len -= 32, data += 32) skein256_do_chunk(ctx, (uint64_t *) data, 32); /* append data into buf */ if (len) { memcpy(ctx->buf + ctx->bufindex, data, len); ctx->bufindex += len; } } void cryptohash_skein256_finalize(struct skein256_ctx *ctx, uint8_t *out) { uint32_t outsize; uint64_t *p = (uint64_t *) out; uint64_t x[4]; int i, j, n; ctx->t1 |= FLAG_FINAL; /* if buf is not complete pad with 0 bytes */ if (ctx->bufindex < 32) memset(ctx->buf + ctx->bufindex, '\0', 32 - ctx->bufindex); skein256_do_chunk(ctx, (uint64_t *) ctx->buf, ctx->bufindex); memset(ctx->buf, '\0', 32); /* make sure we have a 8 bit rounded value */ outsize = ctx->hashlen; /* backup h[0--4] */ for (j = 0; j < 4; j++) x[j] = ctx->h[j]; /* threefish in counter mode, 0 for 1st 64 bytes, 1 for 2nd 64 bytes, .. */ for (i = 0; i*32 < outsize; i++) { uint64_t w[4]; *((uint64_t *) ctx->buf) = cpu_to_le64(i); SET_TYPE(ctx, FLAG_FIRST | FLAG_FINAL | FLAG_TYPE(TYPE_OUT)); skein256_do_chunk(ctx, (uint64_t *) ctx->buf, sizeof(uint64_t)); n = outsize - i * 32; if (n >= 32) n = 32; cpu_to_le64_array(w, ctx->h, 4); memcpy(out + i*32, w, n); /* restore h[0--4] */ for (j = 0; j < 4; j++) ctx->h[j] = x[j]; } } cryptohash-0.11.9/cbits/skein256.h0000644000000000000000000000345012675272160015011 0ustar0000000000000000/* * Copyright (C) 2006-2010 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef CRYPTOHASH_SKEIN256_H #define CRYPTOHASH_SKEIN256_H #include struct skein256_ctx { uint32_t hashlen; uint32_t bufindex; uint8_t buf[32]; uint64_t h[4]; uint64_t t0; uint64_t t1; }; #define SKEIN256_CTX_SIZE sizeof(struct skein256_ctx) void cryptohash_skein256_init(struct skein256_ctx *ctx, uint32_t hashlen); void cryptohash_skein256_update(struct skein256_ctx *ctx, uint8_t *data, uint32_t len); void cryptohash_skein256_finalize(struct skein256_ctx *ctx, uint8_t *out); #endif cryptohash-0.11.9/cbits/skein512.c0000644000000000000000000001510512675272160014777 0ustar0000000000000000/* * Copyright (C) 2006-2010 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "skein.h" #include "skein512.h" #include "bitfn.h" static const uint8_t K512_0[4] = { 46, 36, 19, 37, }; static const uint8_t K512_1[4] = { 33, 27, 14, 42, }; static const uint8_t K512_2[4] = { 17, 49, 36, 39, }; static const uint8_t K512_3[4] = { 44, 9, 54, 56, }; static const uint8_t K512_4[4] = { 39, 30, 34, 24, }; static const uint8_t K512_5[4] = { 13, 50, 10, 17, }; static const uint8_t K512_6[4] = { 25, 29, 39, 43, }; static const uint8_t K512_7[4] = { 8, 35, 56, 22, }; static inline void skein512_do_chunk(struct skein512_ctx *ctx, uint64_t *buf, uint32_t len) { uint64_t x[8]; uint64_t ts[3]; uint64_t ks[8+1]; ks[8] = 0x1bd11bdaa9fc1a22ULL; ks[0] = ctx->h[0]; ks[8] ^= ctx->h[0]; ks[1] = ctx->h[1]; ks[8] ^= ctx->h[1]; ks[2] = ctx->h[2]; ks[8] ^= ctx->h[2]; ks[3] = ctx->h[3]; ks[8] ^= ctx->h[3]; ks[4] = ctx->h[4]; ks[8] ^= ctx->h[4]; ks[5] = ctx->h[5]; ks[8] ^= ctx->h[5]; ks[6] = ctx->h[6]; ks[8] ^= ctx->h[6]; ks[7] = ctx->h[7]; ks[8] ^= ctx->h[7]; ts[0] = ctx->t0; ts[1] = ctx->t1; ts[0] += len; ts[2] = ts[0] ^ ts[1]; #define INJECTKEY(r) \ x[0] += ks[((r)+0) % (8+1)]; \ x[1] += ks[((r)+1) % (8+1)]; \ x[2] += ks[((r)+2) % (8+1)]; \ x[3] += ks[((r)+3) % (8+1)]; \ x[4] += ks[((r)+4) % (8+1)]; \ x[5] += ks[((r)+5) % (8+1)] + ts[((r)+0) % 3]; \ x[6] += ks[((r)+6) % (8+1)] + ts[((r)+1) % 3]; \ x[7] += ks[((r)+7) % (8+1)] + (r) #define ROUND(a,b,c,d,e,f,g,h,k) \ x[a] += x[b]; x[b] = rol64(x[b],k[0]); x[b] ^= x[a]; \ x[c] += x[d]; x[d] = rol64(x[d],k[1]); x[d] ^= x[c]; \ x[e] += x[f]; x[f] = rol64(x[f],k[2]); x[f] ^= x[e]; \ x[g] += x[h]; x[h] = rol64(x[h],k[3]); x[h] ^= x[g]; #define PASS(i) \ ROUND(0,1,2,3,4,5,6,7,K512_0); \ ROUND(2,1,4,7,6,5,0,3,K512_1); \ ROUND(4,1,6,3,0,5,2,7,K512_2); \ ROUND(6,1,0,7,2,5,4,3,K512_3); \ INJECTKEY((i*2) + 1); \ ROUND(0,1,2,3,4,5,6,7,K512_4); \ ROUND(2,1,4,7,6,5,0,3,K512_5); \ ROUND(4,1,6,3,0,5,2,7,K512_6); \ ROUND(6,1,0,7,2,5,4,3,K512_7); \ INJECTKEY((i*2) + 2) x[0] = le64_to_cpu(buf[0]) + ks[0]; x[1] = le64_to_cpu(buf[1]) + ks[1]; x[2] = le64_to_cpu(buf[2]) + ks[2]; x[3] = le64_to_cpu(buf[3]) + ks[3]; x[4] = le64_to_cpu(buf[4]) + ks[4]; x[5] = le64_to_cpu(buf[5]) + ks[5] + ts[0]; x[6] = le64_to_cpu(buf[6]) + ks[6] + ts[1]; x[7] = le64_to_cpu(buf[7]) + ks[7]; /* 9 pass of 8 rounds = 72 rounds */ PASS(0); PASS(1); PASS(2); PASS(3); PASS(4); PASS(5); PASS(6); PASS(7); PASS(8); ts[1] &= ~FLAG_FIRST; ctx->t0 = ts[0]; ctx->t1 = ts[1]; ctx->h[0] = x[0] ^ cpu_to_le64(buf[0]); ctx->h[1] = x[1] ^ cpu_to_le64(buf[1]); ctx->h[2] = x[2] ^ cpu_to_le64(buf[2]); ctx->h[3] = x[3] ^ cpu_to_le64(buf[3]); ctx->h[4] = x[4] ^ cpu_to_le64(buf[4]); ctx->h[5] = x[5] ^ cpu_to_le64(buf[5]); ctx->h[6] = x[6] ^ cpu_to_le64(buf[6]); ctx->h[7] = x[7] ^ cpu_to_le64(buf[7]); } void cryptohash_skein512_init(struct skein512_ctx *ctx, uint32_t hashlen) { uint64_t buf[8]; memset(ctx, 0, sizeof(*ctx)); ctx->hashlen = (hashlen + 7) >> 3; SET_TYPE(ctx, FLAG_FIRST | FLAG_FINAL | FLAG_TYPE(TYPE_CFG)); memset(buf, '\0', sizeof(buf)); buf[0] = cpu_to_le64((SKEIN_VERSION << 32) | SKEIN_IDSTRING); buf[1] = cpu_to_le64(hashlen); buf[2] = 0; /* tree info, not implemented */ skein512_do_chunk(ctx, buf, 4*8); SET_TYPE(ctx, FLAG_FIRST | FLAG_TYPE(TYPE_MSG)); } void cryptohash_skein512_update(struct skein512_ctx *ctx, uint8_t *data, uint32_t len) { uint32_t to_fill; if (!len) return; to_fill = 64 - ctx->bufindex; if (ctx->bufindex == 64) { skein512_do_chunk(ctx, (uint64_t *) ctx->buf, 64); ctx->bufindex = 0; } /* process partial buffer if there's enough data to make a block * and there's without doubt further blocks */ if (ctx->bufindex && len > to_fill) { memcpy(ctx->buf + ctx->bufindex, data, to_fill); skein512_do_chunk(ctx, (uint64_t *) ctx->buf, 64); len -= to_fill; data += to_fill; ctx->bufindex = 0; } /* process as much 64-block as possible except the last one in case we finalize */ for (; len > 64; len -= 64, data += 64) skein512_do_chunk(ctx, (uint64_t *) data, 64); /* append data into buf */ if (len) { memcpy(ctx->buf + ctx->bufindex, data, len); ctx->bufindex += len; } } void cryptohash_skein512_finalize(struct skein512_ctx *ctx, uint8_t *out) { uint32_t outsize; uint64_t *p = (uint64_t *) out; uint64_t x[8]; int i, j, n; ctx->t1 |= FLAG_FINAL; /* if buf is not complete pad with 0 bytes */ if (ctx->bufindex < 64) memset(ctx->buf + ctx->bufindex, '\0', 64 - ctx->bufindex); skein512_do_chunk(ctx, (uint64_t *) ctx->buf, ctx->bufindex); memset(ctx->buf, '\0', 64); /* make sure we have a 8 bit rounded value */ outsize = ctx->hashlen; /* backup h[0--7] */ for (j = 0; j < 8; j++) x[j] = ctx->h[j]; /* threefish in counter mode, 0 for 1st 64 bytes, 1 for 2nd 64 bytes, .. */ for (i = 0; i*64 < outsize; i++) { uint64_t w[8]; *((uint64_t *) ctx->buf) = cpu_to_le64(i); SET_TYPE(ctx, FLAG_FIRST | FLAG_FINAL | FLAG_TYPE(TYPE_OUT)); skein512_do_chunk(ctx, (uint64_t *) ctx->buf, sizeof(uint64_t)); n = outsize - i * 64; if (n >= 64) n = 64; cpu_to_le64_array(w, ctx->h, 8); memcpy(out + i*64, w, n); /* restore h[0--7] */ for (j = 0; j < 8; j++) ctx->h[j] = x[j]; } } cryptohash-0.11.9/cbits/skein512.h0000644000000000000000000000351712675272160015010 0ustar0000000000000000/* * Copyright (C) 2006-2010 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef CRYPTOHASH_SKEIN512_H #define CRYPTOHASH_SKEIN512_H #include struct skein512_ctx { uint32_t hashlen; /* in bytes, typically 384/8, 512/8 */ uint32_t bufindex; uint8_t buf[64]; uint64_t h[8]; uint64_t t0; uint64_t t1; }; #define SKEIN512_CTX_SIZE sizeof(struct skein512_ctx) void cryptohash_skein512_init(struct skein512_ctx *ctx, uint32_t hashlen); void cryptohash_skein512_update(struct skein512_ctx *ctx, uint8_t *data, uint32_t len); void cryptohash_skein512_finalize(struct skein512_ctx *ctx, uint8_t *out); #endif cryptohash-0.11.9/Crypto/0000755000000000000000000000000012675272160013444 5ustar0000000000000000cryptohash-0.11.9/Crypto/Hash.hs0000644000000000000000000001661512675272160014674 0ustar0000000000000000{-# LANGUAGE CPP #-} {-# LANGUAGE PackageImports #-} -- | -- Module : Crypto.Hash -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- Generalized cryptographic hash interface, that you can use with cryptographic hash -- algorithm that belong to the HashAlgorithm type class. -- -- > import Crypto.Hash -- > -- > sha1 :: ByteString -> Digest SHA1 -- > sha1 = hash -- > -- > hexSha3_512 :: ByteString -> String -- > hexSha3_512 bs = show (hash bs :: Digest SHA3_512) -- module Crypto.Hash ( -- * Types HashAlgorithm(..) , HashFunctionBS , HashFunctionLBS , Context , Digest -- * Functions , digestToByteString , digestToHexByteString , hash , hashlazy , hashUpdate , hashInitAlg -- * hash algorithms , H.MD2(..) , H.MD4(..) , H.MD5(..) , H.SHA1(..) , H.SHA224(..) , H.SHA256(..) , H.SHA384(..) , H.SHA512(..) , H.RIPEMD160(..) , H.Tiger(..) , H.SHA3_224(..) , H.SHA3_256(..) , H.SHA3_384(..) , H.SHA3_512(..) , H.Skein256_224(..) , H.Skein256_256(..) , H.Skein512_224(..) , H.Skein512_256(..) , H.Skein512_384(..) , H.Skein512_512(..) , H.Whirlpool(..) -- * MAC algorithms , HMAC(..) , hmac , hmacAlg ) where import Crypto.Hash.Types import Data.ByteString (ByteString) import Data.Byteable import Data.Bits (xor) import qualified Data.ByteString as B import qualified Data.ByteArray.Encoding as B import qualified Data.ByteString.Lazy as L import qualified "cryptonite" Crypto.Hash as H -- | Alias to a single pass hash function that operate on a strict bytestring type HashFunctionBS a = ByteString -> Digest a -- | Alias to a single pass hash function that operate on a lazy bytestring type HashFunctionLBS a = L.ByteString -> Digest a -- | run hashUpdates on one single bytestring and return the updated context. hashUpdate :: HashAlgorithm a => Context a -> ByteString -> Context a hashUpdate ctx b = hashUpdates ctx [b] -- | Hash a strict bytestring into a digest. hash :: HashAlgorithm a => ByteString -> Digest a hash bs = hashFinalize $ hashUpdate hashInit bs -- | Hash a lazy bytestring into a digest. hashlazy :: HashAlgorithm a => L.ByteString -> Digest a hashlazy lbs = hashFinalize $ hashUpdates hashInit (L.toChunks lbs) -- | Return the hexadecimal (base16) bytestring of the digest digestToHexByteString :: Digest a -> ByteString digestToHexByteString = B.convertToBase B.Base16 . toBytes -- | Class representing hashing algorithms. -- -- The hash algorithm is built over 3 primitives: -- -- * init : create a new hashing context -- -- * updates : update the hashing context with some strict bytestrings -- and return the new context -- -- * finalize : finalize the context into a digest -- class HashAlgorithm a where -- | Block size in bytes the hash algorithm operates on hashBlockSize :: Context a -> Int -- | Initialize a new context for this hash algorithm hashInit :: Context a -- | Update the context with a list of strict bytestring, -- and return a new context with the updates. hashUpdates :: Context a -> [ByteString] -> Context a -- | Finalize a context and return a digest. hashFinalize :: Context a -> Digest a -- | Try to convert a binary digest bytestring to a digest. digestFromByteString :: ByteString -> Maybe (Digest a) #define DEFINE_INSTANCE(NAME, MODULENAME, BLOCKSIZE) \ instance HashAlgorithm H.NAME where \ { hashInit = Context $ H.hashInit \ ; hashBlockSize ~(Context _) = BLOCKSIZE \ ; hashUpdates (Context c) bs = Context $ H.hashUpdates c bs \ ; hashFinalize (Context c) = Digest $ H.hashFinalize c \ ; digestFromByteString bs = Digest `fmap` H.digestFromByteString bs \ }; #define DEFINE_INSTANCE_LEN(NAME, MODULENAME, LEN, BLOCKSIZE) \ instance HashAlgorithm H.NAME where \ { hashInit = Context $ H.hashInit \ ; hashBlockSize ~(Context _) = BLOCKSIZE \ ; hashUpdates (Context c) bs = Context $ H.hashUpdates c bs \ ; hashFinalize (Context c) = Digest $ H.hashFinalize c \ ; digestFromByteString bs = Digest `fmap` H.digestFromByteString bs \ }; -- | MD2 cryptographic hash DEFINE_INSTANCE(MD2, MD2, 16) -- | MD4 cryptographic hash DEFINE_INSTANCE(MD4, MD4, 64) -- | MD5 cryptographic hash DEFINE_INSTANCE(MD5, MD5, 64) -- | SHA1 cryptographic hash DEFINE_INSTANCE(SHA1, SHA1, 64) -- | SHA224 cryptographic hash DEFINE_INSTANCE(SHA224, SHA224, 64) -- | SHA256 cryptographic hash DEFINE_INSTANCE(SHA256, SHA256, 64) -- | SHA384 cryptographic hash DEFINE_INSTANCE(SHA384, SHA384, 128) -- | SHA512 cryptographic hash DEFINE_INSTANCE(SHA512, SHA512, 128) -- | RIPEMD160 cryptographic hash DEFINE_INSTANCE(RIPEMD160, RIPEMD160, 64) -- | Whirlpool cryptographic hash DEFINE_INSTANCE(Whirlpool, Whirlpool, 64) -- | Tiger cryptographic hash DEFINE_INSTANCE(Tiger, Tiger, 64) -- | SHA3 (224 bits version) cryptographic hash DEFINE_INSTANCE_LEN(SHA3_224, SHA3, 224, 144) -- | SHA3 (256 bits version) cryptographic hash DEFINE_INSTANCE_LEN(SHA3_256, SHA3, 256, 136) -- | SHA3 (384 bits version) cryptographic hash DEFINE_INSTANCE_LEN(SHA3_384, SHA3, 384, 104) -- | SHA3 (512 bits version) cryptographic hash DEFINE_INSTANCE_LEN(SHA3_512, SHA3, 512, 72) -- | Skein256 (224 bits version) cryptographic hash DEFINE_INSTANCE_LEN(Skein256_224, Skein256, 224, 32) -- | Skein256 (256 bits version) cryptographic hash DEFINE_INSTANCE_LEN(Skein256_256, Skein256, 256, 32) -- | Skein512 (224 bits version) cryptographic hash DEFINE_INSTANCE_LEN(Skein512_224, Skein512, 224, 64) -- | Skein512 (256 bits version) cryptographic hash DEFINE_INSTANCE_LEN(Skein512_256, Skein512, 256, 64) -- | Skein512 (384 bits version) cryptographic hash DEFINE_INSTANCE_LEN(Skein512_384, Skein512, 384, 64) -- | Skein512 (512 bits version) cryptographic hash DEFINE_INSTANCE_LEN(Skein512_512, Skein512, 512, 64) -- | Initialize a new context for a specified hash algorithm hashInitAlg :: HashAlgorithm alg => alg -> Context alg hashInitAlg _ = hashInit -- | Represent an HMAC that is a phantom type with the hash used to produce the mac. -- -- The Eq instance is constant time. newtype HMAC a = HMAC { hmacGetDigest :: Digest a } instance Byteable (HMAC a) where toBytes (HMAC b) = toBytes b instance Eq (HMAC a) where (HMAC b1) == (HMAC b2) = constEqBytes (toBytes b1) (toBytes b2) -- | compute a MAC using the supplied hashing function hmac :: HashAlgorithm a => ByteString -- ^ Secret key -> ByteString -- ^ Message to MAC -> HMAC a hmac secret msg = doHMAC hashInit where doHMAC :: HashAlgorithm a => Context a -> HMAC a doHMAC ctxInit = HMAC $ hashF $ B.append opad (toBytes $ hashF $ B.append ipad msg) where opad = B.map (xor 0x5c) k' ipad = B.map (xor 0x36) k' k' = B.append kt pad kt = if B.length secret > fromIntegral blockSize then toBytes (hashF secret) else secret pad = B.replicate (fromIntegral blockSize - B.length kt) 0 hashF = hashFinalize . hashUpdate ctxInit blockSize = hashBlockSize ctxInit -- | compute a HMAC using a specified algorithm hmacAlg :: HashAlgorithm a => a -- ^ the hash algorithm the actual value is unused. -> ByteString -- ^ Secret key -> ByteString -- ^ Message to MAC -> HMAC a hmacAlg _ secret msg = hmac secret msg cryptohash-0.11.9/Crypto/MAC.hs0000644000000000000000000000455112675272160014405 0ustar0000000000000000-- | -- Module : Crypto.MAC -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- Crypto hash generic MAC (Message Authentification Code) module -- {-# LANGUAGE BangPatterns #-} module Crypto.MAC ( -- * MAC algorithms HMAC(..) , hmac , hmacAlg -- ** Incremental MAC algorithms , HMACContext , hmacInit , hmacInitAlg , hmacUpdate , hmacFinalize ) where import Crypto.Hash import Data.ByteString (ByteString) import Data.Byteable import Data.Bits (xor) import qualified Data.ByteString as B -- -------------------------------------------------------------------------- -- -- Incremental HMAC -- | Represent an ongoing HMAC state, that can be appended with 'hmacUpdate' -- and finalize to an HMAC with 'hmacFinalize' data HMACContext hashalg = HMACContext !(Context hashalg) !(Context hashalg) -- | Initialize a new incremental HMAC context hmacInit :: HashAlgorithm a => ByteString -- ^ Secret key -> HMACContext a hmacInit secret = HMACContext octx ictx where ctxInit = hashInit ictx = hashUpdates ctxInit [ipad] octx = hashUpdates ctxInit [opad] ipad = B.map (xor 0x36) k' opad = B.map (xor 0x5c) k' k' = B.append kt pad kt = if B.length secret > fromIntegral blockSize then toBytes (hashF secret) else secret pad = B.replicate (fromIntegral blockSize - B.length kt) 0 hashF = hashFinalize . hashUpdate ctxInit blockSize = hashBlockSize ctxInit -- | Initialize a new incremental HMAC context with a given hash algorithm. hmacInitAlg :: HashAlgorithm a => a -- ^ the hash algorithm the actual value is unused. -> ByteString -- ^ Secret key -> HMACContext a hmacInitAlg _ secret = hmacInit secret -- | Incrementally update a HMAC context hmacUpdate :: HashAlgorithm a => HMACContext a -> ByteString -- ^ Message to Mac -> HMACContext a hmacUpdate (HMACContext octx ictx) msg = HMACContext octx (hashUpdate ictx msg) -- | Finalize a HMAC context and return the HMAC. hmacFinalize :: HashAlgorithm a => HMACContext a -> HMAC a hmacFinalize (HMACContext octx ictx) = HMAC $ hashFinalize $ hashUpdates octx [toBytes $ hashFinalize ictx] cryptohash-0.11.9/Crypto/Hash/0000755000000000000000000000000012675272160014327 5ustar0000000000000000cryptohash-0.11.9/Crypto/Hash/Internal.hs0000644000000000000000000000206012675272160016435 0ustar0000000000000000{-# LANGUAGE CPP #-} {-# LANGUAGE PackageImports #-} -- | -- Module : Crypto.Hash.Internal -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown module Crypto.Hash.Internal ( unsafeDoIO , digestToByteString , digestToByteStringWitness ) where import System.IO.Unsafe import Data.ByteArray (convert) import "cryptonite" Crypto.Hash import Data.ByteString (ByteString) -- | perform io for hashes that do allocation and ffi. -- unsafeDupablePerformIO is used when possible as the -- computation is pure and the output is directly linked -- to the input. we also do not modify anything after it has -- been returned to the user. unsafeDoIO :: IO a -> a #if __GLASGOW_HASKELL__ > 704 unsafeDoIO = unsafeDupablePerformIO #else unsafeDoIO = unsafePerformIO #endif digestToByteString :: HashAlgorithm h => Digest h -> ByteString digestToByteString = convert digestToByteStringWitness :: HashAlgorithm h => h -> Digest h -> ByteString digestToByteStringWitness _ = convert cryptohash-0.11.9/Crypto/Hash/MD2.hs0000644000000000000000000000317212675272160015250 0ustar0000000000000000{-# LANGUAGE PackageImports #-} -- | -- Module : Crypto.Hash.MD2 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- A module containing MD2 bindings -- module Crypto.Hash.MD2 ( Ctx(..) -- * Incremental hashing Functions , init -- :: Ctx , update -- :: Ctx -> ByteString -> Ctx , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing , hash -- :: ByteString -> ByteString , hashlazy -- :: ByteString -> ByteString ) where import Prelude hiding (init) import qualified Data.ByteString.Lazy as L import Data.ByteString (ByteString) import Crypto.Hash.Internal (digestToByteString, digestToByteStringWitness) import qualified "cryptonite" Crypto.Hash as H -- | MD2 Context newtype Ctx = Ctx (H.Context H.MD2) -- | init a context init :: Ctx init = Ctx H.hashInit -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx update (Ctx ctx) d = Ctx $ H.hashUpdate ctx d -- | updates a context with multiples bytestring updates :: Ctx -> [ByteString] -> Ctx updates (Ctx ctx) d = Ctx $ H.hashUpdates ctx d -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString finalize (Ctx ctx) = digestToByteString $ H.hashFinalize ctx -- | hash a strict bytestring into a digest bytestring hash :: ByteString -> ByteString hash d = digestToByteStringWitness H.MD2 $ H.hash d -- | hash a lazy bytestring into a digest bytestring hashlazy :: L.ByteString -> ByteString hashlazy l = digestToByteStringWitness H.MD2 $ H.hashlazy l cryptohash-0.11.9/Crypto/Hash/MD4.hs0000644000000000000000000000317212675272160015252 0ustar0000000000000000{-# LANGUAGE PackageImports #-} -- | -- Module : Crypto.Hash.MD4 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- A module containing MD4 bindings -- module Crypto.Hash.MD4 ( Ctx(..) -- * Incremental hashing Functions , init -- :: Ctx , update -- :: Ctx -> ByteString -> Ctx , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing , hash -- :: ByteString -> ByteString , hashlazy -- :: ByteString -> ByteString ) where import Prelude hiding (init) import qualified Data.ByteString.Lazy as L import Data.ByteString (ByteString) import Crypto.Hash.Internal (digestToByteString, digestToByteStringWitness) import qualified "cryptonite" Crypto.Hash as H -- | MD4 Context newtype Ctx = Ctx (H.Context H.MD4) -- | init a context init :: Ctx init = Ctx H.hashInit -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx update (Ctx ctx) d = Ctx $ H.hashUpdate ctx d -- | updates a context with multiples bytestring updates :: Ctx -> [ByteString] -> Ctx updates (Ctx ctx) d = Ctx $ H.hashUpdates ctx d -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString finalize (Ctx ctx) = digestToByteString $ H.hashFinalize ctx -- | hash a strict bytestring into a digest bytestring hash :: ByteString -> ByteString hash d = digestToByteStringWitness H.MD4 $ H.hash d -- | hash a lazy bytestring into a digest bytestring hashlazy :: L.ByteString -> ByteString hashlazy l = digestToByteStringWitness H.MD4 $ H.hashlazy l cryptohash-0.11.9/Crypto/Hash/MD5.hs0000644000000000000000000000317212675272160015253 0ustar0000000000000000{-# LANGUAGE PackageImports #-} -- | -- Module : Crypto.Hash.MD5 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- A module containing MD5 bindings -- module Crypto.Hash.MD5 ( Ctx(..) -- * Incremental hashing Functions , init -- :: Ctx , update -- :: Ctx -> ByteString -> Ctx , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing , hash -- :: ByteString -> ByteString , hashlazy -- :: ByteString -> ByteString ) where import Prelude hiding (init) import qualified Data.ByteString.Lazy as L import Data.ByteString (ByteString) import Crypto.Hash.Internal (digestToByteString, digestToByteStringWitness) import qualified "cryptonite" Crypto.Hash as H -- | MD5 Context newtype Ctx = Ctx (H.Context H.MD5) -- | init a context init :: Ctx init = Ctx H.hashInit -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx update (Ctx ctx) d = Ctx $ H.hashUpdate ctx d -- | updates a context with multiples bytestring updates :: Ctx -> [ByteString] -> Ctx updates (Ctx ctx) d = Ctx $ H.hashUpdates ctx d -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString finalize (Ctx ctx) = digestToByteString $ H.hashFinalize ctx -- | hash a strict bytestring into a digest bytestring hash :: ByteString -> ByteString hash d = digestToByteStringWitness H.MD5 $ H.hash d -- | hash a lazy bytestring into a digest bytestring hashlazy :: L.ByteString -> ByteString hashlazy l = digestToByteStringWitness H.MD5 $ H.hashlazy l cryptohash-0.11.9/Crypto/Hash/RIPEMD160.hs0000644000000000000000000000324412675272160016075 0ustar0000000000000000{-# LANGUAGE PackageImports #-} -- | -- Module : Crypto.Hash.RIPEMD160 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- A module containing RIPEMD160 bindings -- module Crypto.Hash.RIPEMD160 ( Ctx(..) -- * Incremental hashing Functions , init -- :: Ctx , update -- :: Ctx -> ByteString -> Ctx , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing , hash -- :: ByteString -> ByteString , hashlazy -- :: ByteString -> ByteString ) where import Prelude hiding (init) import qualified Data.ByteString.Lazy as L import Data.ByteString (ByteString) import Crypto.Hash.Internal (digestToByteString, digestToByteStringWitness) import qualified "cryptonite" Crypto.Hash as H -- | RIPEMD160 Context newtype Ctx = Ctx (H.Context H.RIPEMD160) -- | init a context init :: Ctx init = Ctx H.hashInit -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx update (Ctx ctx) d = Ctx $ H.hashUpdate ctx d -- | updates a context with multiples bytestring updates :: Ctx -> [ByteString] -> Ctx updates (Ctx ctx) d = Ctx $ H.hashUpdates ctx d -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString finalize (Ctx ctx) = digestToByteString $ H.hashFinalize ctx -- | hash a strict bytestring into a digest bytestring hash :: ByteString -> ByteString hash d = digestToByteStringWitness H.RIPEMD160 $ H.hash d -- | hash a lazy bytestring into a digest bytestring hashlazy :: L.ByteString -> ByteString hashlazy l = digestToByteStringWitness H.RIPEMD160 $ H.hashlazy l cryptohash-0.11.9/Crypto/Hash/SHA1.hs0000644000000000000000000000320112675272160015353 0ustar0000000000000000{-# LANGUAGE PackageImports #-} -- | -- Module : Crypto.Hash.SHA1 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- A module containing SHA1 bindings -- module Crypto.Hash.SHA1 ( Ctx(..) -- * Incremental hashing Functions , init -- :: Ctx , update -- :: Ctx -> ByteString -> Ctx , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing , hash -- :: ByteString -> ByteString , hashlazy -- :: ByteString -> ByteString ) where import Prelude hiding (init) import qualified Data.ByteString.Lazy as L import Data.ByteString (ByteString) import Crypto.Hash.Internal (digestToByteString, digestToByteStringWitness) import qualified "cryptonite" Crypto.Hash as H -- | SHA1 Context newtype Ctx = Ctx (H.Context H.SHA1) -- | init a context init :: Ctx init = Ctx H.hashInit -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx update (Ctx ctx) d = Ctx $ H.hashUpdate ctx d -- | updates a context with multiples bytestring updates :: Ctx -> [ByteString] -> Ctx updates (Ctx ctx) d = Ctx $ H.hashUpdates ctx d -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString finalize (Ctx ctx) = digestToByteString $ H.hashFinalize ctx -- | hash a strict bytestring into a digest bytestring hash :: ByteString -> ByteString hash d = digestToByteStringWitness H.SHA1 $ H.hash d -- | hash a lazy bytestring into a digest bytestring hashlazy :: L.ByteString -> ByteString hashlazy l = digestToByteStringWitness H.SHA1 $ H.hashlazy l cryptohash-0.11.9/Crypto/Hash/SHA224.hs0000644000000000000000000000321712675272160015531 0ustar0000000000000000{-# LANGUAGE PackageImports #-} -- | -- Module : Crypto.Hash.SHA224 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- A module containing SHA224 bindings -- module Crypto.Hash.SHA224 ( Ctx(..) -- * Incremental hashing Functions , init -- :: Ctx , update -- :: Ctx -> ByteString -> Ctx , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing , hash -- :: ByteString -> ByteString , hashlazy -- :: ByteString -> ByteString ) where import Prelude hiding (init) import qualified Data.ByteString.Lazy as L import Data.ByteString (ByteString) import Crypto.Hash.Internal (digestToByteString, digestToByteStringWitness) import qualified "cryptonite" Crypto.Hash as H -- | SHA224 Context newtype Ctx = Ctx (H.Context H.SHA224) -- | init a context init :: Ctx init = Ctx H.hashInit -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx update (Ctx ctx) d = Ctx $ H.hashUpdate ctx d -- | updates a context with multiples bytestring updates :: Ctx -> [ByteString] -> Ctx updates (Ctx ctx) d = Ctx $ H.hashUpdates ctx d -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString finalize (Ctx ctx) = digestToByteString $ H.hashFinalize ctx -- | hash a strict bytestring into a digest bytestring hash :: ByteString -> ByteString hash d = digestToByteStringWitness H.SHA224 $ H.hash d -- | hash a lazy bytestring into a digest bytestring hashlazy :: L.ByteString -> ByteString hashlazy l = digestToByteStringWitness H.SHA224 $ H.hashlazy l cryptohash-0.11.9/Crypto/Hash/SHA256.hs0000644000000000000000000000321712675272160015536 0ustar0000000000000000{-# LANGUAGE PackageImports #-} -- | -- Module : Crypto.Hash.SHA256 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- A module containing SHA256 bindings -- module Crypto.Hash.SHA256 ( Ctx(..) -- * Incremental hashing Functions , init -- :: Ctx , update -- :: Ctx -> ByteString -> Ctx , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing , hash -- :: ByteString -> ByteString , hashlazy -- :: ByteString -> ByteString ) where import Prelude hiding (init) import qualified Data.ByteString.Lazy as L import Data.ByteString (ByteString) import Crypto.Hash.Internal (digestToByteString, digestToByteStringWitness) import qualified "cryptonite" Crypto.Hash as H -- | SHA256 Context newtype Ctx = Ctx (H.Context H.SHA256) -- | init a context init :: Ctx init = Ctx H.hashInit -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx update (Ctx ctx) d = Ctx $ H.hashUpdate ctx d -- | updates a context with multiples bytestring updates :: Ctx -> [ByteString] -> Ctx updates (Ctx ctx) d = Ctx $ H.hashUpdates ctx d -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString finalize (Ctx ctx) = digestToByteString $ H.hashFinalize ctx -- | hash a strict bytestring into a digest bytestring hash :: ByteString -> ByteString hash d = digestToByteStringWitness H.SHA256 $ H.hash d -- | hash a lazy bytestring into a digest bytestring hashlazy :: L.ByteString -> ByteString hashlazy l = digestToByteStringWitness H.SHA256 $ H.hashlazy l cryptohash-0.11.9/Crypto/Hash/SHA3.hs0000644000000000000000000001213712675272160015365 0ustar0000000000000000{-# LANGUAGE ForeignFunctionInterface #-} -- | -- Module : Crypto.Hash.SHA3 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- A module containing SHA3 bindings -- -- WARNING: this implementation is not SHA3 as standardize, but -- SHA3 as submitted before standardisation. also known at the Keccak. -- -- A matching implementation is available as Keccak in cryptonite -- for people that are using the pre-standard SHA3. -- -- do not use. -- module Crypto.Hash.SHA3 {-# WARNING "this implementation is not SHA3 as standardized, but SHA3 as submitted before standardisation (Keccak)" #-} ( Ctx(..) -- * Incremental hashing Functions , init -- :: Int -> Ctx , update -- :: Ctx -> ByteString -> Ctx , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing , hash -- :: Int -> ByteString -> ByteString , hashlazy -- :: Int -> ByteString -> ByteString ) where import Prelude hiding (init) import Foreign.Ptr import Foreign.ForeignPtr (withForeignPtr) import Foreign.Storable import Foreign.Marshal.Alloc import qualified Data.ByteString.Lazy as L import Data.ByteString (ByteString) import Data.ByteString.Unsafe (unsafeUseAsCStringLen) import Data.ByteString.Internal (create, toForeignPtr) import Data.Word import Crypto.Hash.Internal (unsafeDoIO) -- | SHA3 Context newtype Ctx = Ctx ByteString {-# INLINE sizeCtx #-} sizeCtx :: Int sizeCtx = 360 {- return the number of bytes of output for the digest -} peekHashlen :: Ptr Ctx -> IO Int peekHashlen ptr = peek iptr >>= \v -> return $! fromIntegral v where iptr :: Ptr Word32 iptr = castPtr ptr {-# RULES "hash" forall b i. finalize (update (init i) b) = hash i b #-} {-# RULES "hash.list1" forall b i. finalize (updates (init i) [b]) = hash i b #-} {-# RULES "hashmany" forall b i. finalize (foldl update (init i) b) = hashlazy i (L.fromChunks b) #-} {-# RULES "hashlazy" forall b i. finalize (foldl update (init i) $ L.toChunks b) = hashlazy i b #-} {-# INLINE withByteStringPtr #-} withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a withByteStringPtr b f = withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off) where (fptr, off, _) = toForeignPtr b {-# INLINE memcopy64 #-} memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO () memcopy64 dst src = mapM_ peekAndPoke [0..(45-1)] where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx where createCtx = create sizeCtx $ \dstPtr -> withByteStringPtr ctxB $ \srcPtr -> do memcopy64 (castPtr dstPtr) (castPtr srcPtr) f (castPtr dstPtr) withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a withCtxThrow (Ctx ctxB) f = allocaBytes sizeCtx $ \dstPtr -> withByteStringPtr ctxB $ \srcPtr -> do memcopy64 (castPtr dstPtr) (castPtr srcPtr) f (castPtr dstPtr) withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr) withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr) foreign import ccall unsafe "sha3.h cryptohash_sha3_init" c_sha3_init :: Ptr Ctx -> Word32 -> IO () foreign import ccall "sha3.h cryptohash_sha3_update" c_sha3_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "sha3.h cryptohash_sha3_finalize" c_sha3_finalize :: Ptr Ctx -> Ptr Word8 -> IO () updateInternalIO :: Ptr Ctx -> ByteString -> IO () updateInternalIO ptr d = unsafeUseAsCStringLen d (\(cs, len) -> c_sha3_update ptr (castPtr cs) (fromIntegral len)) finalizeInternalIO :: Ptr Ctx -> IO ByteString finalizeInternalIO ptr = peekHashlen ptr >>= \digestSize -> create digestSize (c_sha3_finalize ptr) {-# NOINLINE init #-} -- | init a context init :: Int -> Ctx init hashlen = unsafeDoIO $ withCtxNew $ \ptr -> c_sha3_init ptr (fromIntegral hashlen) {-# NOINLINE update #-} -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d {-# NOINLINE updates #-} -- | updates a context with multiples bytestring updates :: Ctx -> [ByteString] -> Ctx updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d {-# NOINLINE finalize #-} -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO {-# NOINLINE hash #-} -- | hash a strict bytestring into a digest bytestring hash :: Int -> ByteString -> ByteString hash hashlen d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do c_sha3_init ptr (fromIntegral hashlen) >> updateInternalIO ptr d >> finalizeInternalIO ptr {-# NOINLINE hashlazy #-} -- | hash a lazy bytestring into a digest bytestring hashlazy :: Int -> L.ByteString -> ByteString hashlazy hashlen l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do c_sha3_init ptr (fromIntegral hashlen) >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr cryptohash-0.11.9/Crypto/Hash/SHA384.hs0000644000000000000000000000321712675272160015540 0ustar0000000000000000{-# LANGUAGE PackageImports #-} -- | -- Module : Crypto.Hash.SHA384 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- A module containing SHA384 bindings -- module Crypto.Hash.SHA384 ( Ctx(..) -- * Incremental hashing Functions , init -- :: Ctx , update -- :: Ctx -> ByteString -> Ctx , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing , hash -- :: ByteString -> ByteString , hashlazy -- :: ByteString -> ByteString ) where import Prelude hiding (init) import qualified Data.ByteString.Lazy as L import Data.ByteString (ByteString) import Crypto.Hash.Internal (digestToByteString, digestToByteStringWitness) import qualified "cryptonite" Crypto.Hash as H -- | SHA384 Context newtype Ctx = Ctx (H.Context H.SHA384) -- | init a context init :: Ctx init = Ctx H.hashInit -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx update (Ctx ctx) d = Ctx $ H.hashUpdate ctx d -- | updates a context with multiples bytestring updates :: Ctx -> [ByteString] -> Ctx updates (Ctx ctx) d = Ctx $ H.hashUpdates ctx d -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString finalize (Ctx ctx) = digestToByteString $ H.hashFinalize ctx -- | hash a strict bytestring into a digest bytestring hash :: ByteString -> ByteString hash d = digestToByteStringWitness H.SHA384 $ H.hash d -- | hash a lazy bytestring into a digest bytestring hashlazy :: L.ByteString -> ByteString hashlazy l = digestToByteStringWitness H.SHA384 $ H.hashlazy l cryptohash-0.11.9/Crypto/Hash/SHA512.hs0000644000000000000000000001143412675272160015531 0ustar0000000000000000{-# LANGUAGE ForeignFunctionInterface #-} -- | -- Module : Crypto.Hash.SHA512 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- A module containing SHA512 bindings -- module Crypto.Hash.SHA512 ( Ctx(..) -- * Incremental hashing Functions , init -- :: Ctx , init_t -- :: Int -> Ctx , update -- :: Ctx -> ByteString -> Ctx , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing , hash -- :: ByteString -> ByteString , hashlazy -- :: ByteString -> ByteString ) where import Prelude hiding (init) import Foreign.Ptr import Foreign.ForeignPtr (withForeignPtr) import Foreign.Storable import Foreign.Marshal.Alloc import qualified Data.ByteString.Lazy as L import qualified Data.ByteString as B import Data.ByteString (ByteString) import Data.ByteString.Unsafe (unsafeUseAsCStringLen) import Data.ByteString.Internal (create, toForeignPtr) import Data.Word import Crypto.Hash.Internal (unsafeDoIO) -- | SHA512 Context newtype Ctx = Ctx ByteString {-# INLINE digestSize #-} digestSize :: Int digestSize = 64 {-# INLINE sizeCtx #-} sizeCtx :: Int sizeCtx = 256 {-# RULES "digestSize" B.length (finalize init) = digestSize #-} {-# RULES "hash" forall b. finalize (update init b) = hash b #-} {-# RULES "hash.list1" forall b. finalize (updates init [b]) = hash b #-} {-# RULES "hashmany" forall b. finalize (foldl update init b) = hashlazy (L.fromChunks b) #-} {-# RULES "hashlazy" forall b. finalize (foldl update init $ L.toChunks b) = hashlazy b #-} {-# INLINE withByteStringPtr #-} withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a withByteStringPtr b f = withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off) where (fptr, off, _) = toForeignPtr b {-# INLINE memcopy64 #-} memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO () memcopy64 dst src = mapM_ peekAndPoke [0..(32-1)] where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx where createCtx = create sizeCtx $ \dstPtr -> withByteStringPtr ctxB $ \srcPtr -> do memcopy64 (castPtr dstPtr) (castPtr srcPtr) f (castPtr dstPtr) withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a withCtxThrow (Ctx ctxB) f = allocaBytes sizeCtx $ \dstPtr -> withByteStringPtr ctxB $ \srcPtr -> do memcopy64 (castPtr dstPtr) (castPtr srcPtr) f (castPtr dstPtr) withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr) withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr) foreign import ccall unsafe "sha512.h cryptohash_sha512_init" c_sha512_init :: Ptr Ctx -> IO () foreign import ccall "sha512.h cryptohash_sha512_update" c_sha512_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "sha512.h cryptohash_sha512_finalize" c_sha512_finalize :: Ptr Ctx -> Ptr Word8 -> IO () foreign import ccall unsafe "sha512.h cryptohash_sha512_init_t" c_sha512_init_t :: Ptr Ctx -> Int -> IO () {-# NOINLINE init_t #-} -- | init a context using FIPS 180-4 for truncated SHA512 init_t :: Int -> Ctx init_t t = unsafeDoIO $ withCtxNew $ \ptr -> c_sha512_init_t ptr t updateInternalIO :: Ptr Ctx -> ByteString -> IO () updateInternalIO ptr d = unsafeUseAsCStringLen d (\(cs, len) -> c_sha512_update ptr (castPtr cs) (fromIntegral len)) finalizeInternalIO :: Ptr Ctx -> IO ByteString finalizeInternalIO ptr = create digestSize (c_sha512_finalize ptr) {-# NOINLINE init #-} -- | init a context init :: Ctx init = unsafeDoIO $ withCtxNew $ c_sha512_init {-# NOINLINE update #-} -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d {-# NOINLINE updates #-} -- | updates a context with multiples bytestring updates :: Ctx -> [ByteString] -> Ctx updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d {-# NOINLINE finalize #-} -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO {-# NOINLINE hash #-} -- | hash a strict bytestring into a digest bytestring hash :: ByteString -> ByteString hash d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do c_sha512_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr {-# NOINLINE hashlazy #-} -- | hash a lazy bytestring into a digest bytestring hashlazy :: L.ByteString -> ByteString hashlazy l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do c_sha512_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr cryptohash-0.11.9/Crypto/Hash/SHA512t.hs0000644000000000000000000000270712675272160015720 0ustar0000000000000000-- | -- Module : Crypto.Hash.SHA512t -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- A module containing SHA512/t -- module Crypto.Hash.SHA512t ( Ctx(..) -- * Incremental hashing Functions , init -- :: Ctx , update -- :: Ctx -> ByteString -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing , hash -- :: ByteString -> ByteString , hashlazy -- :: ByteString -> ByteString ) where import Prelude hiding (init) import Data.List (foldl') import Data.ByteString (ByteString) import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as L import qualified Crypto.Hash.SHA512 as SHA512 -- | SHA512 Context with variable size output data Ctx = Ctx !Int !SHA512.Ctx -- | init a context init :: Int -> Ctx init t = Ctx t (SHA512.init_t t) -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx update (Ctx t ctx) d = Ctx t (SHA512.update ctx d) -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString finalize (Ctx sz ctx) = B.take (sz `div` 8) (SHA512.finalize ctx) -- | hash a strict bytestring into a digest bytestring hash :: Int -> ByteString -> ByteString hash t = finalize . update (init t) -- | hash a lazy bytestring into a digest bytestring hashlazy :: Int -> L.ByteString -> ByteString hashlazy t = finalize . foldl' update (init t) . L.toChunks cryptohash-0.11.9/Crypto/Hash/Skein256.hs0000644000000000000000000001143112675272160016171 0ustar0000000000000000{-# LANGUAGE ForeignFunctionInterface #-} -- | -- Module : Crypto.Hash.Skein256 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- A module containing Skein256 bindings -- module Crypto.Hash.Skein256 ( Ctx(..) -- * Incremental hashing Functions , init -- :: Int -> Ctx , update -- :: Ctx -> ByteString -> Ctx , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing , hash -- :: Int -> ByteString -> ByteString , hashlazy -- :: Int -> ByteString -> ByteString ) where import Prelude hiding (init) import Foreign.Ptr import Foreign.ForeignPtr (withForeignPtr) import Foreign.Storable import Foreign.Marshal.Alloc import qualified Data.ByteString.Lazy as L import Data.ByteString (ByteString) import Data.ByteString.Unsafe (unsafeUseAsCStringLen) import Data.ByteString.Internal (create, toForeignPtr) import Data.Word import Crypto.Hash.Internal (unsafeDoIO) -- | Skein256 Context newtype Ctx = Ctx ByteString {-# INLINE sizeCtx #-} sizeCtx :: Int sizeCtx = 96 {- return the number of bytes of output for the digest -} peekHashlen :: Ptr Ctx -> IO Int peekHashlen ptr = peek iptr >>= \v -> return $! fromIntegral v where iptr :: Ptr Word32 iptr = castPtr ptr {-# RULES "hash" forall b i. finalize (update (init i) b) = hash i b #-} {-# RULES "hash.list1" forall b i. finalize (updates (init i) [b]) = hash i b #-} {-# RULES "hashmany" forall b i. finalize (foldl update (init i) b) = hashlazy i (L.fromChunks b) #-} {-# RULES "hashlazy" forall b i. finalize (foldl update (init i) $ L.toChunks b) = hashlazy i b #-} {-# INLINE withByteStringPtr #-} withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a withByteStringPtr b f = withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off) where (fptr, off, _) = toForeignPtr b {-# INLINE memcopy64 #-} memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO () memcopy64 dst src = mapM_ peekAndPoke [0..(12-1)] where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx where createCtx = create sizeCtx $ \dstPtr -> withByteStringPtr ctxB $ \srcPtr -> do memcopy64 (castPtr dstPtr) (castPtr srcPtr) f (castPtr dstPtr) withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a withCtxThrow (Ctx ctxB) f = allocaBytes sizeCtx $ \dstPtr -> withByteStringPtr ctxB $ \srcPtr -> do memcopy64 (castPtr dstPtr) (castPtr srcPtr) f (castPtr dstPtr) withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr) withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr) foreign import ccall unsafe "skein256.h cryptohash_skein256_init" c_skein256_init :: Ptr Ctx -> Word32 -> IO () foreign import ccall "skein256.h cryptohash_skein256_update" c_skein256_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "skein256.h cryptohash_skein256_finalize" c_skein256_finalize :: Ptr Ctx -> Ptr Word8 -> IO () updateInternalIO :: Ptr Ctx -> ByteString -> IO () updateInternalIO ptr d = unsafeUseAsCStringLen d (\(cs, len) -> c_skein256_update ptr (castPtr cs) (fromIntegral len)) finalizeInternalIO :: Ptr Ctx -> IO ByteString finalizeInternalIO ptr = peekHashlen ptr >>= \digestSize -> create digestSize (c_skein256_finalize ptr) {-# NOINLINE init #-} -- | init a context init :: Int -> Ctx init hashlen = unsafeDoIO $ withCtxNew $ \ptr -> c_skein256_init ptr (fromIntegral hashlen) {-# NOINLINE update #-} -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d {-# NOINLINE updates #-} -- | updates a context with multiples bytestring updates :: Ctx -> [ByteString] -> Ctx updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d {-# NOINLINE finalize #-} -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO {-# NOINLINE hash #-} -- | hash a strict bytestring into a digest bytestring hash :: Int -> ByteString -> ByteString hash hashlen d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do c_skein256_init ptr (fromIntegral hashlen) >> updateInternalIO ptr d >> finalizeInternalIO ptr {-# NOINLINE hashlazy #-} -- | hash a lazy bytestring into a digest bytestring hashlazy :: Int -> L.ByteString -> ByteString hashlazy hashlen l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do c_skein256_init ptr (fromIntegral hashlen) >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr cryptohash-0.11.9/Crypto/Hash/Skein512.hs0000644000000000000000000001143212675272160016165 0ustar0000000000000000{-# LANGUAGE ForeignFunctionInterface #-} -- | -- Module : Crypto.Hash.Skein512 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- A module containing Skein512 bindings -- module Crypto.Hash.Skein512 ( Ctx(..) -- * Incremental hashing Functions , init -- :: Int -> Ctx , update -- :: Ctx -> ByteString -> Ctx , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing , hash -- :: Int -> ByteString -> ByteString , hashlazy -- :: Int -> ByteString -> ByteString ) where import Prelude hiding (init) import Foreign.Ptr import Foreign.ForeignPtr (withForeignPtr) import Foreign.Storable import Foreign.Marshal.Alloc import qualified Data.ByteString.Lazy as L import Data.ByteString (ByteString) import Data.ByteString.Unsafe (unsafeUseAsCStringLen) import Data.ByteString.Internal (create, toForeignPtr) import Data.Word import Crypto.Hash.Internal (unsafeDoIO) -- | Skein512 Context newtype Ctx = Ctx ByteString {-# INLINE sizeCtx #-} sizeCtx :: Int sizeCtx = 160 {- return the number of bytes of output for the digest -} peekHashlen :: Ptr Ctx -> IO Int peekHashlen ptr = peek iptr >>= \v -> return $! fromIntegral v where iptr :: Ptr Word32 iptr = castPtr ptr {-# RULES "hash" forall b i. finalize (update (init i) b) = hash i b #-} {-# RULES "hash.list1" forall b i. finalize (updates (init i) [b]) = hash i b #-} {-# RULES "hashmany" forall b i. finalize (foldl update (init i) b) = hashlazy i (L.fromChunks b) #-} {-# RULES "hashlazy" forall b i. finalize (foldl update (init i) $ L.toChunks b) = hashlazy i b #-} {-# INLINE withByteStringPtr #-} withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a withByteStringPtr b f = withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off) where (fptr, off, _) = toForeignPtr b {-# INLINE memcopy64 #-} memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO () memcopy64 dst src = mapM_ peekAndPoke [0..(20-1)] where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx where createCtx = create sizeCtx $ \dstPtr -> withByteStringPtr ctxB $ \srcPtr -> do memcopy64 (castPtr dstPtr) (castPtr srcPtr) f (castPtr dstPtr) withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a withCtxThrow (Ctx ctxB) f = allocaBytes sizeCtx $ \dstPtr -> withByteStringPtr ctxB $ \srcPtr -> do memcopy64 (castPtr dstPtr) (castPtr srcPtr) f (castPtr dstPtr) withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr) withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr) foreign import ccall unsafe "skein512.h cryptohash_skein512_init" c_skein512_init :: Ptr Ctx -> Word32 -> IO () foreign import ccall "skein512.h cryptohash_skein512_update" c_skein512_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "skein512.h cryptohash_skein512_finalize" c_skein512_finalize :: Ptr Ctx -> Ptr Word8 -> IO () updateInternalIO :: Ptr Ctx -> ByteString -> IO () updateInternalIO ptr d = unsafeUseAsCStringLen d (\(cs, len) -> c_skein512_update ptr (castPtr cs) (fromIntegral len)) finalizeInternalIO :: Ptr Ctx -> IO ByteString finalizeInternalIO ptr = peekHashlen ptr >>= \digestSize -> create digestSize (c_skein512_finalize ptr) {-# NOINLINE init #-} -- | init a context init :: Int -> Ctx init hashlen = unsafeDoIO $ withCtxNew $ \ptr -> c_skein512_init ptr (fromIntegral hashlen) {-# NOINLINE update #-} -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> updateInternalIO ptr d {-# NOINLINE updates #-} -- | updates a context with multiples bytestring updates :: Ctx -> [ByteString] -> Ctx updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (updateInternalIO ptr) d {-# NOINLINE finalize #-} -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString finalize ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO {-# NOINLINE hash #-} -- | hash a strict bytestring into a digest bytestring hash :: Int -> ByteString -> ByteString hash hashlen d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do c_skein512_init ptr (fromIntegral hashlen) >> updateInternalIO ptr d >> finalizeInternalIO ptr {-# NOINLINE hashlazy #-} -- | hash a lazy bytestring into a digest bytestring hashlazy :: Int -> L.ByteString -> ByteString hashlazy hashlen l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do c_skein512_init ptr (fromIntegral hashlen) >> mapM_ (updateInternalIO ptr) (L.toChunks l) >> finalizeInternalIO ptr cryptohash-0.11.9/Crypto/Hash/Tiger.hs0000644000000000000000000000321012675272160015731 0ustar0000000000000000{-# LANGUAGE PackageImports #-} -- | -- Module : Crypto.Hash.Tiger -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- A module containing Tiger bindings -- module Crypto.Hash.Tiger ( Ctx(..) -- * Incremental hashing Functions , init -- :: Ctx , update -- :: Ctx -> ByteString -> Ctx , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing , hash -- :: ByteString -> ByteString , hashlazy -- :: ByteString -> ByteString ) where import Prelude hiding (init) import qualified Data.ByteString.Lazy as L import Data.ByteString (ByteString) import Crypto.Hash.Internal (digestToByteString, digestToByteStringWitness) import qualified "cryptonite" Crypto.Hash as H -- | Tiger Context newtype Ctx = Ctx (H.Context H.Tiger) -- | init a context init :: Ctx init = Ctx H.hashInit -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx update (Ctx ctx) d = Ctx $ H.hashUpdate ctx d -- | updates a context with multiples bytestring updates :: Ctx -> [ByteString] -> Ctx updates (Ctx ctx) d = Ctx $ H.hashUpdates ctx d -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString finalize (Ctx ctx) = digestToByteString $ H.hashFinalize ctx -- | hash a strict bytestring into a digest bytestring hash :: ByteString -> ByteString hash d = digestToByteStringWitness H.Tiger $ H.hash d -- | hash a lazy bytestring into a digest bytestring hashlazy :: L.ByteString -> ByteString hashlazy l = digestToByteStringWitness H.Tiger $ H.hashlazy l cryptohash-0.11.9/Crypto/Hash/Types.hs0000644000000000000000000000246012675272160015771 0ustar0000000000000000{-# LANGUAGE PackageImports #-} -- | -- Module : Crypto.Hash.Types -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- Crypto hash types definitions -- module Crypto.Hash.Types ( Context(..) , Digest(..) -- * deprecated , contextToByteString , digestToByteString ) where import Data.ByteString (ByteString) import Data.Byteable import qualified Data.ByteArray as B (convert) import qualified "cryptonite" Crypto.Hash as H -- | Represent a context for a given hash algorithm. newtype Context a = Context (H.Context a) instance Byteable (Context a) where toBytes (Context ctx) = B.convert ctx --- | return the binary bytestring. deprecated use toBytes. contextToByteString :: Context a -> ByteString contextToByteString = toBytes -- | Represent a digest for a given hash algorithm. newtype Digest a = Digest (H.Digest a) deriving (Eq,Ord) instance Byteable (Digest a) where toBytes (Digest dig) = B.convert dig -- | return the binary bytestring. deprecated use toBytes. {-# DEPRECATED digestToByteString "use toBytes from byteable:Data.Byteable" #-} digestToByteString :: Digest a -> ByteString digestToByteString = toBytes instance Show (Digest a) where show (Digest dig) = show dig cryptohash-0.11.9/Crypto/Hash/Whirlpool.hs0000644000000000000000000000324412675272160016645 0ustar0000000000000000{-# LANGUAGE PackageImports #-} -- | -- Module : Crypto.Hash.Whirlpool -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- A module containing Whirlpool bindings -- module Crypto.Hash.Whirlpool ( Ctx(..) -- * Incremental hashing Functions , init -- :: Ctx , update -- :: Ctx -> ByteString -> Ctx , updates -- :: Ctx -> [ByteString] -> Ctx , finalize -- :: Ctx -> ByteString -- * Single Pass hashing , hash -- :: ByteString -> ByteString , hashlazy -- :: ByteString -> ByteString ) where import Prelude hiding (init) import qualified Data.ByteString.Lazy as L import Data.ByteString (ByteString) import Crypto.Hash.Internal (digestToByteString, digestToByteStringWitness) import qualified "cryptonite" Crypto.Hash as H -- | Whirlpool Context newtype Ctx = Ctx (H.Context H.Whirlpool) -- | init a context init :: Ctx init = Ctx H.hashInit -- | update a context with a bytestring update :: Ctx -> ByteString -> Ctx update (Ctx ctx) d = Ctx $ H.hashUpdate ctx d -- | updates a context with multiples bytestring updates :: Ctx -> [ByteString] -> Ctx updates (Ctx ctx) d = Ctx $ H.hashUpdates ctx d -- | finalize the context into a digest bytestring finalize :: Ctx -> ByteString finalize (Ctx ctx) = digestToByteString $ H.hashFinalize ctx -- | hash a strict bytestring into a digest bytestring hash :: ByteString -> ByteString hash d = digestToByteStringWitness H.Whirlpool $ H.hash d -- | hash a lazy bytestring into a digest bytestring hashlazy :: L.ByteString -> ByteString hashlazy l = digestToByteStringWitness H.Whirlpool $ H.hashlazy l cryptohash-0.11.9/Crypto/MAC/0000755000000000000000000000000012675272160014044 5ustar0000000000000000cryptohash-0.11.9/Crypto/MAC/HMAC.hs0000644000000000000000000000207112675272160015110 0ustar0000000000000000-- | -- Module : Crypto.MAC.HMAC -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- provide the HMAC (Hash based Message Authentification Code) base algorithm. -- -- module Crypto.MAC.HMAC ( hmac ) where import Data.ByteString (ByteString) import qualified Data.ByteString as B import Data.Bits (xor) -- | compute a MAC using the supplied hashing function -- -- An incremental API can be found in the module "Crypto.Hash". -- hmac :: (ByteString -> ByteString) -- ^ hash function -> Int -- ^ block size -> ByteString -- ^ secret -> ByteString -- ^ message -> ByteString hmac hashF blockSize secret msg = hashF $ B.append opad (hashF $ B.append ipad msg) where opad = B.map (xor 0x5c) k' ipad = B.map (xor 0x36) k' k' = B.append kt pad kt = if B.length secret > fromIntegral blockSize then hashF secret else secret pad = B.replicate (fromIntegral blockSize - B.length kt) 0 cryptohash-0.11.9/Crypto/MAC/SHA3.hs0000644000000000000000000000437712675272160015111 0ustar0000000000000000-- | -- Module : Crypto.MAC.SHA3 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- provide a simple SHA3 MAC mechanism with -- -- > mac = hash(key|message) -- module Crypto.MAC.SHA3 ( MAC512(..) , MAC384(..) , MAC256(..) , MAC224(..) , mac512 , mac384 , mac256 , mac224 ) where import Data.Byteable import Data.ByteString (ByteString) import Crypto.Hash -- | SHA3_512 MAC data MAC512 = MAC512 { getDigest512 :: Digest SHA3_512 } instance Byteable MAC512 where toBytes (MAC512 b) = toBytes b instance Eq MAC512 where (MAC512 b1) == (MAC512 b2) = constEqBytes (toBytes b1) (toBytes b2) -- | SHA3_384 MAC data MAC384 = MAC384 { getDigest384 :: Digest SHA3_384 } instance Byteable MAC384 where toBytes (MAC384 b) = toBytes b instance Eq MAC384 where (MAC384 b1) == (MAC384 b2) = constEqBytes (toBytes b1) (toBytes b2) -- | SHA3_256 MAC data MAC256 = MAC256 { getDigest256 :: Digest SHA3_256 } instance Byteable MAC256 where toBytes (MAC256 b) = toBytes b instance Eq MAC256 where (MAC256 b1) == (MAC256 b2) = constEqBytes (toBytes b1) (toBytes b2) -- | SHA3_224 MAC data MAC224 = MAC224 { getDigest224 :: Digest SHA3_224 } instance Byteable MAC224 where toBytes (MAC224 b) = toBytes b instance Eq MAC224 where (MAC224 b1) == (MAC224 b2) = constEqBytes (toBytes b1) (toBytes b2) -- | compute a MAC using a simple SHA3_512 key|msg mac512 :: ByteString -- ^ secret -> ByteString -- ^ message -> MAC512 mac512 secret msg = MAC512 $ hashFinalize $ hashUpdates hashInit [secret,msg] -- | compute a MAC using a simple SHA3_384 key|msg mac384 :: ByteString -- ^ secret -> ByteString -- ^ message -> MAC384 mac384 secret msg = MAC384 $ hashFinalize $ hashUpdates hashInit [secret,msg] -- | compute a MAC using a simple SHA3_256 key|msg mac256 :: ByteString -- ^ secret -> ByteString -- ^ message -> MAC256 mac256 secret msg = MAC256 $ hashFinalize $ hashUpdates hashInit [secret,msg] -- | compute a MAC using a simple SHA3_224 key|msg mac224 :: ByteString -- ^ secret -> ByteString -- ^ message -> MAC224 mac224 secret msg = MAC224 $ hashFinalize $ hashUpdates hashInit [secret,msg] cryptohash-0.11.9/Tests/0000755000000000000000000000000012675272160013266 5ustar0000000000000000cryptohash-0.11.9/Tests/KAT.hs0000644000000000000000000003274412675272160014253 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ViewPatterns #-} import Data.Char import Data.Bits import Data.Word import Data.ByteString (ByteString) import Data.Byteable import Data.Foldable (foldl') import Data.Monoid (mconcat) import qualified Data.ByteString as B import qualified Data.ByteString.Char8 as BC import qualified Crypto.Hash.MD2 as MD2 import qualified Crypto.Hash.MD4 as MD4 import qualified Crypto.Hash.MD5 as MD5 import qualified Crypto.Hash.SHA1 as SHA1 import qualified Crypto.Hash.SHA224 as SHA224 import qualified Crypto.Hash.SHA256 as SHA256 import qualified Crypto.Hash.SHA384 as SHA384 import qualified Crypto.Hash.SHA512 as SHA512 import qualified Crypto.Hash.SHA512t as SHA512t import qualified Crypto.Hash.RIPEMD160 as RIPEMD160 import qualified Crypto.Hash.Tiger as Tiger import qualified Crypto.Hash.Skein256 as Skein256 import qualified Crypto.Hash.Skein512 as Skein512 import qualified Crypto.Hash.Whirlpool as Whirlpool import Crypto.Hash import Crypto.MAC import Test.Tasty import Test.Tasty.QuickCheck import Test.Tasty.HUnit v0,v1,v2 :: ByteString v0 = "" v1 = "The quick brown fox jumps over the lazy dog" v2 = "The quick brown fox jumps over the lazy cog" vectors = [ v0, v1, v2 ] instance Arbitrary ByteString where arbitrary = B.pack `fmap` arbitrary data HashFct = HashFct { fctHash :: (B.ByteString -> B.ByteString) , fctInc :: ([B.ByteString] -> B.ByteString) } hashinc i u f = f . foldl u i md2Hash = HashFct { fctHash = MD2.hash, fctInc = hashinc MD2.init MD2.update MD2.finalize } md4Hash = HashFct { fctHash = MD4.hash, fctInc = hashinc MD4.init MD4.update MD4.finalize } md5Hash = HashFct { fctHash = MD5.hash, fctInc = hashinc MD5.init MD5.update MD5.finalize } sha1Hash = HashFct { fctHash = SHA1.hash, fctInc = hashinc SHA1.init SHA1.update SHA1.finalize } sha224Hash = HashFct { fctHash = SHA224.hash, fctInc = hashinc SHA224.init SHA224.update SHA224.finalize } sha256Hash = HashFct { fctHash = SHA256.hash, fctInc = hashinc SHA256.init SHA256.update SHA256.finalize } sha384Hash = HashFct { fctHash = SHA384.hash, fctInc = hashinc SHA384.init SHA384.update SHA384.finalize } sha512Hash = HashFct { fctHash = SHA512.hash, fctInc = hashinc SHA512.init SHA512.update SHA512.finalize } sha512_224Hash = HashFct { fctHash = SHA512t.hash 224, fctInc = hashinc (SHA512t.init 224) SHA512t.update SHA512t.finalize } sha512_256Hash = HashFct { fctHash = SHA512t.hash 256, fctInc = hashinc (SHA512t.init 256) SHA512t.update SHA512t.finalize } ripemd160Hash = HashFct { fctHash = RIPEMD160.hash, fctInc = hashinc RIPEMD160.init RIPEMD160.update RIPEMD160.finalize } tigerHash = HashFct { fctHash = Tiger.hash, fctInc = hashinc Tiger.init Tiger.update Tiger.finalize } skein256Hash x = HashFct { fctHash = Skein256.hash x, fctInc = hashinc (Skein256.init x) Skein256.update Skein256.finalize } skein512Hash x = HashFct { fctHash = Skein512.hash x, fctInc = hashinc (Skein512.init x) Skein512.update Skein512.finalize } whirlpoolHash = HashFct { fctHash = Whirlpool.hash, fctInc = hashinc Whirlpool.init Whirlpool.update Whirlpool.finalize } results :: [ (String, HashFct, [String]) ] results = [ ("MD2", md2Hash, [ "8350e5a3e24c153df2275c9f80692773", "03d85a0d629d2c442e987525319fc471", "6b890c9292668cdbbfda00a4ebf31f05" ]), ("MD4", md4Hash, [ "31d6cfe0d16ae931b73c59d7e0c089c0", "1bee69a46ba811185c194762abaeae90", "b86e130ce7028da59e672d56ad0113df" ]), ("MD5", md5Hash, [ "d41d8cd98f00b204e9800998ecf8427e", "9e107d9d372bb6826bd81d3542a419d6", "1055d3e698d289f2af8663725127bd4b" ]), ("SHA1", sha1Hash, [ "da39a3ee5e6b4b0d3255bfef95601890afd80709", "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12", "de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3" ]), ("SHA224", sha224Hash, [ "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", "730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525", "fee755f44a55f20fb3362cdc3c493615b3cb574ed95ce610ee5b1e9b" ]), ("SHA256", sha256Hash, [ "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592", "e4c4d8f3bf76b692de791a173e05321150f7a345b46484fe427f6acc7ecc81be" ]), ("SHA384", sha384Hash, [ "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", "ca737f1014a48f4c0b6dd43cb177b0afd9e5169367544c494011e3317dbf9a509cb1e5dc1e85a941bbee3d7f2afbc9b1", "098cea620b0978caa5f0befba6ddcf22764bea977e1c70b3483edfdf1de25f4b40d6cea3cadf00f809d422feb1f0161b" ]), ("SHA512", sha512Hash, [ "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6", "3eeee1d0e11733ef152a6c29503b3ae20c4f1f3cda4cb26f1bc1a41f91c7fe4ab3bd86494049e201c4bd5155f31ecb7a3c8606843c4cc8dfcab7da11c8ae5045" ]), ("SHA512/224", sha512_224Hash, [ "6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4", "944cd2847fb54558d4775db0485a50003111c8e5daa63fe722c6aa37", "2b9d6565a7e40f780ba8ab7c8dcf41e3ed3b77997f4c55aa987eede5" ]), ("SHA512/256", sha512_256Hash, [ "c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a", "dd9d67b371519c339ed8dbd25af90e976a1eeefd4ad3d889005e532fc5bef04d", "cc8d255a7f2f38fd50388fd1f65ea7910835c5c1e73da46fba01ea50d5dd76fb" ]), ("RIPEMD160", ripemd160Hash, [ "9c1185a5c5e9fc54612808977ee8f548b2258d31", "37f332f68db77bd9d7edd4969571ad671cf9dd3b", "132072df690933835eb8b6ad0b77e7b6f14acad7" ]), ("Tiger", tigerHash, [ "3293ac630c13f0245f92bbb1766e16167a4e58492dde73f3", "6d12a41e72e644f017b6f0e2f7b44c6285f06dd5d2c5b075", "a8f04b0f7201a0d728101c9d26525b31764a3493fcd8458f" ]) , ("Skein256-160", skein256Hash 160, [ "ff800bed6d2044ee9d604a674e3fda50d9b24a72", "3265703c166aa3e0d7da070b9cf1b1a5953f0a77", "17b29aa1424b3ec022505bd215ff73fd2e6d1e5a" ]) , ("Skein256-256", skein256Hash 256, [ "c8877087da56e072870daa843f176e9453115929094c3a40c463a196c29bf7ba", "c0fbd7d779b20f0a4614a66697f9e41859eaf382f14bf857e8cdb210adb9b3fe", "fb2f2f2deed0e1dd7ee2b91cee34e2d1c22072e1f5eaee288c35a0723eb653cd" ]) , ("Skein512-160", skein512Hash 160, [ "49daf1ccebb3544bc93cb5019ba91b0eea8876ee", "826325ee55a6dd18c3b2dbbc9c10420f5475975e", "7544ec7a35712ec953f02b0d0c86641cae4eb6e5" ]) , ("Skein512-384", skein512Hash 384, [ "dd5aaf4589dc227bd1eb7bc68771f5baeaa3586ef6c7680167a023ec8ce26980f06c4082c488b4ac9ef313f8cbe70808", "f814c107f3465e7c54048a5503547deddc377264f05c706b0d19db4847b354855ee52ab6a785c238c9e710d848542041", "e06520eeadc1d0a44fee1d2492547499c1e58526387c8b9c53905e5edb79f9840575cbf844e21b1ad1ea126dd8a8ca6f" ]) , ("Skein512-512", skein512Hash 512, [ "bc5b4c50925519c290cc634277ae3d6257212395cba733bbad37a4af0fa06af41fca7903d06564fea7a2d3730dbdb80c1f85562dfcc070334ea4d1d9e72cba7a", "94c2ae036dba8783d0b3f7d6cc111ff810702f5c77707999be7e1c9486ff238a7044de734293147359b4ac7e1d09cd247c351d69826b78dcddd951f0ef912713", "7f81113575e4b4d3441940e87aca331e6d63d103fe5107f29cd877af0d0f5e0ea34164258c60da5190189d0872e63a96596d2ef25e709099842da71d64111e0f" ]) , ("Skein512-896", skein512Hash 896, [ "b95175236c83a459ce7ec6c12b761a838b22d750e765b3fdaa892201b2aa714bc3d1d887dd64028bbf177c1dd11baa09c6c4ddb598fd07d6a8c131a09fc5b958e2999a8006754b25abe3bf8492b7eabec70e52e04e5ac867df2393c573f16eee3244554f1d2b724f2c0437c62007f770", "3265708553e7d146e5c7bcbc97b3e9e9f5b53a5e4af53612bdd6454da4fa7b13d413184fe34ed57b6574be10e389d0ec4b1d2b1dd2c80e0257d5a76b2cd86a19a27b1bcb3cc24d911b5dc5ee74d19ad558fd85b5f024e99f56d1d3199f1f9f88ed85fab9f945f11cf9fc00e94e3ca4c7", "3d23d3db9be719bbd2119f8402a28f38d8225faa79d5b68b80738c64a82004aafc7a840cd6dd9bced6644fa894a3d8d7d2ee89525fd1956a2db052c4c2f8d2111c91ef46b0997540d42bcf384826af1a5ef6510077f52d0574cf2b46f1b6a5dad07ed40f3d21a13ca2d079fa602ff02d" ]) , ("Whirlpool", whirlpoolHash, [ "19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288febcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3", "b97de512e91e3828b40d2b0fdce9ceb3c4a71f9bea8d88e75c4fa854df36725fd2b52eb6544edcacd6f8beddfea403cb55ae31f03ad62a5ef54e42ee82c3fb35", "dce81fc695cfea3d7e1446509238daf89f24cc61896f2d265927daa70f2108f8902f0dfd68be085d5abb9fcd2e482c1dc24f2fabf81f40b73495cad44d7360d3"]) ] hexalise s = concatMap (\c -> [ hex $ c `div` 16, hex $ c `mod` 16 ]) s where hex i | i >= 0 && i <= 9 = fromIntegral (ord '0') + i | i >= 10 && i <= 15 = fromIntegral (ord 'a') + i - 10 | otherwise = 0 hexaliseB :: B.ByteString -> B.ByteString hexaliseB = B.pack . hexalise . B.unpack splitB :: Int -> ByteString -> [ByteString] splitB l b = if B.length b > l then let (b1, b2) = B.splitAt l b in b1 : splitB l b2 else [ b ] showHash :: B.ByteString -> String showHash = map (toEnum.fromEnum) . hexalise . B.unpack runhash hash v = showHash $ (fctHash hash) $ v runhashinc hash v = showHash $ (fctInc hash) $ v makeTestAlg (name, hash, results) = testGroup name $ concatMap maketest (zip3 [0..] vectors results) where runtest :: ByteString -> String runtest v = runhash hash v runtestinc :: Int -> ByteString -> String runtestinc i v = runhashinc hash $ splitB i v maketest (i, v, r) = [ testCase (show i ++ " one-pass") (r @=? runtest v) , testCase (show i ++ " inc 1") (r @=? runtestinc 1 v) , testCase (show i ++ " inc 2") (r @=? runtestinc 2 v) , testCase (show i ++ " inc 3") (r @=? runtestinc 3 v) , testCase (show i ++ " inc 4") (r @=? runtestinc 4 v) , testCase (show i ++ " inc 5") (r @=? runtestinc 5 v) , testCase (show i ++ " inc 9") (r @=? runtestinc 9 v) , testCase (show i ++ " inc 16") (r @=? runtestinc 16 v) ] katTests :: [TestTree] katTests = map makeTestAlg results apiTests :: [TestTree] apiTests = [ testCase "sha1 api" (runhash sha1Hash B.empty @=? show (hash B.empty :: Digest SHA1)) , testCase "sha256 api" (runhash sha256Hash B.empty @=? show (hash B.empty :: Digest SHA256)) , testCase "sha512 api" (runhash sha512Hash B.empty @=? show (hash B.empty :: Digest SHA512)) ] data MACVector = MACVector { macKey :: ByteString , macSecret :: ByteString , macResult :: ByteString } md5MACVectors = [ MACVector B.empty B.empty "\x74\xe6\xf7\x29\x8a\x9c\x2d\x16\x89\x35\xf5\x8c\x00\x1b\xad\x88" , MACVector "key" v1 "\x80\x07\x07\x13\x46\x3e\x77\x49\xb9\x0c\x2d\xc2\x49\x11\xe2\x75" ] sha1MACVectors = [ MACVector B.empty B.empty "\xfb\xdb\x1d\x1b\x18\xaa\x6c\x08\x32\x4b\x7d\x64\xb7\x1f\xb7\x63\x70\x69\x0e\x1d" , MACVector "key" v1 "\xde\x7c\x9b\x85\xb8\xb7\x8a\xa6\xbc\x8a\x7a\x36\xf7\x0a\x90\x70\x1c\x9d\xb4\xd9" ] sha256MACVectors = [ MACVector B.empty B.empty "\xb6\x13\x67\x9a\x08\x14\xd9\xec\x77\x2f\x95\xd7\x78\xc3\x5f\xc5\xff\x16\x97\xc4\x93\x71\x56\x53\xc6\xc7\x12\x14\x42\x92\xc5\xad" , MACVector "key" v1 "\xf7\xbc\x83\xf4\x30\x53\x84\x24\xb1\x32\x98\xe6\xaa\x6f\xb1\x43\xef\x4d\x59\xa1\x49\x46\x17\x59\x97\x47\x9d\xbc\x2d\x1a\x3c\xd8" ] macTests :: [TestTree] macTests = [ testGroup "hmac-md5" $ map (toMACTest MD5) $ zip [0..] md5MACVectors , testGroup "hmac-sha1" $ map (toMACTest SHA1) $ zip [0..] sha1MACVectors , testGroup "hmac-sha256" $ map (toMACTest SHA256) $ zip [0..] sha256MACVectors ] where toMACTest hashAlg (i, macVector) = testCase (show i) (macResult macVector @=? toBytes (hmacAlg hashAlg (macKey macVector) (macSecret macVector))) macIncrementalTests :: [TestTree] macIncrementalTests = [ testGroup "hmac-md5" $ map (toMACTest MD5) $ zip [0..] md5MACVectors , testGroup "hmac-sha1" $ map (toMACTest SHA1) $ zip [0..] sha1MACVectors , testGroup "hmac-sha256" $ map (toMACTest SHA256) $ zip [0..] sha256MACVectors , testProperty "hmac-md5" $ prop_inc0 MD5 , testProperty "hmac-md5" $ prop_inc1 MD5 , testProperty "hmac-sha1" $ prop_inc0 SHA1 , testProperty "hmac-sha1" $ prop_inc1 SHA1 , testProperty "hmac-sha256" $ prop_inc0 SHA256 , testProperty "hmac-sha256" $ prop_inc1 SHA256 ] where toMACTest hashAlg (i, macVector) = testCase (show i) (macResult macVector @=? toBytes (hmacFinalize $ hmacUpdate initCtx (macSecret macVector))) where initCtx = hmacInitAlg hashAlg (macKey macVector) prop_inc0 :: HashAlgorithm a => a -> ByteString -> ByteString -> Bool prop_inc0 hashAlg secret msg = hmacFinalize (hmacUpdate initCtx msg) == hmacAlg hashAlg secret msg where initCtx = hmacInitAlg hashAlg secret prop_inc1 :: HashAlgorithm a => a -> ByteString -> [ByteString] -> Bool prop_inc1 hashAlg secret msgs = hmacFinalize (foldl' hmacUpdate initCtx msgs) == hmacAlg hashAlg secret (mconcat msgs) where initCtx = hmacInitAlg hashAlg secret main = defaultMain $ testGroup "cryptohash" [ testGroup "KATs" katTests , testGroup "API" apiTests , testGroup "MACs" macTests , testGroup "Incremental MACs" macIncrementalTests ]