Hello community,
here is the log from the commit of package ghc-cryptohash-sha256 for
openSUSE:Factory checked in at 2018-05-30 12:05:43
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-cryptohash-sha256 (Old)
and /work/SRC/openSUSE:Factory/.ghc-cryptohash-sha256.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ghc-cryptohash-sha256"
Wed May 30 12:05:43 2018 rev:5 rq:607776 version:0.11.101.0
Changes:
--------
---
/work/SRC/openSUSE:Factory/ghc-cryptohash-sha256/ghc-cryptohash-sha256.changes
2017-09-15 21:29:45.963752062 +0200
+++
/work/SRC/openSUSE:Factory/.ghc-cryptohash-sha256.new/ghc-cryptohash-sha256.changes
2018-05-30 12:25:19.198301076 +0200
@@ -1,0 +2,14 @@
+Mon May 14 17:02:11 UTC 2018 - [email protected]
+
+- Update cryptohash-sha256 to version 0.11.101.0 revision 1.
+ - Add `hkdf` function providing HKDF-SHA256 conforming to RFC5869
+ - Declare `Crypto.Hash.SHA256` module `-XTrustworthy`
+ - Remove ineffective RULES
+ - Convert to `CApiFFI`
+ - Added `...AndLength` variants of hashing functions:
+ - `finalizeAndLength`
+ - `hashlazyAndLength`
+ - `hmaclazyAndLength`
+ - Minor optimizations in `hmac` and `hash`
+
+-------------------------------------------------------------------
Old:
----
cryptohash-sha256-0.11.100.1.tar.gz
New:
----
cryptohash-sha256-0.11.101.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ ghc-cryptohash-sha256.spec ++++++
--- /var/tmp/diff_new_pack.e7ZlNX/_old 2018-05-30 12:25:19.762282617 +0200
+++ /var/tmp/diff_new_pack.e7ZlNX/_new 2018-05-30 12:25:19.762282617 +0200
@@ -1,7 +1,7 @@
#
# spec file for package ghc-cryptohash-sha256
#
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
%global pkg_name cryptohash-sha256
%bcond_with tests
Name: ghc-%{pkg_name}
-Version: 0.11.100.1
+Version: 0.11.101.0
Release: 0
Summary: Fast, pure and practical SHA-256 implementation
License: BSD-3-Clause
@@ -39,22 +39,44 @@
%endif
%description
-A practical incremental and one-pass, pure API to the
-<https://en.wikipedia.org/wiki/SHA-2 SHA-256 hash algorithm> (including
-<https://en.wikipedia.org/wiki/HMAC HMAC> support) with performance close to
-the fastest implementations available in other languages.
-
-The implementation is made in C with a haskell FFI wrapper that hides the C
-implementation.
-
-NOTE: This package has been forked off 'cryptohash-0.11.7' because the
-'cryptohash' package has been deprecated and so this package continues to
-satisfy the need for a lightweight package providing the SHA256 hash algorithm
+A practical incremental and one-pass, pure API to the [SHA-256 cryptographic
+hash algorithm](https://en.wikipedia.org/wiki/SHA-2) according to [FIPS
+180-4](http://dx.doi.org/10.6028/NIST.FIPS.180-4) with performance close to the
+fastest implementations available in other languages.
+
+The core SHA-256 algorithm is implemented in C and is thus expected to be as
+fast as the standard [sha256sum(1)
+tool](https://linux.die.net/man/1/sha256sum); for instance, on an /Intel Core
+i7-3770/ at 3.40GHz this implementation can compute a SHA-256 hash over 230 MiB
+of data in under one second. (If, instead, you require a pure Haskell
+implementation and performance is secondary, please refer to the [SHA
+package](https://hackage.haskell.org/package/SHA).)
+
+Additionally, this package provides support for
+
+- HMAC-SHA-256: SHA-256-based [Hashed Message Authentication
+Codes](https://en.wikipedia.org/wiki/HMAC) (HMAC) - HKDF-SHA-256:
+[HMAC-SHA-256-based Key Derivation
+Function](https://en.wikipedia.org/wiki/HKDF) (HKDF)
+
+conforming to [RFC6234](https://tools.ietf.org/html/rfc6234),
+[RFC4231](https://tools.ietf.org/html/rfc4231),
+[RFC5869](https://tools.ietf.org/html/rfc5869), et al..
+
+=== Relationship to the 'cryptohash' package and its API
+
+This package has been originally a fork of 'cryptohash-0.11.7' because the
+'cryptohash' package had been deprecated and so this package continues to
+satisfy the need for a lightweight package providing the SHA-256 hash algorithm
without any dependencies on packages other than 'base' and 'bytestring'.
-
-Consequently, this package can be used as a drop-in replacement for
-'cryptohash''s "Crypto.Hash.SHA256" module, though with a clearly smaller
-footprint.
+The API exposed by 'cryptohash-sha256-0.11.*''s "Crypto.Hash.SHA256" module is
+guaranteed to remain a compatible superset of the API provided by the
+'cryptohash-0.11.7''s module of the same name.
+
+Consequently, this package is designed to be used as a drop-in replacement for
+'cryptohash-0.11.7''s "Crypto.Hash.SHA256" module, though with a [clearly
+smaller footprint by almost 3 orders of
+magnitude](https://www.reddit.com/r/haskell/comments/5lxv75/psa_please_use_unique_module_names_when_uploading/dbzegx3/).
%package devel
Summary: Haskell %{pkg_name} library development files
@@ -88,7 +110,7 @@
%ghc_pkg_recache
%files -f %{name}.files
-%doc LICENSE
+%license LICENSE
%files devel -f %{name}-devel.files
%doc changelog.md
++++++ cryptohash-sha256-0.11.100.1.tar.gz ->
cryptohash-sha256-0.11.101.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cryptohash-sha256-0.11.100.1/cbits/hs_sha256.h
new/cryptohash-sha256-0.11.101.0/cbits/hs_sha256.h
--- old/cryptohash-sha256-0.11.100.1/cbits/hs_sha256.h 1970-01-01
01:00:00.000000000 +0100
+++ new/cryptohash-sha256-0.11.101.0/cbits/hs_sha256.h 2017-11-13
09:04:55.000000000 +0100
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2006-2009 Vincent Hanquez <[email protected]>
+ * 2016 Herbert Valerio Riedel <[email protected]>
+ *
+ * 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 HS_CRYPTOHASH_SHA256_H
+#define HS_CRYPTOHASH_SHA256_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <assert.h>
+#include <string.h>
+#include <ghcautoconf.h>
+
+struct sha256_ctx
+{
+ uint64_t sz;
+ uint8_t buf[64];
+ uint32_t h[8];
+};
+
+/* keep this synchronised with 'digestSize'/'sizeCtx' in SHA256.hs */
+#define SHA256_DIGEST_SIZE 32
+#define SHA256_CTX_SIZE 104
+
+static inline void hs_cryptohash_sha256_init (struct sha256_ctx *ctx);
+static inline void hs_cryptohash_sha256_update (struct sha256_ctx *ctx, const
uint8_t *data, size_t len);
+static inline uint64_t hs_cryptohash_sha256_finalize (struct sha256_ctx *ctx,
uint8_t *out);
+
+#if defined(static_assert)
+static_assert(sizeof(struct sha256_ctx) == SHA256_CTX_SIZE, "unexpected
sha256_ctx size");
+#else
+/* poor man's pre-C11 _Static_assert */
+typedef char static_assertion__unexpected_sha256_ctx_size[(sizeof(struct
sha256_ctx) == SHA256_CTX_SIZE)?1:-1];
+#endif
+
+#define ptr_uint32_aligned(ptr) (!((uintptr_t)(ptr) & 0x3))
+
+static inline uint32_t
+ror32(const uint32_t word, const unsigned shift)
+{
+ /* GCC usually transforms this into a 'ror'-insn */
+ return (word >> shift) | (word << (32 - shift));
+}
+
+static inline uint32_t
+cpu_to_be32(const uint32_t hl)
+{
+#if WORDS_BIGENDIAN
+ return hl;
+#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
+ return __builtin_bswap32(hl);
+#else
+ /* GCC usually transforms this into a bswap insn */
+ return ((hl & 0xff000000) >> 24) |
+ ((hl & 0x00ff0000) >> 8) |
+ ((hl & 0x0000ff00) << 8) |
+ ( hl << 24);
+#endif
+}
+
+static inline void
+cpu_to_be32_array(uint32_t *dest, const uint32_t *src, unsigned wordcnt)
+{
+ while (wordcnt--)
+ *dest++ = cpu_to_be32(*src++);
+}
+
+static inline uint64_t
+cpu_to_be64(const uint64_t hll)
+{
+#if WORDS_BIGENDIAN
+ return hll;
+#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
+ return __builtin_bswap64(hll);
+#else
+ return ((uint64_t)cpu_to_be32(hll & 0xffffffff) << 32LL) | cpu_to_be32(hll
>> 32);
+#endif
+}
+
+
+static inline void
+hs_cryptohash_sha256_init (struct sha256_ctx *ctx)
+{
+ memset(ctx, 0, SHA256_CTX_SIZE);
+
+ ctx->h[0] = 0x6a09e667;
+ ctx->h[1] = 0xbb67ae85;
+ ctx->h[2] = 0x3c6ef372;
+ ctx->h[3] = 0xa54ff53a;
+ ctx->h[4] = 0x510e527f;
+ ctx->h[5] = 0x9b05688c;
+ ctx->h[6] = 0x1f83d9ab;
+ ctx->h[7] = 0x5be0cd19;
+}
+
+/* 232 times the cube root of the first 64 primes 2..311 */
+static const uint32_t k[] = {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
+ 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
+ 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
+ 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
+ 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
+ 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+#define e0(x) (ror32(x, 2) ^ ror32(x,13) ^ ror32(x,22))
+#define e1(x) (ror32(x, 6) ^ ror32(x,11) ^ ror32(x,25))
+#define s0(x) (ror32(x, 7) ^ ror32(x,18) ^ (x >> 3))
+#define s1(x) (ror32(x,17) ^ ror32(x,19) ^ (x >> 10))
+
+static void
+sha256_do_chunk_aligned(struct sha256_ctx *ctx, uint32_t w[])
+{
+ int i;
+
+ for (i = 16; i < 64; i++)
+ w[i] = s1(w[i - 2]) + w[i - 7] + s0(w[i - 15]) + w[i - 16];
+
+ uint32_t a = ctx->h[0];
+ uint32_t b = ctx->h[1];
+ uint32_t c = ctx->h[2];
+ uint32_t d = ctx->h[3];
+ uint32_t e = ctx->h[4];
+ uint32_t f = ctx->h[5];
+ uint32_t g = ctx->h[6];
+ uint32_t 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 < 64; i += 8) {
+ uint32_t t1, t2;
+
+ 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;
+}
+
+static void
+sha256_do_chunk(struct sha256_ctx *ctx, const uint8_t buf[])
+{
+ uint32_t w[64]; /* only first 16 words are filled in */
+ if (ptr_uint32_aligned(buf)) { /* aligned buf */
+ cpu_to_be32_array(w, (const uint32_t *)buf, 16);
+ } else { /* unaligned buf */
+ memcpy(w, buf, 64);
+#if !WORDS_BIGENDIAN
+ cpu_to_be32_array(w, w, 16);
+#endif
+ }
+ sha256_do_chunk_aligned(ctx, w);
+}
+
+static inline void
+hs_cryptohash_sha256_update(struct sha256_ctx *ctx, const uint8_t *data,
size_t len)
+{
+ size_t index = ctx->sz & 0x3f;
+ const size_t to_fill = 64 - index;
+
+ ctx->sz += len;
+
+ /* process partial buffer if there's enough data to make a block */
+ if (index && len >= to_fill) {
+ memcpy(ctx->buf + index, data, to_fill);
+ sha256_do_chunk(ctx, ctx->buf);
+ /* memset(ctx->buf, 0, 64); */
+ len -= to_fill;
+ data += to_fill;
+ index = 0;
+ }
+
+ /* process as many 64-blocks as possible */
+ while (len >= 64) {
+ sha256_do_chunk(ctx, data);
+ len -= 64;
+ data += 64;
+ }
+
+ /* append data into buf */
+ if (len)
+ memcpy(ctx->buf + index, data, len);
+}
+
+static inline uint64_t
+hs_cryptohash_sha256_finalize (struct sha256_ctx *ctx, uint8_t *out)
+{
+ static const uint8_t padding[64] = { 0x80, };
+ const uint64_t sz = ctx->sz;
+
+ /* add padding and update data with it */
+ uint64_t bits = cpu_to_be64(ctx->sz << 3);
+
+ /* pad out to 56 */
+ const size_t index = ctx->sz & 0x3f;
+ const size_t padlen = (index < 56) ? (56 - index) : ((64 + 56) - index);
+ hs_cryptohash_sha256_update(ctx, padding, padlen);
+
+ /* append length */
+ hs_cryptohash_sha256_update(ctx, (uint8_t *) &bits, sizeof(bits));
+
+ /* output hash */
+ cpu_to_be32_array((uint32_t *) out, ctx->h, 8);
+
+ return sz;
+}
+
+static inline void
+hs_cryptohash_sha256_hash (const uint8_t *data, size_t len, uint8_t *out)
+{
+ struct sha256_ctx ctx;
+
+ hs_cryptohash_sha256_init(&ctx);
+
+ hs_cryptohash_sha256_update(&ctx, data, len);
+
+ hs_cryptohash_sha256_finalize(&ctx, out);
+}
+
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cryptohash-sha256-0.11.100.1/cbits/sha256.c
new/cryptohash-sha256-0.11.101.0/cbits/sha256.c
--- old/cryptohash-sha256-0.11.100.1/cbits/sha256.c 2016-06-27
22:36:50.000000000 +0200
+++ new/cryptohash-sha256-0.11.101.0/cbits/sha256.c 1970-01-01
01:00:00.000000000 +0100
@@ -1,230 +0,0 @@
-/*
- * Copyright (C) 2006-2009 Vincent Hanquez <[email protected]>
- * 2016 Herbert Valerio Riedel <[email protected]>
- *
- * 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 "sha256.h"
-
-#include <assert.h>
-#include <string.h>
-#include <ghcautoconf.h>
-
-#if defined(static_assert)
-static_assert(sizeof(struct sha256_ctx) == SHA256_CTX_SIZE, "unexpected
sha256_ctx size");
-#else
-/* poor man's pre-C11 _Static_assert */
-typedef char static_assertion__unexpected_sha256_ctx_size[(sizeof(struct
sha256_ctx) == SHA256_CTX_SIZE)?1:-1];
-#endif
-
-#define ptr_uint32_aligned(ptr) (!((uintptr_t)(ptr) & 0x3))
-
-static inline uint32_t
-ror32(const uint32_t word, const unsigned shift)
-{
- /* GCC usually transforms this into a 'ror'-insn */
- return (word >> shift) | (word << (32 - shift));
-}
-
-static inline uint32_t
-cpu_to_be32(const uint32_t hl)
-{
-#if WORDS_BIGENDIAN
- return hl;
-#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
- return __builtin_bswap32(hl);
-#else
- /* GCC usually transforms this into a bswap insn */
- return ((hl & 0xff000000) >> 24) |
- ((hl & 0x00ff0000) >> 8) |
- ((hl & 0x0000ff00) << 8) |
- ( hl << 24);
-#endif
-}
-
-static inline void
-cpu_to_be32_array(uint32_t *dest, const uint32_t *src, unsigned wordcnt)
-{
- while (wordcnt--)
- *dest++ = cpu_to_be32(*src++);
-}
-
-static inline uint64_t
-cpu_to_be64(const uint64_t hll)
-{
-#if WORDS_BIGENDIAN
- return hll;
-#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
- return __builtin_bswap64(hll);
-#else
- return ((uint64_t)cpu_to_be32(hll & 0xffffffff) << 32LL) | cpu_to_be32(hll
>> 32);
-#endif
-}
-
-
-void
-hs_cryptohash_sha256_init (struct sha256_ctx *ctx)
-{
- memset(ctx, 0, SHA256_CTX_SIZE);
-
- ctx->h[0] = 0x6a09e667;
- ctx->h[1] = 0xbb67ae85;
- ctx->h[2] = 0x3c6ef372;
- ctx->h[3] = 0xa54ff53a;
- ctx->h[4] = 0x510e527f;
- ctx->h[5] = 0x9b05688c;
- ctx->h[6] = 0x1f83d9ab;
- ctx->h[7] = 0x5be0cd19;
-}
-
-/* 232 times the cube root of the first 64 primes 2..311 */
-static const uint32_t k[] = {
- 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
- 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
- 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
- 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
- 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
- 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
- 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
- 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
- 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
- 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
- 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
-};
-
-#define e0(x) (ror32(x, 2) ^ ror32(x,13) ^ ror32(x,22))
-#define e1(x) (ror32(x, 6) ^ ror32(x,11) ^ ror32(x,25))
-#define s0(x) (ror32(x, 7) ^ ror32(x,18) ^ (x >> 3))
-#define s1(x) (ror32(x,17) ^ ror32(x,19) ^ (x >> 10))
-
-static void
-sha256_do_chunk_aligned(struct sha256_ctx *ctx, uint32_t w[])
-{
- int i;
-
- for (i = 16; i < 64; i++)
- w[i] = s1(w[i - 2]) + w[i - 7] + s0(w[i - 15]) + w[i - 16];
-
- uint32_t a = ctx->h[0];
- uint32_t b = ctx->h[1];
- uint32_t c = ctx->h[2];
- uint32_t d = ctx->h[3];
- uint32_t e = ctx->h[4];
- uint32_t f = ctx->h[5];
- uint32_t g = ctx->h[6];
- uint32_t 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 < 64; i += 8) {
- uint32_t t1, t2;
-
- 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;
-}
-
-static void
-sha256_do_chunk(struct sha256_ctx *ctx, const uint8_t buf[])
-{
- uint32_t w[64]; /* only first 16 words are filled in */
- if (ptr_uint32_aligned(buf)) { /* aligned buf */
- cpu_to_be32_array(w, (const uint32_t *)buf, 16);
- } else { /* unaligned buf */
- memcpy(w, buf, 64);
-#if !WORDS_BIGENDIAN
- cpu_to_be32_array(w, w, 16);
-#endif
- }
- sha256_do_chunk_aligned(ctx, w);
-}
-
-void
-hs_cryptohash_sha256_update(struct sha256_ctx *ctx, const uint8_t *data,
size_t len)
-{
- size_t index = ctx->sz & 0x3f;
- const size_t to_fill = 64 - index;
-
- ctx->sz += len;
-
- /* process partial buffer if there's enough data to make a block */
- if (index && len >= to_fill) {
- memcpy(ctx->buf + index, data, to_fill);
- sha256_do_chunk(ctx, ctx->buf);
- /* memset(ctx->buf, 0, 64); */
- len -= to_fill;
- data += to_fill;
- index = 0;
- }
-
- /* process as many 64-blocks as possible */
- while (len >= 64) {
- sha256_do_chunk(ctx, data);
- len -= 64;
- data += 64;
- }
-
- /* append data into buf */
- if (len)
- memcpy(ctx->buf + index, data, len);
-}
-
-void
-hs_cryptohash_sha256_finalize (struct sha256_ctx *ctx, uint8_t *out)
-{
- static const uint8_t padding[64] = { 0x80, };
-
- /* add padding and update data with it */
- uint64_t bits = cpu_to_be64(ctx->sz << 3);
-
- /* pad out to 56 */
- const size_t index = ctx->sz & 0x3f;
- const size_t padlen = (index < 56) ? (56 - index) : ((64 + 56) - index);
- hs_cryptohash_sha256_update(ctx, padding, padlen);
-
- /* append length */
- hs_cryptohash_sha256_update(ctx, (uint8_t *) &bits, sizeof(bits));
-
- /* output hash */
- cpu_to_be32_array((uint32_t *) out, ctx->h, 8);
-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cryptohash-sha256-0.11.100.1/cbits/sha256.h
new/cryptohash-sha256-0.11.101.0/cbits/sha256.h
--- old/cryptohash-sha256-0.11.100.1/cbits/sha256.h 2016-06-27
22:36:50.000000000 +0200
+++ new/cryptohash-sha256-0.11.101.0/cbits/sha256.h 1970-01-01
01:00:00.000000000 +0100
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2006-2009 Vincent Hanquez <[email protected]>
- * 2016 Herbert Valerio Riedel <[email protected]>
- *
- * 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_SHA256_H
-#define CRYPTOHASH_SHA256_H
-
-#include <stdint.h>
-#include <stddef.h>
-
-struct sha256_ctx
-{
- uint64_t sz;
- uint8_t buf[64];
- uint32_t h[8];
-};
-
-/* keep this synchronised with 'digestSize'/'sizeCtx' in SHA256.hs */
-#define SHA256_DIGEST_SIZE 32
-#define SHA256_CTX_SIZE 104
-
-void hs_cryptohash_sha256_init (struct sha256_ctx *ctx);
-void hs_cryptohash_sha256_update (struct sha256_ctx *ctx, const uint8_t *data,
size_t len);
-void hs_cryptohash_sha256_finalize (struct sha256_ctx *ctx, uint8_t *out);
-
-#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cryptohash-sha256-0.11.100.1/changelog.md
new/cryptohash-sha256-0.11.101.0/changelog.md
--- old/cryptohash-sha256-0.11.100.1/changelog.md 2016-06-27
22:36:50.000000000 +0200
+++ new/cryptohash-sha256-0.11.101.0/changelog.md 2017-11-13
09:04:55.000000000 +0100
@@ -1,3 +1,17 @@
+## 0.11.101.0
+
+ - Add `hkdf` function providing HKDF-SHA256 conforming to RFC5869
+ - Declare `Crypto.Hash.SHA256` module `-XTrustworthy`
+ - Remove ineffective RULES
+ - Convert to `CApiFFI`
+ - Added `...AndLength` variants of hashing functions:
+
+ - `finalizeAndLength`
+ - `hashlazyAndLength`
+ - `hmaclazyAndLength`
+
+ - Minor optimizations in `hmac` and `hash`
+
## 0.11.100.1
- Use `__builtin_bswap{32,64}` only with GCC >= 4.3
@@ -5,7 +19,7 @@
## 0.11.100.0
- - new `hmac` and `hmaclazy` functions providing HMAC-SHA1
+ - new `hmac` and `hmaclazy` functions providing HMAC-SHA256
computation conforming to RFC2104 and RFC4231
- fix unaligned memory-accesses
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cryptohash-sha256-0.11.100.1/cryptohash-sha256.cabal
new/cryptohash-sha256-0.11.101.0/cryptohash-sha256.cabal
--- old/cryptohash-sha256-0.11.100.1/cryptohash-sha256.cabal 2016-06-27
22:36:50.000000000 +0200
+++ new/cryptohash-sha256-0.11.101.0/cryptohash-sha256.cabal 2017-11-13
09:04:55.000000000 +0100
@@ -1,20 +1,44 @@
+cabal-version: 1.12
name: cryptohash-sha256
-version: 0.11.100.1
-description:
- A practical incremental and one-pass, pure API to the
- <https://en.wikipedia.org/wiki/SHA-2 SHA-256 hash algorithm>
- (including <https://en.wikipedia.org/wiki/HMAC HMAC> support)
- with performance close to the fastest implementations available in other
languages.
- .
- The implementation is made in C with a haskell FFI wrapper that hides the
C implementation.
- .
- NOTE: This package has been forked off @cryptohash-0.11.7@ because the
@cryptohash@ package has been
- deprecated and so this package continues to satisfy the need for a
lightweight package
- providing the SHA256 hash algorithm without any dependencies on packages
other than
- @base@ and @bytestring@.
- .
- Consequently, this package can be used as a drop-in replacement for
@cryptohash@'s
- "Crypto.Hash.SHA256" module, though with a clearly smaller footprint.
+version: 0.11.101.0
+
+synopsis: Fast, pure and practical SHA-256 implementation
+description: {
+
+A practical incremental and one-pass, pure API to
+the [SHA-256 cryptographic hash
algorithm](https://en.wikipedia.org/wiki/SHA-2) according
+to [FIPS 180-4](http://dx.doi.org/10.6028/NIST.FIPS.180-4)
+with performance close to the fastest implementations available in other
languages.
+.
+The core SHA-256 algorithm is implemented in C and is thus expected
+to be as fast as the standard [sha256sum(1)
tool](https://linux.die.net/man/1/sha256sum);
+for instance, on an /Intel Core i7-3770/ at 3.40GHz this implementation can
+compute a SHA-256 hash over 230 MiB of data in under one second.
+(If, instead, you require a pure Haskell implementation and performance is
secondary, please refer to the [SHA
package](https://hackage.haskell.org/package/SHA).)
+.
+
+.
+Additionally, this package provides support for
+.
+- HMAC-SHA-256: SHA-256-based [Hashed Message Authentication
Codes](https://en.wikipedia.org/wiki/HMAC) (HMAC)
+- HKDF-SHA-256: [HMAC-SHA-256-based Key Derivation
Function](https://en.wikipedia.org/wiki/HKDF) (HKDF)
+.
+conforming to [RFC6234](https://tools.ietf.org/html/rfc6234),
[RFC4231](https://tools.ietf.org/html/rfc4231),
[RFC5869](https://tools.ietf.org/html/rfc5869), et al..
+.
+=== Relationship to the @cryptohash@ package and its API
+.
+This package has been originally a fork of @cryptohash-0.11.7@ because the
@cryptohash@
+package had been deprecated and so this package continues to satisfy the need
for a
+lightweight package providing the SHA-256 hash algorithm without any
dependencies on packages
+other than @base@ and @bytestring@. The API exposed by
@cryptohash-sha256-0.11.*@'s
+"Crypto.Hash.SHA256" module is guaranteed to remain a compatible superset of
the API provided
+by the @cryptohash-0.11.7@'s module of the same name.
+.
+Consequently, this package is designed to be used as a drop-in replacement for
@cryptohash-0.11.7@'s
+"Crypto.Hash.SHA256" module, though with
+a [clearly smaller footprint by almost 3 orders of
magnitude](https://www.reddit.com/r/haskell/comments/5lxv75/psa_please_use_unique_module_names_when_uploading/dbzegx3/).
+
+}
license: BSD3
license-file: LICENSE
@@ -22,37 +46,62 @@
maintainer: Herbert Valerio Riedel <[email protected]>
homepage: https://github.com/hvr/cryptohash-sha256
bug-reports: https://github.com/hvr/cryptohash-sha256/issues
-synopsis: Fast, pure and practical SHA-256 implementation
category: Data, Cryptography
build-type: Simple
-cabal-version: >=1.10
tested-with: GHC == 7.4.2
, GHC == 7.6.3
, GHC == 7.8.4
, GHC == 7.10.3
- , GHC == 8.0.1
+ , GHC == 8.0.2
+ , GHC == 8.2.1
-extra-source-files: cbits/sha256.h
+extra-source-files: cbits/hs_sha256.h
changelog.md
source-repository head
type: git
location: https://github.com/hvr/cryptohash-sha256.git
+flag exe
+ description: Enable building @sha256sum@ executable
+ manual: True
+ default: False
+
library
default-language: Haskell2010
- build-depends: base >= 4.5 && < 4.10
+ other-extensions: BangPatterns
+ CApiFFI
+ Trustworthy
+ Unsafe
+
+ build-depends: base >= 4.5 && < 4.11
, bytestring >= 0.9.2 && < 0.11
+ ghc-options: -Wall
+
hs-source-dirs: src
exposed-modules: Crypto.Hash.SHA256
- ghc-options: -Wall -fno-cse -O2
- cc-options: -Wall -O3
- c-sources: cbits/sha256.c
+ other-modules: Crypto.Hash.SHA256.FFI
include-dirs: cbits
+executable sha256sum
+ hs-source-dirs: src-exe
+ main-is: sha256sum.hs
+ ghc-options: -Wall -threaded
+ if flag(exe)
+ default-language: Haskell2010
+ other-extensions: RecordWildCards
+ build-depends: cryptohash-sha256
+ , base
+ , bytestring
+
+ , base16-bytestring >= 0.1.1 && < 0.2
+ else
+ buildable: False
+
test-suite test-sha256
default-language: Haskell2010
+ other-extensions: OverloadedStrings
type: exitcode-stdio-1.0
hs-source-dirs: src-tests
main-is: test-sha256.hs
@@ -69,6 +118,7 @@
benchmark bench-sha256
default-language: Haskell2010
+ other-extensions: BangPatterns
type: exitcode-stdio-1.0
main-is: bench-sha256.hs
hs-source-dirs: src-bench
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/cryptohash-sha256-0.11.100.1/src/Crypto/Hash/SHA256/FFI.hs
new/cryptohash-sha256-0.11.101.0/src/Crypto/Hash/SHA256/FFI.hs
--- old/cryptohash-sha256-0.11.100.1/src/Crypto/Hash/SHA256/FFI.hs
1970-01-01 01:00:00.000000000 +0100
+++ new/cryptohash-sha256-0.11.101.0/src/Crypto/Hash/SHA256/FFI.hs
2017-11-13 09:04:55.000000000 +0100
@@ -0,0 +1,61 @@
+{-# LANGUAGE CApiFFI #-}
+{-# LANGUAGE Unsafe #-}
+
+-- Ugly hack to workaround https://ghc.haskell.org/trac/ghc/ticket/14452
+{-# OPTIONS_GHC -O0
+ -fdo-lambda-eta-expansion
+ -fcase-merge
+ -fstrictness
+ -fno-omit-interface-pragmas
+ -fno-ignore-interface-pragmas #-}
+
+{-# OPTIONS_GHC -optc-Wall -optc-O3 #-}
+
+-- |
+-- Module : Crypto.Hash.SHA256.FFI
+-- License : BSD-3
+-- Maintainer : Herbert Valerio Riedel <[email protected]>
+--
+module Crypto.Hash.SHA256.FFI where
+
+import Data.ByteString (ByteString)
+import Data.Word
+import Foreign.C.Types
+import Foreign.Ptr
+
+-- | SHA-256 Context
+--
+-- The context data is exactly 104 bytes long, however
+-- the data in the context is stored in host-endianness.
+--
+-- The context data is made up of
+--
+-- * a 'Word64' representing the number of bytes already feed to hash
algorithm so far,
+--
+-- * a 64-element 'Word8' buffer holding partial input-chunks, and finally
+--
+-- * a 8-element 'Word32' array holding the current work-in-progress
digest-value.
+--
+-- Consequently, a SHA-256 digest as produced by 'hash', 'hashlazy', or
'finalize' is 32 bytes long.
+newtype Ctx = Ctx ByteString
+
+foreign import capi unsafe "hs_sha256.h hs_cryptohash_sha256_init"
+ c_sha256_init :: Ptr Ctx -> IO ()
+
+foreign import capi unsafe "hs_sha256.h hs_cryptohash_sha256_update"
+ c_sha256_update_unsafe :: Ptr Ctx -> Ptr Word8 -> CSize -> IO ()
+
+foreign import capi safe "hs_sha256.h hs_cryptohash_sha256_update"
+ c_sha256_update_safe :: Ptr Ctx -> Ptr Word8 -> CSize -> IO ()
+
+foreign import capi unsafe "hs_sha256.h hs_cryptohash_sha256_finalize"
+ c_sha256_finalize_len :: Ptr Ctx -> Ptr Word8 -> IO Word64
+
+foreign import capi unsafe "hs_sha256.h hs_cryptohash_sha256_finalize"
+ c_sha256_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
+
+foreign import capi unsafe "hs_sha256.h hs_cryptohash_sha256_hash"
+ c_sha256_hash_unsafe :: Ptr Word8 -> CSize -> Ptr Word8 -> IO ()
+
+foreign import capi safe "hs_sha256.h hs_cryptohash_sha256_hash"
+ c_sha256_hash_safe :: Ptr Word8 -> CSize -> Ptr Word8 -> IO ()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/cryptohash-sha256-0.11.100.1/src/Crypto/Hash/SHA256.hs
new/cryptohash-sha256-0.11.101.0/src/Crypto/Hash/SHA256.hs
--- old/cryptohash-sha256-0.11.100.1/src/Crypto/Hash/SHA256.hs 2016-06-27
22:36:50.000000000 +0200
+++ new/cryptohash-sha256-0.11.101.0/src/Crypto/Hash/SHA256.hs 2017-11-13
09:04:55.000000000 +0100
@@ -1,9 +1,11 @@
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE Trustworthy #-}
+
-- |
-- Module : Crypto.Hash.SHA256
--- License : BSD-style
+-- License : BSD-3
-- Maintainer : Herbert Valerio Riedel <[email protected]>
-- Stability : stable
--- Portability : unknown
--
-- A module containing <https://en.wikipedia.org/wiki/SHA-2 SHA-256> bindings
--
@@ -40,6 +42,7 @@
, update -- :: Ctx -> ByteString -> Ctx
, updates -- :: Ctx -> [ByteString] -> Ctx
, finalize -- :: Ctx -> ByteString
+ , finalizeAndLength -- :: Ctx -> (ByteString,Word64)
-- * Single Pass API
--
@@ -49,6 +52,7 @@
--
-- - 'hash': create a digest ('init' + 'update' + 'finalize') from a
strict 'ByteString'
-- - 'hashlazy': create a digest ('init' + 'update' + 'finalize') from a
lazy 'L.ByteString'
+ -- - 'hashlazyAndLength': create a digest ('init' + 'update' +
'finalizeAndLength') from a lazy 'L.ByteString'
--
-- Example:
--
@@ -64,6 +68,7 @@
, hash -- :: ByteString -> ByteString
, hashlazy -- :: L.ByteString -> ByteString
+ , hashlazyAndLength -- :: L.ByteString -> (ByteString,Int64)
-- ** HMAC-SHA-256
--
@@ -72,21 +77,33 @@
, hmac -- :: ByteString -> ByteString -> ByteString
, hmaclazy -- :: ByteString -> L.ByteString -> ByteString
+ , hmaclazyAndLength -- :: ByteString -> L.ByteString -> (ByteString,Word64)
+
+ -- ** HKDF-SHA-256
+ --
+ -- | <https://tools.ietf.org/html/rfc5869 RFC5869>-compatible
+ -- <https://en.wikipedia.org/wiki/HKDF HKDF>-SHA-256 key derivation
function
+
+ , hkdf
) where
-import Prelude hiding (init)
-import Foreign.C.Types
-import Foreign.Ptr
-import Foreign.ForeignPtr (withForeignPtr)
-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, memcpy)
-import Data.Bits (xor)
-import Data.Word
-import System.IO.Unsafe (unsafeDupablePerformIO)
+import Data.Bits (xor)
+import Data.ByteString (ByteString)
+import qualified Data.ByteString as B
+import Data.ByteString.Internal (ByteString (PS), create,
+ createAndTrim, mallocByteString,
+ memcpy, toForeignPtr)
+import qualified Data.ByteString.Lazy as L
+import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
+import Data.Word
+import Foreign.C.Types
+import Foreign.ForeignPtr (withForeignPtr)
+import Foreign.Marshal.Alloc
+import Foreign.Ptr
+import Prelude hiding (init)
+import System.IO.Unsafe (unsafeDupablePerformIO)
+
+import Crypto.Hash.SHA256.FFI
-- | perform IO for hashes that do allocation and ffi.
-- unsafeDupablePerformIO is used when possible as the
@@ -96,22 +113,6 @@
unsafeDoIO :: IO a -> a
unsafeDoIO = unsafeDupablePerformIO
--- | SHA-256 Context
---
--- The context data is exactly 104 bytes long, however
--- the data in the context is stored in host-endianness.
---
--- The context data is made up of
---
--- * a 'Word64' representing the number of bytes already feed to hash
algorithm so far,
---
--- * a 64-element 'Word8' buffer holding partial input-chunks, and finally
---
--- * a 8-element 'Word32' array holding the current work-in-progress
digest-value.
---
--- Consequently, a SHA-256 digest as produced by 'hash', 'hashlazy', or
'finalize' is 32 bytes long.
-newtype Ctx = Ctx ByteString
-
-- keep this synchronised with cbits/sha256.h
{-# INLINE digestSize #-}
digestSize :: Int
@@ -121,18 +122,21 @@
sizeCtx :: Int
sizeCtx = 104
-{-# 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 create' #-}
+-- | Variant of 'create' which allows to return an argument
+create' :: Int -> (Ptr Word8 -> IO a) -> IO (ByteString,a)
+create' l f = do
+ fp <- mallocByteString l
+ x <- withForeignPtr fp $ \p -> f p
+ let bs = PS fp 0 l
+ return $! x `seq` bs `seq` (bs,x)
+
copyCtx :: Ptr Ctx -> Ptr Ctx -> IO ()
copyCtx dst src = memcpy (castPtr dst) (castPtr src) (fromIntegral sizeCtx)
@@ -157,23 +161,17 @@
withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
-foreign import ccall unsafe "sha256.h hs_cryptohash_sha256_init"
- c_sha256_init :: Ptr Ctx -> IO ()
-
-foreign import ccall unsafe "sha256.h hs_cryptohash_sha256_update"
- c_sha256_update_unsafe :: Ptr Ctx -> Ptr Word8 -> CSize -> IO ()
-
-foreign import ccall safe "sha256.h hs_cryptohash_sha256_update"
- c_sha256_update_safe :: Ptr Ctx -> Ptr Word8 -> CSize -> IO ()
-
-- 'safe' call overhead neglible for 4KiB and more
c_sha256_update :: Ptr Ctx -> Ptr Word8 -> CSize -> IO ()
c_sha256_update pctx pbuf sz
| sz < 4096 = c_sha256_update_unsafe pctx pbuf sz
| otherwise = c_sha256_update_safe pctx pbuf sz
-foreign import ccall unsafe "sha256.h hs_cryptohash_sha256_finalize"
- c_sha256_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
+-- 'safe' call overhead neglible for 4KiB and more
+c_sha256_hash :: Ptr Word8 -> CSize -> Ptr Word8 -> IO ()
+c_sha256_hash pbuf sz pout
+ | sz < 4096 = c_sha256_hash_unsafe pbuf sz pout
+ | otherwise = c_sha256_hash_safe pbuf sz pout
updateInternalIO :: Ptr Ctx -> ByteString -> IO ()
updateInternalIO ptr d =
@@ -182,10 +180,14 @@
finalizeInternalIO :: Ptr Ctx -> IO ByteString
finalizeInternalIO ptr = create digestSize (c_sha256_finalize ptr)
+finalizeInternalIO' :: Ptr Ctx -> IO (ByteString,Word64)
+finalizeInternalIO' ptr = create' digestSize (c_sha256_finalize_len ptr)
+
+
{-# NOINLINE init #-}
-- | create a new hash context
init :: Ctx
-init = unsafeDoIO $ withCtxNew $ c_sha256_init
+init = unsafeDoIO $ withCtxNew c_sha256_init
validCtx :: Ctx -> Bool
validCtx (Ctx b) = B.length b == sizeCtx
@@ -211,28 +213,44 @@
| validCtx ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO
| otherwise = error "SHA256.finalize: invalid Ctx"
+{-# NOINLINE finalizeAndLength #-}
+-- | Variant of 'finalize' also returning length of hashed content
+--
+-- @since 0.11.101.0
+finalizeAndLength :: Ctx -> (ByteString,Word64)
+finalizeAndLength ctx
+ | validCtx ctx = unsafeDoIO $ withCtxThrow ctx finalizeInternalIO'
+ | otherwise = error "SHA256.finalize: invalid Ctx"
+
{-# NOINLINE hash #-}
-- | hash a strict bytestring into a digest bytestring (32 bytes)
hash :: ByteString -> ByteString
-hash d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
- c_sha256_init ptr >> updateInternalIO ptr d >> finalizeInternalIO ptr
+-- hash d = unsafeDoIO $ withCtxNewThrow $ \ptr -> c_sha256_init ptr >>
updateInternalIO ptr d >> finalizeInternalIO ptr
+hash d = unsafeDoIO $ unsafeUseAsCStringLen d $ \(cs, len) -> create
digestSize (c_sha256_hash (castPtr cs) (fromIntegral len))
{-# NOINLINE hashlazy #-}
-- | hash a lazy bytestring into a digest bytestring (32 bytes)
hashlazy :: L.ByteString -> ByteString
-hashlazy l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
+hashlazy l = unsafeDoIO $ withCtxNewThrow $ \ptr ->
c_sha256_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >>
finalizeInternalIO ptr
+{-# NOINLINE hashlazyAndLength #-}
+-- | Variant of 'hashlazy' which simultaneously computes the hash and length
of a lazy bytestring.
+--
+-- @since 0.11.101.0
+hashlazyAndLength :: L.ByteString -> (ByteString,Word64)
+hashlazyAndLength l = unsafeDoIO $ withCtxNewThrow $ \ptr ->
+ c_sha256_init ptr >> mapM_ (updateInternalIO ptr) (L.toChunks l) >>
finalizeInternalIO' ptr
+
-{-# NOINLINE hmac #-}
-- | Compute 32-byte <https://tools.ietf.org/html/rfc2104 RFC2104>-compatible
--- HMAC-SHA1 digest for a strict bytestring message
+-- HMAC-SHA-256 digest for a strict bytestring message
--
-- @since 0.11.100.0
hmac :: ByteString -- ^ secret
-> ByteString -- ^ message
- -> ByteString
-hmac secret msg = hash $ B.append opad (hash $ B.append ipad msg)
+ -> ByteString -- ^ digest (32 bytes)
+hmac secret msg = hash $ B.append opad (hashlazy $ L.fromChunks [ipad,msg])
where
opad = B.map (xor 0x5c) k'
ipad = B.map (xor 0x36) k'
@@ -242,14 +260,13 @@
pad = B.replicate (64 - B.length kt) 0
-{-# NOINLINE hmaclazy #-}
-- | Compute 32-byte <https://tools.ietf.org/html/rfc2104 RFC2104>-compatible
--- HMAC-SHA1 digest for a lazy bytestring message
+-- HMAC-SHA-256 digest for a lazy bytestring message
--
-- @since 0.11.100.0
hmaclazy :: ByteString -- ^ secret
-> L.ByteString -- ^ message
- -> ByteString
+ -> ByteString -- ^ digest (32 bytes)
hmaclazy secret msg = hash $ B.append opad (hashlazy $ L.append ipad msg)
where
opad = B.map (xor 0x5c) k'
@@ -258,3 +275,48 @@
k' = B.append kt pad
kt = if B.length secret > 64 then hash secret else secret
pad = B.replicate (64 - B.length kt) 0
+
+
+-- | Variant of 'hmaclazy' which also returns length of message
+--
+-- @since 0.11.101.0
+hmaclazyAndLength :: ByteString -- ^ secret
+ -> L.ByteString -- ^ message
+ -> (ByteString,Word64) -- ^ digest (32 bytes) and length of
message
+hmaclazyAndLength secret msg =
+ (hash (B.append opad htmp), sz' - fromIntegral ipadLen)
+ where
+ (htmp, sz') = hashlazyAndLength (L.append ipad msg)
+
+ opad = B.map (xor 0x5c) k'
+ ipad = L.fromChunks [B.map (xor 0x36) k']
+ ipadLen = B.length k'
+
+ k' = B.append kt pad
+ kt = if B.length secret > 64 then hash secret else secret
+ pad = B.replicate (64 - B.length kt) 0
+
+{-# NOINLINE hkdf #-}
+-- | <https://tools.ietf.org/html/rfc6234 RFC6234>-compatible
+-- HKDF-SHA-256 key derivation function.
+--
+-- @since 0.11.101.0
+hkdf :: ByteString -- ^ /IKM/ Input keying material
+ -> ByteString -- ^ /salt/ Optional salt value, a non-secret random value
(can be @""@)
+ -> ByteString -- ^ /info/ Optional context and application specific
information (can be @""@)
+ -> Int -- ^ /L/ length of output keying material in octets (at
most 255*32 bytes)
+ -> ByteString -- ^ /OKM/ Output keying material (/L/ bytes)
+hkdf ikm salt info l
+ | l == 0 = B.empty
+ | 0 > l || l > 255*32 = error "hkdf: invalid L parameter"
+ | otherwise = unsafeDoIO $ createAndTrim (32*fromIntegral cnt) (go 0 B.empty)
+ where
+ prk = hmac salt ikm
+ cnt = fromIntegral ((l+31) `div` 32) :: Word8
+
+ go :: Word8 -> ByteString -> Ptr Word8 -> IO Int
+ go !i t !p | i == cnt = return l
+ | otherwise = do
+ let t' = hmaclazy prk (L.fromChunks [t,info,B.singleton
(i+1)])
+ withByteStringPtr t' $ \tptr' -> memcpy p tptr' 32
+ go (i+1) t' (p `plusPtr` 32)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cryptohash-sha256-0.11.100.1/src-exe/sha256sum.hs
new/cryptohash-sha256-0.11.101.0/src-exe/sha256sum.hs
--- old/cryptohash-sha256-0.11.100.1/src-exe/sha256sum.hs 1970-01-01
01:00:00.000000000 +0100
+++ new/cryptohash-sha256-0.11.101.0/src-exe/sha256sum.hs 2017-11-13
09:04:55.000000000 +0100
@@ -0,0 +1,78 @@
+{-# LANGUAGE RecordWildCards #-}
+
+module Main where
+
+import Control.Monad
+import qualified Data.ByteString.Base16 as B16
+import qualified Data.ByteString.Char8 as B
+import qualified Data.ByteString.Lazy as BL
+import System.Console.GetOpt
+import System.Environment
+import System.Exit
+import System.IO
+
+import qualified Crypto.Hash.SHA256 as H
+
+
+data Options = Options
+ { optBinary :: Bool
+ , optHelp :: Bool
+ , optTag :: Bool
+ } deriving Show
+
+defOptions :: Options
+defOptions = Options
+ { optBinary = True
+ , optHelp = False
+ , optTag = False
+ }
+
+options :: [OptDescr (Options -> Options)]
+options = [ Option ['b'] ["binary"]
+ (NoArg (\o -> o { optBinary = True}))
+ "read in binary mode (default)"
+ , Option ['t'] ["text"]
+ (NoArg (\o -> o { optBinary = False}))
+ "read in text mode (ignored)"
+ , Option [] ["help"]
+ (NoArg (\o -> o { optHelp = True}))
+ "display help and exit"
+ , Option [] ["tag"]
+ (NoArg (\o -> o { optTag = True}))
+ "create a BSD-style checksum"
+ ]
+
+main :: IO ()
+main = do
+ argv <- getArgs
+
+ let Options{..} = foldl (flip id) defOptions optset
+ (optset,args0,cliErr) = getOpt Permute options argv
+ args | null args0 = ["-"]
+ | otherwise = args0
+
+ unless (null cliErr) $ do
+ hPutStrLn stderr ("sha256sum: " ++ head cliErr ++ "Try 'sha256sum --help'
for more information.")
+ exitFailure
+
+ when optHelp $ do
+ putStrLn (usageInfo "Usage: sha256sum [OPTION]... [FILE]...\nPrint or
check SHA-256 hashes\n" options)
+ exitSuccess
+
+ forM_ args $ \fn -> do
+ h <- (B16.encode . H.hashlazy) `fmap` bReadFile fn
+
+ case optTag of
+ False -> do
+ B.hPutStr stdout h
+ hPutStrLn stdout (' ':' ':fn)
+ True -> do
+ hPutStrLn stdout $ concat [ "SHA256 (", fn, ") = ", B.unpack h ]
+
+ return ()
+
+bReadFile :: FilePath -> IO BL.ByteString
+bReadFile "-" = do
+ clsd <- hIsClosed stdin
+ if clsd then return BL.empty else BL.getContents
+bReadFile fn = BL.readFile fn
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/cryptohash-sha256-0.11.100.1/src-tests/test-sha256.hs
new/cryptohash-sha256-0.11.101.0/src-tests/test-sha256.hs
--- old/cryptohash-sha256-0.11.100.1/src-tests/test-sha256.hs 2016-06-27
22:36:50.000000000 +0200
+++ new/cryptohash-sha256-0.11.101.0/src-tests/test-sha256.hs 2017-11-13
09:04:55.000000000 +0100
@@ -4,8 +4,9 @@
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
-import qualified Data.ByteString.Lazy as BL
import qualified Data.ByteString.Base16 as B16
+import qualified Data.ByteString.Lazy as BL
+import Data.Word
-- reference implementation
import qualified Data.Digest.Pure.SHA as REF
@@ -124,6 +125,29 @@
hex = B16.encode
+rfc5869Vectors :: [(Int,ByteString,ByteString,ByteString,ByteString)]
+rfc5869Vectors = -- (l,ikm,salt,info,okm)
+ [ (42, rep 22 0x0b, x"000102030405060708090a0b0c",
x"f0f1f2f3f4f5f6f7f8f9",
x"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865")
+ , ( 82
+ ,
x"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f"
+ ,
x"606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
+ ,
x"b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"
+ ,
x"b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87"
+ )
+ , ( 42, rep 22 0x0b, "", "",
x"8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8")
+ ]
+ where
+ x = fst.B16.decode
+ rep n c = B.replicate n c
+
+rfc5869Tests :: [TestTree]
+rfc5869Tests = zipWith makeTest [1::Int ..] rfc5869Vectors
+ where
+ makeTest i (l,ikm,salt,info,okm) = testGroup ("vec"++show i) $
+ [ testCase "hkdf" (hex okm @=? hex (IUT.hkdf ikm salt info l)) ]
+
+ hex = B16.encode
+
-- define own 'foldl' here to avoid RULE rewriting to 'hashlazy'
myfoldl' :: (b -> a -> b) -> b -> [a] -> b
myfoldl' f z0 xs0 = lgo z0 xs0
@@ -155,8 +179,10 @@
refImplTests =
[ testProperty "hash" prop_hash
, testProperty "hashlazy" prop_hashlazy
+ , testProperty "hashlazyAndLength" prop_hashlazyAndLength
, testProperty "hmac" prop_hmac
, testProperty "hmaclazy" prop_hmaclazy
+ , testProperty "hmaclazyAndLength" prop_hmaclazyAndLength
]
where
prop_hash (RandBS bs)
@@ -165,24 +191,36 @@
prop_hashlazy (RandLBS bs)
= ref_hashlazy bs == IUT.hashlazy bs
+ prop_hashlazyAndLength (RandLBS bs)
+ = ref_hashlazyAndLength bs == IUT.hashlazyAndLength bs
+
prop_hmac (RandBS k) (RandBS bs)
= ref_hmac k bs == IUT.hmac k bs
prop_hmaclazy (RandBS k) (RandLBS bs)
= ref_hmaclazy k bs == IUT.hmaclazy k bs
+ prop_hmaclazyAndLength (RandBS k) (RandLBS bs)
+ = ref_hmaclazyAndLength k bs == IUT.hmaclazyAndLength k bs
+
ref_hash :: ByteString -> ByteString
ref_hash = ref_hashlazy . fromStrict
ref_hashlazy :: BL.ByteString -> ByteString
ref_hashlazy = toStrict . REF.bytestringDigest . REF.sha256
+ ref_hashlazyAndLength :: BL.ByteString -> (ByteString,Word64)
+ ref_hashlazyAndLength x = (ref_hashlazy x, fromIntegral (BL.length x))
+
ref_hmac :: ByteString -> ByteString -> ByteString
ref_hmac secret = ref_hmaclazy secret . fromStrict
ref_hmaclazy :: ByteString -> BL.ByteString -> ByteString
ref_hmaclazy secret = toStrict . REF.bytestringDigest . REF.hmacSha256
(fromStrict secret)
+ ref_hmaclazyAndLength :: ByteString -> BL.ByteString -> (ByteString,Word64)
+ ref_hmaclazyAndLength secret msg = (ref_hmaclazy secret msg, fromIntegral
(BL.length msg))
+
-- toStrict/fromStrict only available with bytestring-0.10 and later
toStrict = B.concat . BL.toChunks
fromStrict = BL.fromChunks . (:[])
@@ -191,5 +229,6 @@
main = defaultMain $ testGroup "cryptohash-sha256"
[ testGroup "KATs" katTests
, testGroup "RFC4231" rfc4231Tests
+ , testGroup "RFC5869" rfc5869Tests
, testGroup "REF" refImplTests
]
++++++ cryptohash-sha256.cabal ++++++
--- /var/tmp/diff_new_pack.e7ZlNX/_old 2018-05-30 12:25:19.874278951 +0200
+++ /var/tmp/diff_new_pack.e7ZlNX/_new 2018-05-30 12:25:19.878278821 +0200
@@ -1,21 +1,45 @@
+cabal-version: 1.12
name: cryptohash-sha256
-version: 0.11.100.1
+version: 0.11.101.0
x-revision: 1
-description:
- A practical incremental and one-pass, pure API to the
- <https://en.wikipedia.org/wiki/SHA-2 SHA-256 hash algorithm>
- (including <https://en.wikipedia.org/wiki/HMAC HMAC> support)
- with performance close to the fastest implementations available in other
languages.
- .
- The implementation is made in C with a haskell FFI wrapper that hides the
C implementation.
- .
- NOTE: This package has been forked off @cryptohash-0.11.7@ because the
@cryptohash@ package has been
- deprecated and so this package continues to satisfy the need for a
lightweight package
- providing the SHA256 hash algorithm without any dependencies on packages
other than
- @base@ and @bytestring@.
- .
- Consequently, this package can be used as a drop-in replacement for
@cryptohash@'s
- "Crypto.Hash.SHA256" module, though with a clearly smaller footprint.
+
+synopsis: Fast, pure and practical SHA-256 implementation
+description: {
+
+A practical incremental and one-pass, pure API to
+the [SHA-256 cryptographic hash
algorithm](https://en.wikipedia.org/wiki/SHA-2) according
+to [FIPS 180-4](http://dx.doi.org/10.6028/NIST.FIPS.180-4)
+with performance close to the fastest implementations available in other
languages.
+.
+The core SHA-256 algorithm is implemented in C and is thus expected
+to be as fast as the standard [sha256sum(1)
tool](https://linux.die.net/man/1/sha256sum);
+for instance, on an /Intel Core i7-3770/ at 3.40GHz this implementation can
+compute a SHA-256 hash over 230 MiB of data in under one second.
+(If, instead, you require a pure Haskell implementation and performance is
secondary, please refer to the [SHA
package](https://hackage.haskell.org/package/SHA).)
+.
+
+.
+Additionally, this package provides support for
+.
+- HMAC-SHA-256: SHA-256-based [Hashed Message Authentication
Codes](https://en.wikipedia.org/wiki/HMAC) (HMAC)
+- HKDF-SHA-256: [HMAC-SHA-256-based Key Derivation
Function](https://en.wikipedia.org/wiki/HKDF) (HKDF)
+.
+conforming to [RFC6234](https://tools.ietf.org/html/rfc6234),
[RFC4231](https://tools.ietf.org/html/rfc4231),
[RFC5869](https://tools.ietf.org/html/rfc5869), et al..
+.
+=== Relationship to the @cryptohash@ package and its API
+.
+This package has been originally a fork of @cryptohash-0.11.7@ because the
@cryptohash@
+package had been deprecated and so this package continues to satisfy the need
for a
+lightweight package providing the SHA-256 hash algorithm without any
dependencies on packages
+other than @base@ and @bytestring@. The API exposed by
@cryptohash-sha256-0.11.*@'s
+"Crypto.Hash.SHA256" module is guaranteed to remain a compatible superset of
the API provided
+by the @cryptohash-0.11.7@'s module of the same name.
+.
+Consequently, this package is designed to be used as a drop-in replacement for
@cryptohash-0.11.7@'s
+"Crypto.Hash.SHA256" module, though with
+a [clearly smaller footprint by almost 3 orders of
magnitude](https://www.reddit.com/r/haskell/comments/5lxv75/psa_please_use_unique_module_names_when_uploading/dbzegx3/).
+
+}
license: BSD3
license-file: LICENSE
@@ -23,37 +47,63 @@
maintainer: Herbert Valerio Riedel <[email protected]>
homepage: https://github.com/hvr/cryptohash-sha256
bug-reports: https://github.com/hvr/cryptohash-sha256/issues
-synopsis: Fast, pure and practical SHA-256 implementation
category: Data, Cryptography
build-type: Simple
-cabal-version: >=1.10
tested-with: GHC == 7.4.2
, GHC == 7.6.3
, GHC == 7.8.4
, GHC == 7.10.3
- , GHC == 8.0.1
+ , GHC == 8.0.2
+ , GHC == 8.2.1
+ , GHC == 8.4.1
-extra-source-files: cbits/sha256.h
+extra-source-files: cbits/hs_sha256.h
changelog.md
source-repository head
type: git
location: https://github.com/hvr/cryptohash-sha256.git
+flag exe
+ description: Enable building @sha256sum@ executable
+ manual: True
+ default: False
+
library
default-language: Haskell2010
- build-depends: base >= 4.5 && < 4.11
+ other-extensions: BangPatterns
+ CApiFFI
+ Trustworthy
+ Unsafe
+
+ build-depends: base >= 4.5 && < 4.12
, bytestring >= 0.9.2 && < 0.11
+ ghc-options: -Wall
+
hs-source-dirs: src
exposed-modules: Crypto.Hash.SHA256
- ghc-options: -Wall -fno-cse -O2
- cc-options: -Wall -O3
- c-sources: cbits/sha256.c
+ other-modules: Crypto.Hash.SHA256.FFI
include-dirs: cbits
+executable sha256sum
+ hs-source-dirs: src-exe
+ main-is: sha256sum.hs
+ ghc-options: -Wall -threaded
+ if flag(exe)
+ default-language: Haskell2010
+ other-extensions: RecordWildCards
+ build-depends: cryptohash-sha256
+ , base
+ , bytestring
+
+ , base16-bytestring >= 0.1.1 && < 0.2
+ else
+ buildable: False
+
test-suite test-sha256
default-language: Haskell2010
+ other-extensions: OverloadedStrings
type: exitcode-stdio-1.0
hs-source-dirs: src-tests
main-is: test-sha256.hs
@@ -70,6 +120,7 @@
benchmark bench-sha256
default-language: Haskell2010
+ other-extensions: BangPatterns
type: exitcode-stdio-1.0
main-is: bench-sha256.hs
hs-source-dirs: src-bench