scrypt (empty) → 0.1
raw patch · 10 files changed
+1219/−0 lines, 10 filesdep +basedep +bytestringsetup-changed
Dependencies added: base, bytestring
Files
- Crypto/Scrypt.hs +97/−0
- LICENSE +30/−0
- README.markdown +19/−0
- Setup.hs +2/−0
- cbits/crypto_scrypt-sse.c +364/−0
- cbits/crypto_scrypt.h +46/−0
- cbits/sha256.c +410/−0
- cbits/sha256.h +62/−0
- cbits/sysendian.h +138/−0
- scrypt.cabal +51/−0
+ Crypto/Scrypt.hs view
@@ -0,0 +1,97 @@+{-# LANGUAGE ForeignFunctionInterface, RecordWildCards, NamedFieldPuns #-}++-- |Scrypt is a sequential memory-hard key derivation function. This module+-- provides bindings to a fast C implementation of scrypt, written by Colin+-- Percival. See <http://www.tarsnap.com/scrypt.html> for more information+-- on scrypt.+module Crypto.Scrypt+ ( + -- *Parameters to the @scrypt@ function+ ScryptParams, params, defaultParams+ -- * The @scrypt@ key derivation function+ , scrypt, getSalt+ , Pass(..), Salt(..), PassHash(..)+ ) where++import Control.Applicative ((<$>))+import Data.ByteString+import Data.Maybe+import Foreign+import Foreign.C+import System.IO+++newtype Pass = Pass ByteString deriving (Show)+newtype Salt = Salt ByteString deriving (Show)+newtype PassHash = PassHash ByteString deriving (Show,Eq)++-- |Encapsulates the three tuning parameters to the 'scrypt' function: @N@,+-- @r@ and @p@. The parameters affect running time and memory usage:+--+-- /Memory usage/ is approximately @128*r*N@ bytes. Note that the+-- 'params' function takes @log_2(N)@ as a parameter. As an example, the+-- 'defaultParams'+-- +-- @ log_2(N) = 14, r = 8, and p = 1@+--+-- lead to 'scrypt' using @128 * 8 * 2^14 = 16M@ bytes of memory.+--+-- /Running time/ is proportional to all of @N@, @r@ and @p@. However+-- @p@ only as an insignificant influence on memory usage an can thus be+-- used to tune the running time of 'scrypt'.+--+data ScryptParams = Params { logN, r, p, bufLen :: Integer}++-- |Constructor function for the 'ScryptParams' data type+params :: Integer+ -- ^ @log_2(N)@. Scrypt's @N@ parameter must be a power of two greater+ -- than one, thus it's logarithm to base two must be greater than zero. + -> Integer+ -- ^ The parameter @r@, an integer greater than zero.+ -> Integer+ -- ^ The parameter @p@, an integer greater than zero. @r@ and @p@+ -- must satisfy @r * p < 2^30@.+ -> Maybe ScryptParams+ -- ^ Returns 'Just' the parameter object for valid arguments,+ -- otherwise 'Nothing'.+params logN r p | valid = Just ps+ | otherwise = Nothing+ where+ ps = Params { logN, r, p, bufLen = 64 }+ valid = and [ logN > 0, r > 0, p > 0+ , r*p < 2^(30 :: Int)+ , bufLen ps <= 2^(32 :: Int)-1 * 32+ ]++-- |Default parameters as recommended in the scrypt paper:+--+-- @ N = 2^14, r = 8, p = 1 @+--+-- Equivalent to @'fromJust' ('params' 14 8 1)@.+defaultParams :: ScryptParams+defaultParams = fromJust (params 14 8 1)++-- |Reads a 32-byte random salt from @\/dev\/urandom@.+getSalt :: IO Salt+getSalt = Salt <$> withBinaryFile "/dev/urandom" ReadMode (flip hGet 32)++-- |Calculates a 64-byte hash from the given password, salt and parameters.+scrypt :: ScryptParams -> Salt -> Pass -> PassHash+scrypt Params{..} (Salt salt) (Pass pass) =+ PassHash <$> unsafePerformIO $+ useAsCStringLen salt $ \(saltPtr, saltLen) ->+ useAsCStringLen pass $ \(passPtr, passLen) ->+ allocaBytes (fromIntegral bufLen) $ \bufPtr -> do+ throwErrnoIfMinus1_ "c_scrypt" $ c_scrypt+ (castPtr passPtr) (fromIntegral passLen)+ (castPtr saltPtr) (fromIntegral saltLen)+ (2^logN) (fromIntegral r) (fromIntegral p)+ bufPtr (fromIntegral bufLen)+ packCStringLen (castPtr bufPtr, fromIntegral bufLen)++foreign import ccall unsafe "crypto_scrypt" c_scrypt+ :: Ptr Word8 -> CSize+ -> Ptr Word8 -> CSize+ -> Word64 -> Word32 -> Word32 -- N, r, p+ -> Ptr Word8 -> CSize+ -> IO CInt
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c)2011, Falko Peters++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * 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.++ * Neither the name of Falko Peters nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT+OWNER 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.
+ README.markdown view
@@ -0,0 +1,19 @@+# Welcome to scrypt++This is a Haskell library providing bindings to [Colin Percival's `scrypt` implementation](http://www.tarsnap.com/scrypt.html). Scrypt is a key derivation function designed to be far more secure against hardware brute-force attacks than alternative functions such as PBKDF2 or bcrypt.++Details of the scrypt key derivation function are given in a paper by Colin Percival, Stronger Key Derivation via Sequential Memory-Hard Functions: [PDF](http://www.tarsnap.com/scrypt/scrypt-slides.pdf).++# Join in!++We are happy to receive bug reports, fixes, documentation enhancements, and other improvements.++Please report bugs via the [github issue tracker](http://github.com/informatikr/scrypt/issues).++Master [git repository](http://github.com/informatikr/scrypt):++ git clone git://github.com/informatikr/scrypt.git++# Authors++This library is written and maintained by Falko Peters, <falko.peters@gmail.com>.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ cbits/crypto_scrypt-sse.c view
@@ -0,0 +1,364 @@+/*-+ * Copyright 2009 Colin Percival+ * 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.+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.+ *+ * This file was originally written by Colin Percival as part of the Tarsnap+ * online backup system.+ */+#include <sys/types.h>+#include <sys/mman.h>++#include <emmintrin.h>+#include <errno.h>+#include <stdint.h>+#include <stdlib.h>+#include <string.h>++#include "sha256.h"+#include "sysendian.h"++#include "crypto_scrypt.h"++static void blkcpy(void *, void *, size_t);+static void blkxor(void *, void *, size_t);+static void salsa20_8(__m128i *);+static void blockmix_salsa8(__m128i *, __m128i *, __m128i *, size_t);+static uint64_t integerify(void *, size_t);+static void smix(uint8_t *, size_t, uint64_t, void *, void *);++static void+blkcpy(void * dest, void * src, size_t len)+{+ __m128i * D = dest;+ __m128i * S = src;+ size_t L = len / 16;+ size_t i;++ for (i = 0; i < L; i++)+ D[i] = S[i];+}++static void+blkxor(void * dest, void * src, size_t len)+{+ __m128i * D = dest;+ __m128i * S = src;+ size_t L = len / 16;+ size_t i;++ for (i = 0; i < L; i++)+ D[i] = _mm_xor_si128(D[i], S[i]);+}++/**+ * salsa20_8(B):+ * Apply the salsa20/8 core to the provided block.+ */+static void+salsa20_8(__m128i B[4])+{+ __m128i X0, X1, X2, X3;+ __m128i T;+ size_t i;++ X0 = B[0];+ X1 = B[1];+ X2 = B[2];+ X3 = B[3];++ for (i = 0; i < 8; i += 2) {+ /* Operate on "columns". */+ T = _mm_add_epi32(X0, X3);+ X1 = _mm_xor_si128(X1, _mm_slli_epi32(T, 7));+ X1 = _mm_xor_si128(X1, _mm_srli_epi32(T, 25));+ T = _mm_add_epi32(X1, X0);+ X2 = _mm_xor_si128(X2, _mm_slli_epi32(T, 9));+ X2 = _mm_xor_si128(X2, _mm_srli_epi32(T, 23));+ T = _mm_add_epi32(X2, X1);+ X3 = _mm_xor_si128(X3, _mm_slli_epi32(T, 13));+ X3 = _mm_xor_si128(X3, _mm_srli_epi32(T, 19));+ T = _mm_add_epi32(X3, X2);+ X0 = _mm_xor_si128(X0, _mm_slli_epi32(T, 18));+ X0 = _mm_xor_si128(X0, _mm_srli_epi32(T, 14));++ /* Rearrange data. */+ X1 = _mm_shuffle_epi32(X1, 0x93);+ X2 = _mm_shuffle_epi32(X2, 0x4E);+ X3 = _mm_shuffle_epi32(X3, 0x39);++ /* Operate on "rows". */+ T = _mm_add_epi32(X0, X1);+ X3 = _mm_xor_si128(X3, _mm_slli_epi32(T, 7));+ X3 = _mm_xor_si128(X3, _mm_srli_epi32(T, 25));+ T = _mm_add_epi32(X3, X0);+ X2 = _mm_xor_si128(X2, _mm_slli_epi32(T, 9));+ X2 = _mm_xor_si128(X2, _mm_srli_epi32(T, 23));+ T = _mm_add_epi32(X2, X3);+ X1 = _mm_xor_si128(X1, _mm_slli_epi32(T, 13));+ X1 = _mm_xor_si128(X1, _mm_srli_epi32(T, 19));+ T = _mm_add_epi32(X1, X2);+ X0 = _mm_xor_si128(X0, _mm_slli_epi32(T, 18));+ X0 = _mm_xor_si128(X0, _mm_srli_epi32(T, 14));++ /* Rearrange data. */+ X1 = _mm_shuffle_epi32(X1, 0x39);+ X2 = _mm_shuffle_epi32(X2, 0x4E);+ X3 = _mm_shuffle_epi32(X3, 0x93);+ }++ B[0] = _mm_add_epi32(B[0], X0);+ B[1] = _mm_add_epi32(B[1], X1);+ B[2] = _mm_add_epi32(B[2], X2);+ B[3] = _mm_add_epi32(B[3], X3);+}++/**+ * blockmix_salsa8(Bin, Bout, X, r):+ * Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r+ * bytes in length; the output Bout must also be the same size. The+ * temporary space X must be 64 bytes.+ */+static void+blockmix_salsa8(__m128i * Bin, __m128i * Bout, __m128i * X, size_t r)+{+ size_t i;++ /* 1: X <-- B_{2r - 1} */+ blkcpy(X, &Bin[8 * r - 4], 64);++ /* 2: for i = 0 to 2r - 1 do */+ for (i = 0; i < r; i++) {+ /* 3: X <-- H(X \xor B_i) */+ blkxor(X, &Bin[i * 8], 64);+ salsa20_8(X);++ /* 4: Y_i <-- X */+ /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */+ blkcpy(&Bout[i * 4], X, 64);++ /* 3: X <-- H(X \xor B_i) */+ blkxor(X, &Bin[i * 8 + 4], 64);+ salsa20_8(X);++ /* 4: Y_i <-- X */+ /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */+ blkcpy(&Bout[(r + i) * 4], X, 64);+ }+}++/**+ * integerify(B, r):+ * Return the result of parsing B_{2r-1} as a little-endian integer.+ */+static uint64_t+integerify(void * B, size_t r)+{+ uint32_t * X = (void *)((uintptr_t)(B) + (2 * r - 1) * 64);++ return (((uint64_t)(X[13]) << 32) + X[0]);+}++/**+ * smix(B, r, N, V, XY):+ * Compute B = SMix_r(B, N). The input B must be 128r bytes in length;+ * the temporary storage V must be 128rN bytes in length; the temporary+ * storage XY must be 256r + 64 bytes in length. The value N must be a+ * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a+ * multiple of 64 bytes.+ */+static void+smix(uint8_t * B, size_t r, uint64_t N, void * V, void * XY)+{+ __m128i * X = XY;+ __m128i * Y = (void *)((uintptr_t)(XY) + 128 * r);+ __m128i * Z = (void *)((uintptr_t)(XY) + 256 * r);+ uint32_t * X32 = (void *)X;+ uint64_t i, j;+ size_t k;++ /* 1: X <-- B */+ for (k = 0; k < 2 * r; k++) {+ for (i = 0; i < 16; i++) {+ X32[k * 16 + i] =+ le32dec(&B[(k * 16 + (i * 5 % 16)) * 4]);+ }+ }++ /* 2: for i = 0 to N - 1 do */+ for (i = 0; i < N; i += 2) {+ /* 3: V_i <-- X */+ blkcpy((void *)((uintptr_t)(V) + i * 128 * r), X, 128 * r);++ /* 4: X <-- H(X) */+ blockmix_salsa8(X, Y, Z, r);++ /* 3: V_i <-- X */+ blkcpy((void *)((uintptr_t)(V) + (i + 1) * 128 * r),+ Y, 128 * r);++ /* 4: X <-- H(X) */+ blockmix_salsa8(Y, X, Z, r);+ }++ /* 6: for i = 0 to N - 1 do */+ for (i = 0; i < N; i += 2) {+ /* 7: j <-- Integerify(X) mod N */+ j = integerify(X, r) & (N - 1);++ /* 8: X <-- H(X \xor V_j) */+ blkxor(X, (void *)((uintptr_t)(V) + j * 128 * r), 128 * r);+ blockmix_salsa8(X, Y, Z, r);++ /* 7: j <-- Integerify(X) mod N */+ j = integerify(Y, r) & (N - 1);++ /* 8: X <-- H(X \xor V_j) */+ blkxor(Y, (void *)((uintptr_t)(V) + j * 128 * r), 128 * r);+ blockmix_salsa8(Y, X, Z, r);+ }++ /* 10: B' <-- X */+ for (k = 0; k < 2 * r; k++) {+ for (i = 0; i < 16; i++) {+ le32enc(&B[(k * 16 + (i * 5 % 16)) * 4],+ X32[k * 16 + i]);+ }+ }+}++/**+ * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):+ * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,+ * p, buflen) and write the result into buf. The parameters r, p, and buflen+ * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N+ * must be a power of 2 greater than 1.+ *+ * Return 0 on success; or -1 on error.+ */+int+crypto_scrypt(const uint8_t * passwd, size_t passwdlen,+ const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p,+ uint8_t * buf, size_t buflen)+{+ void * B0, * V0, * XY0;+ uint8_t * B;+ uint32_t * V;+ uint32_t * XY;+ uint32_t i;++ /* Sanity-check parameters. */+#if SIZE_MAX > UINT32_MAX+ if (buflen > (((uint64_t)(1) << 32) - 1) * 32) {+ errno = EFBIG;+ goto err0;+ }+#endif+ if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) {+ errno = EFBIG;+ goto err0;+ }+ if (((N & (N - 1)) != 0) || (N == 0)) {+ errno = EINVAL;+ goto err0;+ }+ if ((r > SIZE_MAX / 128 / p) ||+#if SIZE_MAX / 256 <= UINT32_MAX+ (r > (SIZE_MAX - 64) / 256) ||+#endif+ (N > SIZE_MAX / 128 / r)) {+ errno = ENOMEM;+ goto err0;+ }++ /* Allocate memory. */+#ifdef HAVE_POSIX_MEMALIGN+ if ((errno = posix_memalign(&B0, 64, 128 * r * p)) != 0)+ goto err0;+ B = (uint8_t *)(B0);+ if ((errno = posix_memalign(&XY0, 64, 256 * r + 64)) != 0)+ goto err1;+ XY = (uint32_t *)(XY0);+#ifndef MAP_ANON+ if ((errno = posix_memalign(&V0, 64, 128 * r * N)) != 0)+ goto err2;+ V = (uint32_t *)(V0);+#endif+#else+ if ((B0 = malloc(128 * r * p + 63)) == NULL)+ goto err0;+ B = (uint8_t *)(((uintptr_t)(B0) + 63) & ~ (uintptr_t)(63));+ if ((XY0 = malloc(256 * r + 64 + 63)) == NULL)+ goto err1;+ XY = (uint32_t *)(((uintptr_t)(XY0) + 63) & ~ (uintptr_t)(63));+#ifndef MAP_ANON+ if ((V0 = malloc(128 * r * N + 63)) == NULL)+ goto err2;+ V = (uint32_t *)(((uintptr_t)(V0) + 63) & ~ (uintptr_t)(63));+#endif+#endif+#ifdef MAP_ANON+ if ((V0 = mmap(NULL, 128 * r * N, PROT_READ | PROT_WRITE,+#ifdef MAP_NOCORE+ MAP_ANON | MAP_PRIVATE | MAP_NOCORE,+#else+ MAP_ANON | MAP_PRIVATE,+#endif+ -1, 0)) == MAP_FAILED)+ goto err2;+ V = (uint32_t *)(V0);+#endif++ /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */+ PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r);++ /* 2: for i = 0 to p - 1 do */+ for (i = 0; i < p; i++) {+ /* 3: B_i <-- MF(B_i, N) */+ smix(&B[i * 128 * r], r, N, V, XY);+ }++ /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */+ PBKDF2_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen);++ /* Free memory. */+#ifdef MAP_ANON+ if (munmap(V0, 128 * r * N))+ goto err2;+#else+ free(V0);+#endif+ free(XY0);+ free(B0);++ /* Success! */+ return (0);++err2:+ free(XY0);+err1:+ free(B0);+err0:+ /* Failure! */+ return (-1);+}
+ cbits/crypto_scrypt.h view
@@ -0,0 +1,46 @@+/*-+ * Copyright 2009 Colin Percival+ * 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.+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.+ *+ * This file was originally written by Colin Percival as part of the Tarsnap+ * online backup system.+ */+#ifndef _CRYPTO_SCRYPT_H_+#define _CRYPTO_SCRYPT_H_++#include <stdint.h>+#include <stddef.h>+/**+ * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):+ * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,+ * p, buflen) and write the result into buf. The parameters r, p, and buflen+ * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N+ * must be a power of 2 greater than 1.+ *+ * Return 0 on success; or -1 on error.+ */+int crypto_scrypt(const uint8_t *, size_t, const uint8_t *, size_t, uint64_t,+ uint32_t, uint32_t, uint8_t *, size_t);++#endif /* !_CRYPTO_SCRYPT_H_ */
+ cbits/sha256.c view
@@ -0,0 +1,410 @@+/*-+ * Copyright 2005,2007,2009 Colin Percival+ * 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.+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.+ */+#include <sys/types.h>++#include <stdint.h>+#include <string.h>++#include "sysendian.h"++#include "sha256.h"++/*+ * Encode a length len/4 vector of (uint32_t) into a length len vector of+ * (unsigned char) in big-endian form. Assumes len is a multiple of 4.+ */+static void+be32enc_vect(unsigned char *dst, const uint32_t *src, size_t len)+{+ size_t i;++ for (i = 0; i < len / 4; i++)+ be32enc(dst + i * 4, src[i]);+}++/*+ * Decode a big-endian length len vector of (unsigned char) into a length+ * len/4 vector of (uint32_t). Assumes len is a multiple of 4.+ */+static void+be32dec_vect(uint32_t *dst, const unsigned char *src, size_t len)+{+ size_t i;++ for (i = 0; i < len / 4; i++)+ dst[i] = be32dec(src + i * 4);+}++/* Elementary functions used by SHA256 */+#define Ch(x, y, z) ((x & (y ^ z)) ^ z)+#define Maj(x, y, z) ((x & (y | z)) | (y & z))+#define SHR(x, n) (x >> n)+#define ROTR(x, n) ((x >> n) | (x << (32 - n)))+#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))+#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))+#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))+#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))++/* SHA256 round function */+#define RND(a, b, c, d, e, f, g, h, k) \+ t0 = h + S1(e) + Ch(e, f, g) + k; \+ t1 = S0(a) + Maj(a, b, c); \+ d += t0; \+ h = t0 + t1;++/* Adjusted round function for rotating state */+#define RNDr(S, W, i, k) \+ RND(S[(64 - i) % 8], S[(65 - i) % 8], \+ S[(66 - i) % 8], S[(67 - i) % 8], \+ S[(68 - i) % 8], S[(69 - i) % 8], \+ S[(70 - i) % 8], S[(71 - i) % 8], \+ W[i] + k)++/*+ * SHA256 block compression function. The 256-bit state is transformed via+ * the 512-bit input block to produce a new state.+ */+static void+SHA256_Transform(uint32_t * state, const unsigned char block[64])+{+ uint32_t W[64];+ uint32_t S[8];+ uint32_t t0, t1;+ int i;++ /* 1. Prepare message schedule W. */+ be32dec_vect(W, block, 64);+ for (i = 16; i < 64; i++)+ W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];++ /* 2. Initialize working variables. */+ memcpy(S, state, 32);++ /* 3. Mix. */+ RNDr(S, W, 0, 0x428a2f98);+ RNDr(S, W, 1, 0x71374491);+ RNDr(S, W, 2, 0xb5c0fbcf);+ RNDr(S, W, 3, 0xe9b5dba5);+ RNDr(S, W, 4, 0x3956c25b);+ RNDr(S, W, 5, 0x59f111f1);+ RNDr(S, W, 6, 0x923f82a4);+ RNDr(S, W, 7, 0xab1c5ed5);+ RNDr(S, W, 8, 0xd807aa98);+ RNDr(S, W, 9, 0x12835b01);+ RNDr(S, W, 10, 0x243185be);+ RNDr(S, W, 11, 0x550c7dc3);+ RNDr(S, W, 12, 0x72be5d74);+ RNDr(S, W, 13, 0x80deb1fe);+ RNDr(S, W, 14, 0x9bdc06a7);+ RNDr(S, W, 15, 0xc19bf174);+ RNDr(S, W, 16, 0xe49b69c1);+ RNDr(S, W, 17, 0xefbe4786);+ RNDr(S, W, 18, 0x0fc19dc6);+ RNDr(S, W, 19, 0x240ca1cc);+ RNDr(S, W, 20, 0x2de92c6f);+ RNDr(S, W, 21, 0x4a7484aa);+ RNDr(S, W, 22, 0x5cb0a9dc);+ RNDr(S, W, 23, 0x76f988da);+ RNDr(S, W, 24, 0x983e5152);+ RNDr(S, W, 25, 0xa831c66d);+ RNDr(S, W, 26, 0xb00327c8);+ RNDr(S, W, 27, 0xbf597fc7);+ RNDr(S, W, 28, 0xc6e00bf3);+ RNDr(S, W, 29, 0xd5a79147);+ RNDr(S, W, 30, 0x06ca6351);+ RNDr(S, W, 31, 0x14292967);+ RNDr(S, W, 32, 0x27b70a85);+ RNDr(S, W, 33, 0x2e1b2138);+ RNDr(S, W, 34, 0x4d2c6dfc);+ RNDr(S, W, 35, 0x53380d13);+ RNDr(S, W, 36, 0x650a7354);+ RNDr(S, W, 37, 0x766a0abb);+ RNDr(S, W, 38, 0x81c2c92e);+ RNDr(S, W, 39, 0x92722c85);+ RNDr(S, W, 40, 0xa2bfe8a1);+ RNDr(S, W, 41, 0xa81a664b);+ RNDr(S, W, 42, 0xc24b8b70);+ RNDr(S, W, 43, 0xc76c51a3);+ RNDr(S, W, 44, 0xd192e819);+ RNDr(S, W, 45, 0xd6990624);+ RNDr(S, W, 46, 0xf40e3585);+ RNDr(S, W, 47, 0x106aa070);+ RNDr(S, W, 48, 0x19a4c116);+ RNDr(S, W, 49, 0x1e376c08);+ RNDr(S, W, 50, 0x2748774c);+ RNDr(S, W, 51, 0x34b0bcb5);+ RNDr(S, W, 52, 0x391c0cb3);+ RNDr(S, W, 53, 0x4ed8aa4a);+ RNDr(S, W, 54, 0x5b9cca4f);+ RNDr(S, W, 55, 0x682e6ff3);+ RNDr(S, W, 56, 0x748f82ee);+ RNDr(S, W, 57, 0x78a5636f);+ RNDr(S, W, 58, 0x84c87814);+ RNDr(S, W, 59, 0x8cc70208);+ RNDr(S, W, 60, 0x90befffa);+ RNDr(S, W, 61, 0xa4506ceb);+ RNDr(S, W, 62, 0xbef9a3f7);+ RNDr(S, W, 63, 0xc67178f2);++ /* 4. Mix local working variables into global state */+ for (i = 0; i < 8; i++)+ state[i] += S[i];++ /* Clean the stack. */+ memset(W, 0, 256);+ memset(S, 0, 32);+ t0 = t1 = 0;+}++static unsigned char PAD[64] = {+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0+};++/* Add padding and terminating bit-count. */+static void+SHA256_Pad(SHA256_CTX * ctx)+{+ unsigned char len[8];+ uint32_t r, plen;++ /*+ * Convert length to a vector of bytes -- we do this now rather+ * than later because the length will change after we pad.+ */+ be32enc_vect(len, ctx->count, 8);++ /* Add 1--64 bytes so that the resulting length is 56 mod 64 */+ r = (ctx->count[1] >> 3) & 0x3f;+ plen = (r < 56) ? (56 - r) : (120 - r);+ SHA256_Update(ctx, PAD, (size_t)plen);++ /* Add the terminating bit-count */+ SHA256_Update(ctx, len, 8);+}++/* SHA-256 initialization. Begins a SHA-256 operation. */+void+SHA256_Init(SHA256_CTX * ctx)+{++ /* Zero bits processed so far */+ ctx->count[0] = ctx->count[1] = 0;++ /* Magic initialization constants */+ ctx->state[0] = 0x6A09E667;+ ctx->state[1] = 0xBB67AE85;+ ctx->state[2] = 0x3C6EF372;+ ctx->state[3] = 0xA54FF53A;+ ctx->state[4] = 0x510E527F;+ ctx->state[5] = 0x9B05688C;+ ctx->state[6] = 0x1F83D9AB;+ ctx->state[7] = 0x5BE0CD19;+}++/* Add bytes into the hash */+void+SHA256_Update(SHA256_CTX * ctx, const void *in, size_t len)+{+ uint32_t bitlen[2];+ uint32_t r;+ const unsigned char *src = in;++ /* Number of bytes left in the buffer from previous updates */+ r = (ctx->count[1] >> 3) & 0x3f;++ /* Convert the length into a number of bits */+ bitlen[1] = ((uint32_t)len) << 3;+ bitlen[0] = (uint32_t)(len >> 29);++ /* Update number of bits */+ if ((ctx->count[1] += bitlen[1]) < bitlen[1])+ ctx->count[0]++;+ ctx->count[0] += bitlen[0];++ /* Handle the case where we don't need to perform any transforms */+ if (len < 64 - r) {+ memcpy(&ctx->buf[r], src, len);+ return;+ }++ /* Finish the current block */+ memcpy(&ctx->buf[r], src, 64 - r);+ SHA256_Transform(ctx->state, ctx->buf);+ src += 64 - r;+ len -= 64 - r;++ /* Perform complete blocks */+ while (len >= 64) {+ SHA256_Transform(ctx->state, src);+ src += 64;+ len -= 64;+ }++ /* Copy left over data into buffer */+ memcpy(ctx->buf, src, len);+}++/*+ * SHA-256 finalization. Pads the input data, exports the hash value,+ * and clears the context state.+ */+void+SHA256_Final(unsigned char digest[32], SHA256_CTX * ctx)+{++ /* Add padding */+ SHA256_Pad(ctx);++ /* Write the hash */+ be32enc_vect(digest, ctx->state, 32);++ /* Clear the context state */+ memset((void *)ctx, 0, sizeof(*ctx));+}++/* Initialize an HMAC-SHA256 operation with the given key. */+void+HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen)+{+ unsigned char pad[64];+ unsigned char khash[32];+ const unsigned char * K = _K;+ size_t i;++ /* If Klen > 64, the key is really SHA256(K). */+ if (Klen > 64) {+ SHA256_Init(&ctx->ictx);+ SHA256_Update(&ctx->ictx, K, Klen);+ SHA256_Final(khash, &ctx->ictx);+ K = khash;+ Klen = 32;+ }++ /* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */+ SHA256_Init(&ctx->ictx);+ memset(pad, 0x36, 64);+ for (i = 0; i < Klen; i++)+ pad[i] ^= K[i];+ SHA256_Update(&ctx->ictx, pad, 64);++ /* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */+ SHA256_Init(&ctx->octx);+ memset(pad, 0x5c, 64);+ for (i = 0; i < Klen; i++)+ pad[i] ^= K[i];+ SHA256_Update(&ctx->octx, pad, 64);++ /* Clean the stack. */+ memset(khash, 0, 32);+}++/* Add bytes to the HMAC-SHA256 operation. */+void+HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void *in, size_t len)+{++ /* Feed data to the inner SHA256 operation. */+ SHA256_Update(&ctx->ictx, in, len);+}++/* Finish an HMAC-SHA256 operation. */+void+HMAC_SHA256_Final(unsigned char digest[32], HMAC_SHA256_CTX * ctx)+{+ unsigned char ihash[32];++ /* Finish the inner SHA256 operation. */+ SHA256_Final(ihash, &ctx->ictx);++ /* Feed the inner hash to the outer SHA256 operation. */+ SHA256_Update(&ctx->octx, ihash, 32);++ /* Finish the outer SHA256 operation. */+ SHA256_Final(digest, &ctx->octx);++ /* Clean the stack. */+ memset(ihash, 0, 32);+}++/**+ * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):+ * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and+ * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).+ */+void+PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,+ size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen)+{+ HMAC_SHA256_CTX PShctx, hctx;+ size_t i;+ uint8_t ivec[4];+ uint8_t U[32];+ uint8_t T[32];+ uint64_t j;+ int k;+ size_t clen;++ /* Compute HMAC state after processing P and S. */+ HMAC_SHA256_Init(&PShctx, passwd, passwdlen);+ HMAC_SHA256_Update(&PShctx, salt, saltlen);++ /* Iterate through the blocks. */+ for (i = 0; i * 32 < dkLen; i++) {+ /* Generate INT(i + 1). */+ be32enc(ivec, (uint32_t)(i + 1));++ /* Compute U_1 = PRF(P, S || INT(i)). */+ memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX));+ HMAC_SHA256_Update(&hctx, ivec, 4);+ HMAC_SHA256_Final(U, &hctx);++ /* T_i = U_1 ... */+ memcpy(T, U, 32);++ for (j = 2; j <= c; j++) {+ /* Compute U_j. */+ HMAC_SHA256_Init(&hctx, passwd, passwdlen);+ HMAC_SHA256_Update(&hctx, U, 32);+ HMAC_SHA256_Final(U, &hctx);++ /* ... xor U_j ... */+ for (k = 0; k < 32; k++)+ T[k] ^= U[k];+ }++ /* Copy as many bytes as necessary into buf. */+ clen = dkLen - i * 32;+ if (clen > 32)+ clen = 32;+ memcpy(&buf[i * 32], T, clen);+ }++ /* Clean PShctx, since we never called _Final on it. */+ memset(&PShctx, 0, sizeof(HMAC_SHA256_CTX));+}
+ cbits/sha256.h view
@@ -0,0 +1,62 @@+/*-+ * Copyright 2005,2007,2009 Colin Percival+ * 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.+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.+ *+ * $FreeBSD: src/lib/libmd/sha256.h,v 1.2 2006/01/17 15:35:56 phk Exp $+ */++#ifndef _SHA256_H_+#define _SHA256_H_++#include <sys/types.h>++#include <stdint.h>++typedef struct SHA256Context {+ uint32_t state[8];+ uint32_t count[2];+ unsigned char buf[64];+} SHA256_CTX;++typedef struct HMAC_SHA256Context {+ SHA256_CTX ictx;+ SHA256_CTX octx;+} HMAC_SHA256_CTX;++void SHA256_Init(SHA256_CTX *);+void SHA256_Update(SHA256_CTX *, const void *, size_t);+void SHA256_Final(unsigned char [32], SHA256_CTX *);+void HMAC_SHA256_Init(HMAC_SHA256_CTX *, const void *, size_t);+void HMAC_SHA256_Update(HMAC_SHA256_CTX *, const void *, size_t);+void HMAC_SHA256_Final(unsigned char [32], HMAC_SHA256_CTX *);++/**+ * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):+ * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and+ * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).+ */+void PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t,+ uint64_t, uint8_t *, size_t);++#endif /* !_SHA256_H_ */
+ cbits/sysendian.h view
@@ -0,0 +1,138 @@+/*-+ * Copyright 2007-2009 Colin Percival+ * 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.+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.+ *+ * This file was originally written by Colin Percival as part of the Tarsnap+ * online backup system.+ */+#ifndef _SYSENDIAN_H_+#define _SYSENDIAN_H_++/* If we don't have be64enc, the <sys/endian.h> we have isn't usable. */+#if !HAVE_DECL_BE64ENC+#undef HAVE_SYS_ENDIAN_H+#endif++#ifdef HAVE_SYS_ENDIAN_H++#include <sys/endian.h>++#else++#include <stdint.h>++static inline uint32_t+be32dec(const void *pp)+{+ const uint8_t *p = (uint8_t const *)pp;++ return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) ++ ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24));+}++static inline void+be32enc(void *pp, uint32_t x)+{+ uint8_t * p = (uint8_t *)pp;++ p[3] = x & 0xff;+ p[2] = (x >> 8) & 0xff;+ p[1] = (x >> 16) & 0xff;+ p[0] = (x >> 24) & 0xff;+}++static inline uint64_t+be64dec(const void *pp)+{+ const uint8_t *p = (uint8_t const *)pp;++ return ((uint64_t)(p[7]) + ((uint64_t)(p[6]) << 8) ++ ((uint64_t)(p[5]) << 16) + ((uint64_t)(p[4]) << 24) ++ ((uint64_t)(p[3]) << 32) + ((uint64_t)(p[2]) << 40) ++ ((uint64_t)(p[1]) << 48) + ((uint64_t)(p[0]) << 56));+}++static inline void+be64enc(void *pp, uint64_t x)+{+ uint8_t * p = (uint8_t *)pp;++ p[7] = x & 0xff;+ p[6] = (x >> 8) & 0xff;+ p[5] = (x >> 16) & 0xff;+ p[4] = (x >> 24) & 0xff;+ p[3] = (x >> 32) & 0xff;+ p[2] = (x >> 40) & 0xff;+ p[1] = (x >> 48) & 0xff;+ p[0] = (x >> 56) & 0xff;+}++static inline uint32_t+le32dec(const void *pp)+{+ const uint8_t *p = (uint8_t const *)pp;++ return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) ++ ((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24));+}++static inline void+le32enc(void *pp, uint32_t x)+{+ uint8_t * p = (uint8_t *)pp;++ p[0] = x & 0xff;+ p[1] = (x >> 8) & 0xff;+ p[2] = (x >> 16) & 0xff;+ p[3] = (x >> 24) & 0xff;+}++static inline uint64_t+le64dec(const void *pp)+{+ const uint8_t *p = (uint8_t const *)pp;++ return ((uint64_t)(p[0]) + ((uint64_t)(p[1]) << 8) ++ ((uint64_t)(p[2]) << 16) + ((uint64_t)(p[3]) << 24) ++ ((uint64_t)(p[4]) << 32) + ((uint64_t)(p[5]) << 40) ++ ((uint64_t)(p[6]) << 48) + ((uint64_t)(p[7]) << 56));+}++static inline void+le64enc(void *pp, uint64_t x)+{+ uint8_t * p = (uint8_t *)pp;++ p[0] = x & 0xff;+ p[1] = (x >> 8) & 0xff;+ p[2] = (x >> 16) & 0xff;+ p[3] = (x >> 24) & 0xff;+ p[4] = (x >> 32) & 0xff;+ p[5] = (x >> 40) & 0xff;+ p[6] = (x >> 48) & 0xff;+ p[7] = (x >> 56) & 0xff;+}+#endif /* !HAVE_SYS_ENDIAN_H */++#endif /* !_SYSENDIAN_H_ */
+ scrypt.cabal view
@@ -0,0 +1,51 @@+name: scrypt+version: 0.1+license: BSD3+license-file: LICENSE+category: Cryptography+copyright: Copyright 2011 Falko Peters+author: Falko Peters <falko.peters@gmail.com>+maintainer: Falko Peters <falko.peters@gmail.com>+stability: experimental+tested-with: GHC == 6.12.3+cabal-version: >= 1.8+homepage: http://github.com/informatikr/scrypt+bug-reports: http://github.com/informatikr/scrypt/issues+build-type: Simple+synopsis:+ Stronger password hashing via sequential memory-hard functions.+description:+ scrypt provides bindings to Colin Percival's `scrypt` + implementation (<http://www.tarsnap.com/scrypt.html>). Scrypt is a key+ derivation function designed to be far more secure against hardware+ brute-force attacks than alternative functions such as PBKDF2 or bcrypt.+ .+ Details of the scrypt key derivation function are given in a paper by+ Colin Percival, Stronger Key Derivation via Sequential Memory-Hard+ Functions (<http://www.tarsnap.com/scrypt/scrypt-slides.pdf>).++extra-source-files:+ README.markdown,+ cbits/crypto_scrypt.h,+ cbits/sha256.h,+ cbits/sysendian.h++library+ exposed-modules: Crypto.Scrypt++ build-depends:+ base == 4.*,+ bytestring == 0.9.*++ ghc-options: -Wall+ ghc-prof-options: -auto-all++ c-sources: cbits/crypto_scrypt-sse.c, cbits/sha256.c+ cc-options: -msse2+ include-dirs: cbits+ includes: crypto_scrypt.h+ install-includes: crypto_scrypt.h+ +source-repository head+ type: git+ location: http://github.com/informatikr/scrypt