aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2022-01-07 19:52:35 +0100
committerMattias Andrée <maandree@kth.se>2022-01-07 20:21:49 +0100
commit6adc0e6c6c378b5438533bdf55636ef049c1b956 (patch)
treeea55a4f54d7d190a1634c0a7ec8054fa2cdf47fd
parentlibblake_decode_hex: verify input (diff)
downloadlibblake-6adc0e6c6c378b5438533bdf55636ef049c1b956.tar.gz
libblake-6adc0e6c6c378b5438533bdf55636ef049c1b956.tar.bz2
libblake-6adc0e6c6c378b5438533bdf55636ef049c1b956.tar.xz
Add BLAKE2b and BLAKE2s + add salt support to BLAKE + m
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r--Makefile19
-rw-r--r--common.h3
-rw-r--r--config.mk2
-rw-r--r--libblake.h63
-rw-r--r--libblake_blake224_init.c11
-rw-r--r--libblake_blake224_init2.c27
-rw-r--r--libblake_blake256_init.c11
-rw-r--r--libblake_blake256_init2.c27
-rw-r--r--libblake_blake2b_digest.c59
-rw-r--r--libblake_blake2b_digest_get_required_input_size.c13
-rw-r--r--libblake_blake2b_init.c83
-rw-r--r--libblake_blake2b_update.c19
-rw-r--r--libblake_blake2s_digest.c47
-rw-r--r--libblake_blake2s_digest_get_required_input_size.c13
-rw-r--r--libblake_blake2s_init.c58
-rw-r--r--libblake_blake2s_update.c19
-rw-r--r--libblake_blake384_init.c11
-rw-r--r--libblake_blake384_init2.c31
-rw-r--r--libblake_blake512_init.c11
-rw-r--r--libblake_blake512_init2.c31
-rw-r--r--libblake_internal_blake2b_compress.c103
-rw-r--r--libblake_internal_blake2s_compress.c97
-rw-r--r--libblake_internal_blakeb_update.c40
-rw-r--r--libblake_internal_blakes_update.c40
-rw-r--r--test.c146
25 files changed, 900 insertions, 84 deletions
diff --git a/Makefile b/Makefile
index f8e34a8..0bd3b94 100644
--- a/Makefile
+++ b/Makefile
@@ -20,28 +20,45 @@ OBJ_BLAKE =\
libblake_blake224_digest.o\
libblake_blake224_digest_get_required_input_size.o\
libblake_blake224_init.o\
+ libblake_blake224_init2.o\
libblake_blake224_update.o\
libblake_blake256_digest.o\
libblake_blake256_digest_get_required_input_size.o\
libblake_blake256_init.o\
+ libblake_blake256_init2.o\
libblake_blake256_update.o\
libblake_blake384_digest.o\
libblake_blake384_digest_get_required_input_size.o\
libblake_blake384_init.o\
+ libblake_blake384_init2.o\
libblake_blake384_update.o\
libblake_blake512_digest.o\
libblake_blake512_digest_get_required_input_size.o\
libblake_blake512_init.o\
+ libblake_blake512_init2.o\
libblake_blake512_update.o\
libblake_internal_blakeb_digest.o\
libblake_internal_blakes_digest.o\
libblake_internal_blakeb_update.o\
libblake_internal_blakes_update.o
+OBJ_BLAKE2 =\
+ libblake_blake2b_digest.o\
+ libblake_blake2s_digest.o\
+ libblake_blake2b_digest_get_required_input_size.o\
+ libblake_blake2s_digest_get_required_input_size.o\
+ libblake_blake2b_init.o\
+ libblake_blake2s_init.o\
+ libblake_blake2b_update.o\
+ libblake_blake2s_update.o\
+ libblake_internal_blake2b_compress.o\
+ libblake_internal_blake2s_compress.o
+
OBJ =\
libblake_encode_hex.o\
libblake_decode_hex.o\
- $(OBJ_BLAKE)
+ $(OBJ_BLAKE)\
+ $(OBJ_BLAKE2)
HDR =\
libblake.h
diff --git a/common.h b/common.h
index 6ebab6f..740d37e 100644
--- a/common.h
+++ b/common.h
@@ -26,3 +26,6 @@ HIDDEN void libblake_internal_blakes_digest(struct libblake_blakes_state *state,
size_t bits, const char *suffix, unsigned char *output, size_t words_out);
HIDDEN void libblake_internal_blakeb_digest(struct libblake_blakeb_state *state, unsigned char *data, size_t len,
size_t bits, const char *suffix, unsigned char *output, size_t words_out);
+
+HIDDEN void libblake_internal_blake2s_compress(struct libblake_blake2s_state *state, const unsigned char *data);
+HIDDEN void libblake_internal_blake2b_compress(struct libblake_blake2b_state *state, const unsigned char *data);
diff --git a/config.mk b/config.mk
index e460701..bfe4895 100644
--- a/config.mk
+++ b/config.mk
@@ -4,5 +4,5 @@ MANPREFIX = $(PREFIX)/share/man
CC = c99
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_GNU_SOURCE
-CFLAGS = -Wall -O2
+CFLAGS = -Wall -O3
LDFLAGS = -s
diff --git a/libblake.h b/libblake.h
index 7d818fc..01dce32 100644
--- a/libblake.h
+++ b/libblake.h
@@ -7,13 +7,17 @@
#if defined(__GNUC__)
# define LIBBLAKE_PURE__ __attribute__((__pure__))
+# define LIBBLAKE_CONST__ __attribute__((__const__))
#else
# define LIBBLAKE_PURE__
+# define LIBBLAKE_CONST__
#endif
+
void libblake_encode_hex(const void *data, size_t n, char out[/* static n * 2 + 1 */], int uppercase);
size_t libblake_decode_hex(const char *data, size_t n, void *out, int *validp);
+
#define LIBBLAKE_BLAKE224_OUTPUT_SIZE (224 / 8)
#define LIBBLAKE_BLAKE256_OUTPUT_SIZE (256 / 8)
#define LIBBLAKE_BLAKE384_OUTPUT_SIZE (384 / 8)
@@ -37,27 +41,86 @@ struct libblake_blake384_state { struct libblake_blakeb_state b; };
struct libblake_blake512_state { struct libblake_blakeb_state b; };
void libblake_blake224_init(struct libblake_blake224_state *state);
+void libblake_blake224_init2(struct libblake_blake224_state *state, uint_least8_t salt[16]);
size_t libblake_blake224_update(struct libblake_blake224_state *state, const void *data, size_t len);
void libblake_blake224_digest(struct libblake_blake224_state *state, void *data, size_t len, size_t bits,
const char *suffix, unsigned char output[static LIBBLAKE_BLAKE224_OUTPUT_SIZE]);
LIBBLAKE_PURE__ size_t libblake_blake224_digest_get_required_input_size(size_t len, size_t bits, const char *suffix);
void libblake_blake256_init(struct libblake_blake256_state *state);
+void libblake_blake256_init2(struct libblake_blake256_state *state, uint_least8_t salt[16]);
size_t libblake_blake256_update(struct libblake_blake256_state *state, const void *data, size_t len);
void libblake_blake256_digest(struct libblake_blake256_state *state, void *data, size_t len, size_t bits,
const char *suffix, unsigned char output[static LIBBLAKE_BLAKE256_OUTPUT_SIZE]);
LIBBLAKE_PURE__ size_t libblake_blake256_digest_get_required_input_size(size_t len, size_t bits, const char *suffix);
void libblake_blake384_init(struct libblake_blake384_state *state);
+void libblake_blake384_init2(struct libblake_blake384_state *state, uint_least8_t salt[32]);
size_t libblake_blake384_update(struct libblake_blake384_state *state, const void *data, size_t len);
void libblake_blake384_digest(struct libblake_blake384_state *state, void *data, size_t len, size_t bits,
const char *suffix, unsigned char output[static LIBBLAKE_BLAKE384_OUTPUT_SIZE]);
LIBBLAKE_PURE__ size_t libblake_blake384_digest_get_required_input_size(size_t len, size_t bits, const char *suffix);
void libblake_blake512_init(struct libblake_blake512_state *state);
+void libblake_blake512_init2(struct libblake_blake512_state *state, uint_least8_t salt[32]);
size_t libblake_blake512_update(struct libblake_blake512_state *state, const void *data, size_t len);
void libblake_blake512_digest(struct libblake_blake512_state *state, void *data, size_t len, size_t bits,
const char *suffix, unsigned char output[static LIBBLAKE_BLAKE512_OUTPUT_SIZE]);
LIBBLAKE_PURE__ size_t libblake_blake512_digest_get_required_input_size(size_t len, size_t bits, const char *suffix);
+
+struct libblake_blake2s_params {
+ uint_least8_t digest_len; /* in bytes, [1, 32] */
+ uint_least8_t key_len; /* in bytes, [0, 32] */
+ uint_least8_t fanout; /* normally 1 */
+ uint_least8_t depth; /* normally 1 */
+ uint_least32_t leaf_len;
+ uint_least32_t node_offset;
+ uint_least16_t xof_len;
+ uint_least8_t node_depth;
+ uint_least8_t inner_len;
+ uint_least8_t salt[8];
+ uint_least8_t pepper[8];
+};
+
+struct libblake_blake2b_params {
+ uint_least8_t digest_len; /* in bytes, [1, 64] */
+ uint_least8_t key_len; /* in bytes, [0, 64] */
+ uint_least8_t fanout; /* normally 1 */
+ uint_least8_t depth; /* normally 1 */
+ uint_least32_t leaf_len;
+ uint_least32_t node_offset;
+ uint_least32_t xof_len;
+ uint_least8_t node_depth;
+ uint_least8_t inner_len;
+ uint_least8_t salt[16];
+ uint_least8_t pepper[16];
+};
+
+struct libblake_blake2s_state {
+ uint_least32_t h[8];
+ uint_least32_t t[2];
+ uint_least32_t f[2];
+};
+
+struct libblake_blake2b_state {
+ uint_least64_t h[8];
+ uint_least64_t t[2];
+ uint_least64_t f[2];
+};
+
+void libblake_blake2s_init(struct libblake_blake2s_state *state, const struct libblake_blake2s_params *params,
+ const unsigned char *key /* append null bytes until 64 bytes; if key is used */);
+size_t libblake_blake2s_update(struct libblake_blake2s_state *state, const void *data, size_t len);
+void libblake_blake2s_digest(struct libblake_blake2s_state *state, void *data, size_t len,
+ size_t output_len, unsigned char output[static output_len]);
+LIBBLAKE_CONST__ size_t libblake_blake2s_digest_get_required_input_size(size_t len);
+
+void libblake_blake2b_init(struct libblake_blake2b_state *state, const struct libblake_blake2b_params *params,
+ const unsigned char *key /* append null bytes until 128 bytes; if key is used */);
+size_t libblake_blake2b_update(struct libblake_blake2b_state *state, const void *data, size_t len);
+void libblake_blake2b_digest(struct libblake_blake2b_state *state, void *data, size_t len,
+ size_t output_len, unsigned char output[static output_len]);
+LIBBLAKE_CONST__ size_t libblake_blake2b_digest_get_required_input_size(size_t len);
+
#endif
diff --git a/libblake_blake224_init.c b/libblake_blake224_init.c
index 0eb67e0..f133887 100644
--- a/libblake_blake224_init.c
+++ b/libblake_blake224_init.c
@@ -4,14 +4,5 @@
void
libblake_blake224_init(struct libblake_blake224_state *state)
{
- state->s.h[0] = UINT_LEAST32_C(0xC1059ED8);
- state->s.h[1] = UINT_LEAST32_C(0x367CD507);
- state->s.h[2] = UINT_LEAST32_C(0x3070DD17);
- state->s.h[3] = UINT_LEAST32_C(0xF70E5939);
- state->s.h[4] = UINT_LEAST32_C(0xFFC00B31);
- state->s.h[5] = UINT_LEAST32_C(0x68581511);
- state->s.h[6] = UINT_LEAST32_C(0x64F98FA7);
- state->s.h[7] = UINT_LEAST32_C(0xBEFA4FA4);
- memset(state->s.s, 0, sizeof(state->s.s));
- memset(state->s.t, 0, sizeof(state->s.t));
+ libblake_blake224_init2(state, NULL);
}
diff --git a/libblake_blake224_init2.c b/libblake_blake224_init2.c
new file mode 100644
index 0000000..c67eff1
--- /dev/null
+++ b/libblake_blake224_init2.c
@@ -0,0 +1,27 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+void
+libblake_blake224_init2(struct libblake_blake224_state *state, uint_least8_t salt[16])
+{
+ size_t i;
+ state->s.h[0] = UINT_LEAST32_C(0xC1059ED8);
+ state->s.h[1] = UINT_LEAST32_C(0x367CD507);
+ state->s.h[2] = UINT_LEAST32_C(0x3070DD17);
+ state->s.h[3] = UINT_LEAST32_C(0xF70E5939);
+ state->s.h[4] = UINT_LEAST32_C(0xFFC00B31);
+ state->s.h[5] = UINT_LEAST32_C(0x68581511);
+ state->s.h[6] = UINT_LEAST32_C(0x64F98FA7);
+ state->s.h[7] = UINT_LEAST32_C(0xBEFA4FA4);
+ if (!salt) {
+ memset(state->s.s, 0, sizeof(state->s.s));
+ } else {
+ for (i = 0; i < 4; i++) {
+ state->s.s[i] = ((uint_least32_t)(salt[i * 4 + 0] & 255) << 24)
+ | ((uint_least32_t)(salt[i * 4 + 1] & 255) << 16)
+ | ((uint_least32_t)(salt[i * 4 + 2] & 255) << 8)
+ | ((uint_least32_t)(salt[i * 4 + 3] & 255) << 0);
+ }
+ }
+ memset(state->s.t, 0, sizeof(state->s.t));
+}
diff --git a/libblake_blake256_init.c b/libblake_blake256_init.c
index 2a95b8d..78d1978 100644
--- a/libblake_blake256_init.c
+++ b/libblake_blake256_init.c
@@ -4,14 +4,5 @@
void
libblake_blake256_init(struct libblake_blake256_state *state)
{
- state->s.h[0] = UINT_LEAST32_C(0x6A09E667);
- state->s.h[1] = UINT_LEAST32_C(0xBB67AE85);
- state->s.h[2] = UINT_LEAST32_C(0x3C6EF372);
- state->s.h[3] = UINT_LEAST32_C(0xA54FF53A);
- state->s.h[4] = UINT_LEAST32_C(0x510E527F);
- state->s.h[5] = UINT_LEAST32_C(0x9B05688C);
- state->s.h[6] = UINT_LEAST32_C(0x1F83D9AB);
- state->s.h[7] = UINT_LEAST32_C(0x5BE0CD19);
- memset(state->s.s, 0, sizeof(state->s.s));
- memset(state->s.t, 0, sizeof(state->s.t));
+ libblake_blake256_init2(state, NULL);
}
diff --git a/libblake_blake256_init2.c b/libblake_blake256_init2.c
new file mode 100644
index 0000000..271df7d
--- /dev/null
+++ b/libblake_blake256_init2.c
@@ -0,0 +1,27 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+void
+libblake_blake256_init2(struct libblake_blake256_state *state, uint_least8_t salt[16])
+{
+ size_t i;
+ state->s.h[0] = UINT_LEAST32_C(0x6A09E667);
+ state->s.h[1] = UINT_LEAST32_C(0xBB67AE85);
+ state->s.h[2] = UINT_LEAST32_C(0x3C6EF372);
+ state->s.h[3] = UINT_LEAST32_C(0xA54FF53A);
+ state->s.h[4] = UINT_LEAST32_C(0x510E527F);
+ state->s.h[5] = UINT_LEAST32_C(0x9B05688C);
+ state->s.h[6] = UINT_LEAST32_C(0x1F83D9AB);
+ state->s.h[7] = UINT_LEAST32_C(0x5BE0CD19);
+ if (!salt) {
+ memset(state->s.s, 0, sizeof(state->s.s));
+ } else {
+ for (i = 0; i < 4; i++) {
+ state->s.s[i] = ((uint_least32_t)(salt[i * 4 + 0] & 255) << 24)
+ | ((uint_least32_t)(salt[i * 4 + 1] & 255) << 16)
+ | ((uint_least32_t)(salt[i * 4 + 2] & 255) << 8)
+ | ((uint_least32_t)(salt[i * 4 + 3] & 255) << 0);
+ }
+ }
+ memset(state->s.t, 0, sizeof(state->s.t));
+}
diff --git a/libblake_blake2b_digest.c b/libblake_blake2b_digest.c
new file mode 100644
index 0000000..f1e45a8
--- /dev/null
+++ b/libblake_blake2b_digest.c
@@ -0,0 +1,59 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+static void
+encode_uint64_le(unsigned char *out, uint_least64_t value, size_t bytes)
+{
+ switch (bytes) {
+ default:
+ out[7] = (unsigned char)((value >> 56) & 255);
+ /* fall through */
+ case 7:
+ out[6] = (unsigned char)((value >> 48) & 255);
+ /* fall through */
+ case 6:
+ out[5] = (unsigned char)((value >> 40) & 255);
+ /* fall through */
+ case 5:
+ out[4] = (unsigned char)((value >> 32) & 255);
+ /* fall through */
+ case 4:
+ out[3] = (unsigned char)((value >> 24) & 255);
+ /* fall through */
+ case 3:
+ out[2] = (unsigned char)((value >> 16) & 255);
+ /* fall through */
+ case 2:
+ out[1] = (unsigned char)((value >> 8) & 255);
+ /* fall through */
+ case 1:
+ out[0] = (unsigned char)((value >> 0) & 255);
+ /* fall through */
+ case 0:
+ break;
+ }
+}
+
+void
+libblake_blake2b_digest(struct libblake_blake2b_state *state, void *data_, size_t len,
+ size_t output_len, unsigned char output[static output_len])
+{
+ unsigned char *data = data_;
+ size_t r, i, j;
+
+ r = libblake_blake2b_update(state, data, len);
+ data = &data[r];
+ len -= r;
+
+ state->f[0] = UINT_LEAST64_C(0xFFFFffffFFFFffff);
+ memset(&data[len], 0, 128 - len);
+
+ state->t[0] = (state->t[0] + len) & UINT_LEAST64_C(0xFFFFffffFFFFffff);
+ if (state->t[0] < len)
+ state->t[1] = (state->t[1] + 1) & UINT_LEAST64_C(0xFFFFffffFFFFffff);
+
+ libblake_internal_blake2b_compress(state, data);
+
+ for (i = 0, j = 0; i < output_len; i += 8, j += 1)
+ encode_uint64_le(&output[i], state->h[j], output_len - i);
+}
diff --git a/libblake_blake2b_digest_get_required_input_size.c b/libblake_blake2b_digest_get_required_input_size.c
new file mode 100644
index 0000000..12288df
--- /dev/null
+++ b/libblake_blake2b_digest_get_required_input_size.c
@@ -0,0 +1,13 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+size_t
+libblake_blake2b_digest_get_required_input_size(size_t len)
+{
+ size_t blocks, rem;
+ blocks = len >> 7;
+ rem = len & 127;
+ if (rem)
+ blocks += 1;
+ return blocks << 7;
+}
diff --git a/libblake_blake2b_init.c b/libblake_blake2b_init.c
new file mode 100644
index 0000000..7de9bb2
--- /dev/null
+++ b/libblake_blake2b_init.c
@@ -0,0 +1,83 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+#define A 10
+#define B 11
+#define C 12
+#define D 13
+#define E 14
+#define F 15
+
+void
+libblake_blake2b_init(struct libblake_blake2b_state *state, const struct libblake_blake2b_params *params, const unsigned char *key)
+{
+ state->h[0] = UINT_LEAST64_C(0x6A09E667F3BCC908);
+ state->h[1] = UINT_LEAST64_C(0xBB67AE8584CAA73B);
+ state->h[2] = UINT_LEAST64_C(0x3C6EF372FE94F82B);
+ state->h[3] = UINT_LEAST64_C(0xA54FF53A5F1D36F1);
+ state->h[4] = UINT_LEAST64_C(0x510E527FADE682D1);
+ state->h[5] = UINT_LEAST64_C(0x9B05688C2B3E6C1F);
+ state->h[6] = UINT_LEAST64_C(0x1F83D9ABFB41BD6B);
+ state->h[7] = UINT_LEAST64_C(0x5BE0CD19137E2179);
+
+ state->t[0] = 0;
+ state->t[1] = 0;
+ state->f[0] = 0;
+ state->f[1] = 0;
+
+ state->h[0] ^= ((uint_least64_t)params->digest_len & 255) << 0;
+ state->h[0] ^= ((uint_least64_t)params->key_len & 255) << 8;
+ state->h[0] ^= ((uint_least64_t)params->fanout & 255) << 16;
+ state->h[0] ^= ((uint_least64_t)params->depth & 255) << 24;
+ state->h[0] ^= ((uint_least64_t)(params->leaf_len >> 0) & 255) << 32;
+ state->h[0] ^= ((uint_least64_t)(params->leaf_len >> 8) & 255) << 40;
+ state->h[0] ^= ((uint_least64_t)(params->leaf_len >> 16) & 255) << 48;
+ state->h[0] ^= ((uint_least64_t)(params->leaf_len >> 24) & 255) << 56;
+ state->h[1] ^= ((uint_least64_t)(params->node_offset >> 0) & 255) << 0;
+ state->h[1] ^= ((uint_least64_t)(params->node_offset >> 8) & 255) << 8;
+ state->h[1] ^= ((uint_least64_t)(params->node_offset >> 16) & 255) << 16;
+ state->h[1] ^= ((uint_least64_t)(params->node_offset >> 24) & 255) << 24;
+ state->h[1] ^= ((uint_least64_t)(params->xof_len >> 0) & 255) << 32;
+ state->h[1] ^= ((uint_least64_t)(params->xof_len >> 8) & 255) << 40;
+ state->h[1] ^= ((uint_least64_t)(params->xof_len >> 16) & 255) << 48;
+ state->h[1] ^= ((uint_least64_t)(params->xof_len >> 24) & 255) << 56;
+ state->h[2] ^= ((uint_least64_t)params->node_depth & 255) << 0;
+ state->h[2] ^= ((uint_least64_t)params->inner_len & 255) << 8;
+ state->h[4] ^= ((uint_least64_t)params->salt[0] & 255) << 0;
+ state->h[4] ^= ((uint_least64_t)params->salt[1] & 255) << 8;
+ state->h[4] ^= ((uint_least64_t)params->salt[2] & 255) << 16;
+ state->h[4] ^= ((uint_least64_t)params->salt[3] & 255) << 24;
+ state->h[4] ^= ((uint_least64_t)params->salt[4] & 255) << 32;
+ state->h[4] ^= ((uint_least64_t)params->salt[5] & 255) << 40;
+ state->h[4] ^= ((uint_least64_t)params->salt[6] & 255) << 48;
+ state->h[4] ^= ((uint_least64_t)params->salt[7] & 255) << 56;
+ state->h[5] ^= ((uint_least64_t)params->salt[8] & 255) << 0;
+ state->h[5] ^= ((uint_least64_t)params->salt[9] & 255) << 8;
+ state->h[5] ^= ((uint_least64_t)params->salt[A] & 255) << 16;
+ state->h[5] ^= ((uint_least64_t)params->salt[B] & 255) << 24;
+ state->h[5] ^= ((uint_least64_t)params->salt[C] & 255) << 32;
+ state->h[5] ^= ((uint_least64_t)params->salt[D] & 255) << 40;
+ state->h[5] ^= ((uint_least64_t)params->salt[E] & 255) << 48;
+ state->h[5] ^= ((uint_least64_t)params->salt[F] & 255) << 56;
+ state->h[6] ^= ((uint_least64_t)params->pepper[0] & 255) << 0;
+ state->h[6] ^= ((uint_least64_t)params->pepper[1] & 255) << 8;
+ state->h[6] ^= ((uint_least64_t)params->pepper[2] & 255) << 16;
+ state->h[6] ^= ((uint_least64_t)params->pepper[3] & 255) << 24;
+ state->h[6] ^= ((uint_least64_t)params->pepper[4] & 255) << 32;
+ state->h[6] ^= ((uint_least64_t)params->pepper[5] & 255) << 40;
+ state->h[6] ^= ((uint_least64_t)params->pepper[6] & 255) << 48;
+ state->h[6] ^= ((uint_least64_t)params->pepper[7] & 255) << 56;
+ state->h[7] ^= ((uint_least64_t)params->pepper[8] & 255) << 0;
+ state->h[7] ^= ((uint_least64_t)params->pepper[9] & 255) << 8;
+ state->h[7] ^= ((uint_least64_t)params->pepper[A] & 255) << 16;
+ state->h[7] ^= ((uint_least64_t)params->pepper[B] & 255) << 24;
+ state->h[7] ^= ((uint_least64_t)params->pepper[C] & 255) << 32;
+ state->h[7] ^= ((uint_least64_t)params->pepper[D] & 255) << 40;
+ state->h[7] ^= ((uint_least64_t)params->pepper[E] & 255) << 48;
+ state->h[7] ^= ((uint_least64_t)params->pepper[F] & 255) << 56;
+
+ if (params->key_len) {
+ state->t[0] = 128;
+ libblake_internal_blake2b_compress(state, key);
+ }
+}
diff --git a/libblake_blake2b_update.c b/libblake_blake2b_update.c
new file mode 100644
index 0000000..cbd38f2
--- /dev/null
+++ b/libblake_blake2b_update.c
@@ -0,0 +1,19 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+size_t
+libblake_blake2b_update(struct libblake_blake2b_state *state, const void *data_, size_t len)
+{
+ const unsigned char *data = data_;
+ size_t off = 0;
+
+ for (; len - off > 128; off += 128) {
+ state->t[0] = (state->t[0] + 128) & UINT_LEAST64_C(0xFFFFffffFFFFffff);
+ if (state->t[0] < 128)
+ state->t[1] = (state->t[1] + 1) & UINT_LEAST64_C(0xFFFFffffFFFFffff);
+
+ libblake_internal_blake2b_compress(state, &data[off]);
+ }
+
+ return off;
+}
diff --git a/libblake_blake2s_digest.c b/libblake_blake2s_digest.c
new file mode 100644
index 0000000..d9106a5
--- /dev/null
+++ b/libblake_blake2s_digest.c
@@ -0,0 +1,47 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+static void
+encode_uint32_le(unsigned char *out, uint_least32_t value, size_t bytes)
+{
+ switch (bytes) {
+ default:
+ out[3] = (unsigned char)((value >> 24) & 255);
+ /* fall through */
+ case 3:
+ out[2] = (unsigned char)((value >> 16) & 255);
+ /* fall through */
+ case 2:
+ out[1] = (unsigned char)((value >> 8) & 255);
+ /* fall through */
+ case 1:
+ out[0] = (unsigned char)((value >> 0) & 255);
+ /* fall through */
+ case 0:
+ break;
+ }
+}
+
+void
+libblake_blake2s_digest(struct libblake_blake2s_state *state, void *data_, size_t len,
+ size_t output_len, unsigned char output[static output_len])
+{
+ unsigned char *data = data_;
+ size_t r, i, j;
+
+ r = libblake_blake2s_update(state, data, len);
+ data = &data[r];
+ len -= r;
+
+ state->f[0] = UINT_LEAST32_C(0xFFFFffff);
+ memset(&data[len], 0, 64 - len);
+
+ state->t[0] = (state->t[0] + len) & UINT_LEAST32_C(0xFFFFffff);
+ if (state->t[0] < len)
+ state->t[1] = (state->t[1] + 1) & UINT_LEAST32_C(0xFFFFffff);
+
+ libblake_internal_blake2s_compress(state, data);
+
+ for (i = 0, j = 0; i < output_len; i += 4, j += 1)
+ encode_uint32_le(&output[i], state->h[j], output_len - i);
+}
diff --git a/libblake_blake2s_digest_get_required_input_size.c b/libblake_blake2s_digest_get_required_input_size.c
new file mode 100644
index 0000000..c356822
--- /dev/null
+++ b/libblake_blake2s_digest_get_required_input_size.c
@@ -0,0 +1,13 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+size_t
+libblake_blake2s_digest_get_required_input_size(size_t len)
+{
+ size_t blocks, rem;
+ blocks = len >> 6;
+ rem = len & 63;
+ if (rem)
+ blocks += 1;
+ return blocks << 6;
+}
diff --git a/libblake_blake2s_init.c b/libblake_blake2s_init.c
new file mode 100644
index 0000000..d33ce5c
--- /dev/null
+++ b/libblake_blake2s_init.c
@@ -0,0 +1,58 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+void
+libblake_blake2s_init(struct libblake_blake2s_state *state, const struct libblake_blake2s_params *params, const unsigned char *key)
+{
+ state->h[0] = UINT_LEAST32_C(0x6A09E667);
+ state->h[1] = UINT_LEAST32_C(0xBB67AE85);
+ state->h[2] = UINT_LEAST32_C(0x3C6EF372);
+ state->h[3] = UINT_LEAST32_C(0xA54FF53A);
+ state->h[4] = UINT_LEAST32_C(0x510E527F);
+ state->h[5] = UINT_LEAST32_C(0x9B05688C);
+ state->h[6] = UINT_LEAST32_C(0x1F83D9AB);
+ state->h[7] = UINT_LEAST32_C(0x5BE0CD19);
+
+ state->t[0] = 0;
+ state->t[1] = 0;
+ state->f[0] = 0;
+ state->f[1] = 0;
+
+ state->h[0] ^= ((uint_least32_t)params->digest_len & 255) << 0;
+ state->h[0] ^= ((uint_least32_t)params->key_len & 255) << 8;
+ state->h[0] ^= ((uint_least32_t)params->fanout & 255) << 16;
+ state->h[0] ^= ((uint_least32_t)params->depth & 255) << 24;
+ state->h[1] ^= ((uint_least32_t)(params->leaf_len >> 0) & 255) << 0;
+ state->h[1] ^= ((uint_least32_t)(params->leaf_len >> 8) & 255) << 8;
+ state->h[1] ^= ((uint_least32_t)(params->leaf_len >> 16) & 255) << 16;
+ state->h[1] ^= ((uint_least32_t)(params->leaf_len >> 24) & 255) << 24;
+ state->h[2] ^= ((uint_least32_t)(params->node_offset >> 0) & 255) << 0;
+ state->h[2] ^= ((uint_least32_t)(params->node_offset >> 8) & 255) << 8;
+ state->h[2] ^= ((uint_least32_t)(params->node_offset >> 16) & 255) << 16;
+ state->h[2] ^= ((uint_least32_t)(params->node_offset >> 24) & 255) << 24;
+ state->h[3] ^= ((uint_least32_t)(params->xof_len >> 0) & 255) << 0;
+ state->h[3] ^= ((uint_least32_t)(params->xof_len >> 8) & 255) << 8;
+ state->h[3] ^= ((uint_least32_t)params->node_depth & 255) << 16;
+ state->h[3] ^= ((uint_least32_t)params->inner_len & 255) << 24;
+ state->h[4] ^= ((uint_least32_t)params->salt[0] & 255) << 0;
+ state->h[4] ^= ((uint_least32_t)params->salt[1] & 255) << 8;
+ state->h[4] ^= ((uint_least32_t)params->salt[2] & 255) << 16;
+ state->h[4] ^= ((uint_least32_t)params->salt[3] & 255) << 24;
+ state->h[5] ^= ((uint_least32_t)params->salt[4] & 255) << 0;
+ state->h[5] ^= ((uint_least32_t)params->salt[5] & 255) << 8;
+ state->h[5] ^= ((uint_least32_t)params->salt[6] & 255) << 16;
+ state->h[5] ^= ((uint_least32_t)params->salt[7] & 255) << 24;
+ state->h[6] ^= ((uint_least32_t)params->pepper[0] & 255) << 0;
+ state->h[6] ^= ((uint_least32_t)params->pepper[1] & 255) << 8;
+ state->h[6] ^= ((uint_least32_t)params->pepper[2] & 255) << 16;
+ state->h[6] ^= ((uint_least32_t)params->pepper[3] & 255) << 24;
+ state->h[7] ^= ((uint_least32_t)params->pepper[4] & 255) << 0;
+ state->h[7] ^= ((uint_least32_t)params->pepper[5] & 255) << 8;
+ state->h[7] ^= ((uint_least32_t)params->pepper[6] & 255) << 16;
+ state->h[7] ^= ((uint_least32_t)params->pepper[7] & 255) << 24;
+
+ if (params->key_len) {
+ state->t[0] = 32;
+ libblake_internal_blake2s_compress(state, key);
+ }
+}
diff --git a/libblake_blake2s_update.c b/libblake_blake2s_update.c
new file mode 100644
index 0000000..598260f
--- /dev/null
+++ b/libblake_blake2s_update.c
@@ -0,0 +1,19 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+size_t
+libblake_blake2s_update(struct libblake_blake2s_state *state, const void *data_, size_t len)
+{
+ const unsigned char *data = data_;
+ size_t off = 0;
+
+ for (; len - off > 64; off += 64) {
+ state->t[0] = (state->t[0] + 64) & UINT_LEAST32_C(0xFFFFffff);
+ if (state->t[0] < 64)
+ state->t[1] = (state->t[1] + 1) & UINT_LEAST32_C(0xFFFFffff);
+
+ libblake_internal_blake2s_compress(state, &data[off]);
+ }
+
+ return off;
+}
diff --git a/libblake_blake384_init.c b/libblake_blake384_init.c
index b7529f3..a08509a 100644
--- a/libblake_blake384_init.c
+++ b/libblake_blake384_init.c
@@ -4,14 +4,5 @@
void
libblake_blake384_init(struct libblake_blake384_state *state)
{
- state->b.h[0] = UINT_LEAST64_C(0xCBBB9D5DC1059ED8);
- state->b.h[1] = UINT_LEAST64_C(0x629A292A367CD507);
- state->b.h[2] = UINT_LEAST64_C(0x9159015A3070DD17);
- state->b.h[3] = UINT_LEAST64_C(0x152FECD8F70E5939);
- state->b.h[4] = UINT_LEAST64_C(0x67332667FFC00B31);
- state->b.h[5] = UINT_LEAST64_C(0x8EB44A8768581511);
- state->b.h[6] = UINT_LEAST64_C(0xDB0C2E0D64F98FA7);
- state->b.h[7] = UINT_LEAST64_C(0x47B5481DBEFA4FA4);
- memset(state->b.s, 0, sizeof(state->b.s));
- memset(state->b.t, 0, sizeof(state->b.t));
+ libblake_blake384_init2(state, NULL);
}
diff --git a/libblake_blake384_init2.c b/libblake_blake384_init2.c
new file mode 100644
index 0000000..1ea2137
--- /dev/null
+++ b/libblake_blake384_init2.c
@@ -0,0 +1,31 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+void
+libblake_blake384_init2(struct libblake_blake384_state *state, uint_least8_t salt[32])
+{
+ size_t i;
+ state->b.h[0] = UINT_LEAST64_C(0xCBBB9D5DC1059ED8);
+ state->b.h[1] = UINT_LEAST64_C(0x629A292A367CD507);
+ state->b.h[2] = UINT_LEAST64_C(0x9159015A3070DD17);
+ state->b.h[3] = UINT_LEAST64_C(0x152FECD8F70E5939);
+ state->b.h[4] = UINT_LEAST64_C(0x67332667FFC00B31);
+ state->b.h[5] = UINT_LEAST64_C(0x8EB44A8768581511);
+ state->b.h[6] = UINT_LEAST64_C(0xDB0C2E0D64F98FA7);
+ state->b.h[7] = UINT_LEAST64_C(0x47B5481DBEFA4FA4);
+ if (!salt) {
+ memset(state->b.s, 0, sizeof(state->b.s));
+ } else {
+ for (i = 0; i < 4; i++) {
+ state->b.s[i] = ((uint_least64_t)(salt[i * 8 + 0] & 255) << 56)
+ | ((uint_least64_t)(salt[i * 8 + 1] & 255) << 48)
+ | ((uint_least64_t)(salt[i * 8 + 2] & 255) << 40)
+ | ((uint_least64_t)(salt[i * 8 + 3] & 255) << 32)
+ | ((uint_least64_t)(salt[i * 8 + 4] & 255) << 24)
+ | ((uint_least64_t)(salt[i * 8 + 5] & 255) << 16)
+ | ((uint_least64_t)(salt[i * 8 + 6] & 255) << 8)
+ | ((uint_least64_t)(salt[i * 8 + 7] & 255) << 0);
+ }
+ }
+ memset(state->b.t, 0, sizeof(state->b.t));
+}
diff --git a/libblake_blake512_init.c b/libblake_blake512_init.c
index 85d011f..e45fb9e 100644
--- a/libblake_blake512_init.c
+++ b/libblake_blake512_init.c
@@ -4,14 +4,5 @@
void
libblake_blake512_init(struct libblake_blake512_state *state)
{
- state->b.h[0] = UINT_LEAST64_C(0x6A09E667F3BCC908);
- state->b.h[1] = UINT_LEAST64_C(0xBB67AE8584CAA73B);
- state->b.h[2] = UINT_LEAST64_C(0x3C6EF372FE94F82B);
- state->b.h[3] = UINT_LEAST64_C(0xA54FF53A5F1D36F1);
- state->b.h[4] = UINT_LEAST64_C(0x510E527FADE682D1);
- state->b.h[5] = UINT_LEAST64_C(0x9B05688C2B3E6C1F);
- state->b.h[6] = UINT_LEAST64_C(0x1F83D9ABFB41BD6B);
- state->b.h[7] = UINT_LEAST64_C(0x5BE0CD19137E2179);
- memset(state->b.s, 0, sizeof(state->b.s));
- memset(state->b.t, 0, sizeof(state->b.t));
+ libblake_blake512_init2(state, NULL);
}
diff --git a/libblake_blake512_init2.c b/libblake_blake512_init2.c
new file mode 100644
index 0000000..5363e7f
--- /dev/null
+++ b/libblake_blake512_init2.c
@@ -0,0 +1,31 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+void
+libblake_blake512_init2(struct libblake_blake512_state *state, uint_least8_t salt[32])
+{
+ size_t i;
+ state->b.h[0] = UINT_LEAST64_C(0x6A09E667F3BCC908);
+ state->b.h[1] = UINT_LEAST64_C(0xBB67AE8584CAA73B);
+ state->b.h[2] = UINT_LEAST64_C(0x3C6EF372FE94F82B);
+ state->b.h[3] = UINT_LEAST64_C(0xA54FF53A5F1D36F1);
+ state->b.h[4] = UINT_LEAST64_C(0x510E527FADE682D1);
+ state->b.h[5] = UINT_LEAST64_C(0x9B05688C2B3E6C1F);
+ state->b.h[6] = UINT_LEAST64_C(0x1F83D9ABFB41BD6B);
+ state->b.h[7] = UINT_LEAST64_C(0x5BE0CD19137E2179);
+ if (!salt) {
+ memset(state->b.s, 0, sizeof(state->b.s));
+ } else {
+ for (i = 0; i < 4; i++) {
+ state->b.s[i] = ((uint_least64_t)(salt[i * 8 + 0] & 255) << 56)
+ | ((uint_least64_t)(salt[i * 8 + 1] & 255) << 48)
+ | ((uint_least64_t)(salt[i * 8 + 2] & 255) << 40)
+ | ((uint_least64_t)(salt[i * 8 + 3] & 255) << 32)
+ | ((uint_least64_t)(salt[i * 8 + 4] & 255) << 24)
+ | ((uint_least64_t)(salt[i * 8 + 5] & 255) << 16)
+ | ((uint_least64_t)(salt[i * 8 + 6] & 255) << 8)
+ | ((uint_least64_t)(salt[i * 8 + 7] & 255) << 0);
+ }
+ }
+ memset(state->b.t, 0, sizeof(state->b.t));
+}
diff --git a/libblake_internal_blake2b_compress.c b/libblake_internal_blake2b_compress.c
new file mode 100644
index 0000000..eab4b44
--- /dev/null
+++ b/libblake_internal_blake2b_compress.c
@@ -0,0 +1,103 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+#define A 10
+#define B 11
+#define C 12
+#define D 13
+#define E 14
+#define F 15
+
+static uint_least64_t
+decode_uint64_le(const unsigned char *data)
+{
+ return (((uint_least64_t)(data[0] & 255)) << 0) |
+ (((uint_least64_t)(data[1] & 255)) << 8) |
+ (((uint_least64_t)(data[2] & 255)) << 16) |
+ (((uint_least64_t)(data[3] & 255)) << 24) |
+ (((uint_least64_t)(data[4] & 255)) << 32) |
+ (((uint_least64_t)(data[5] & 255)) << 40) |
+ (((uint_least64_t)(data[6] & 255)) << 48) |
+ (((uint_least64_t)(data[7] & 255)) << 56);
+}
+
+static uint_least64_t
+rotate_right(uint_least64_t x, int n)
+{
+ return ((x >> n) | (x << (64 - n))) & UINT_LEAST64_C(0xFFFFffffFFFFffff);
+}
+
+void
+libblake_internal_blake2b_compress(struct libblake_blake2b_state *state, const unsigned char *data)
+{
+ uint_least64_t v[16], m[16];
+
+ memcpy(v, state->h, sizeof(state->h));
+ v[8] = UINT_LEAST64_C(0x6A09E667F3BCC908);
+ v[9] = UINT_LEAST64_C(0xBB67AE8584CAA73B);
+ v[A] = UINT_LEAST64_C(0x3C6EF372FE94F82B);
+ v[B] = UINT_LEAST64_C(0xA54FF53A5F1D36F1);
+ v[C] = UINT_LEAST64_C(0x510E527FADE682D1) ^ state->t[0];
+ v[D] = UINT_LEAST64_C(0x9B05688C2B3E6C1F) ^ state->t[1];
+ v[E] = UINT_LEAST64_C(0x1F83D9ABFB41BD6B) ^ state->f[0];
+ v[F] = UINT_LEAST64_C(0x5BE0CD19137E2179) ^ state->f[1];
+
+ m[0] = decode_uint64_le(&data[0 * 8]);
+ m[1] = decode_uint64_le(&data[1 * 8]);
+ m[2] = decode_uint64_le(&data[2 * 8]);
+ m[3] = decode_uint64_le(&data[3 * 8]);
+ m[4] = decode_uint64_le(&data[4 * 8]);
+ m[5] = decode_uint64_le(&data[5 * 8]);
+ m[6] = decode_uint64_le(&data[6 * 8]);
+ m[7] = decode_uint64_le(&data[7 * 8]);
+ m[8] = decode_uint64_le(&data[8 * 8]);
+ m[9] = decode_uint64_le(&data[9 * 8]);
+ m[A] = decode_uint64_le(&data[A * 8]);
+ m[B] = decode_uint64_le(&data[B * 8]);
+ m[C] = decode_uint64_le(&data[C * 8]);
+ m[D] = decode_uint64_le(&data[D * 8]);
+ m[E] = decode_uint64_le(&data[E * 8]);
+ m[F] = decode_uint64_le(&data[F * 8]);
+
+#define G2B(mj, mk, a, b, c, d)\
+ a = (a + b + mj) & UINT_LEAST64_C(0xFFFFffffFFFFffff);\
+ d = rotate_right(d ^ a, 32);\
+ c = (c + d) & UINT_LEAST64_C(0xFFFFffffFFFFffff);\
+ b = rotate_right(b ^ c, 24);\
+ a = (a + b + mk) & UINT_LEAST64_C(0xFFFFffffFFFFffff);\
+ d = rotate_right(d ^ a, 16);\
+ c = (c + d) & UINT_LEAST64_C(0xFFFFffffFFFFffff);\
+ b = rotate_right(b ^ c, 63)
+
+#define ROUND2B(S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, SA, SB, SC, SD, SE, SF)\
+ G2B(m[S0], m[S1], v[0], v[4], v[8], v[C]);\
+ G2B(m[S2], m[S3], v[1], v[5], v[9], v[D]);\
+ G2B(m[S4], m[S5], v[2], v[6], v[A], v[E]);\
+ G2B(m[S6], m[S7], v[3], v[7], v[B], v[F]);\
+ G2B(m[S8], m[S9], v[0], v[5], v[A], v[F]);\
+ G2B(m[SA], m[SB], v[1], v[6], v[B], v[C]);\
+ G2B(m[SC], m[SD], v[2], v[7], v[8], v[D]);\
+ G2B(m[SE], m[SF], v[3], v[4], v[9], v[E])
+
+ ROUND2B(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F);
+ ROUND2B(E, A, 4, 8, 9, F, D, 6, 1, C, 0, 2, B, 7, 5, 3);
+ ROUND2B(B, 8, C, 0, 5, 2, F, D, A, E, 3, 6, 7, 1, 9, 4);
+ ROUND2B(7, 9, 3, 1, D, C, B, E, 2, 6, 5, A, 4, 0, F, 8);
+ ROUND2B(9, 0, 5, 7, 2, 4, A, F, E, 1, B, C, 6, 8, 3, D);
+ ROUND2B(2, C, 6, A, 0, B, 8, 3, 4, D, 7, 5, F, E, 1, 9);
+ ROUND2B(C, 5, 1, F, E, D, 4, A, 0, 7, 6, 3, 9, 2, 8, B);
+ ROUND2B(D, B, 7, E, C, 1, 3, 9, 5, 0, F, 4, 8, 6, 2, A);
+ ROUND2B(6, F, E, 9, B, 3, 0, 8, C, 2, D, 7, 1, 4, A, 5);
+ ROUND2B(A, 2, 8, 4, 7, 6, 1, 5, F, B, 9, E, 3, C, D, 0);
+ ROUND2B(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F);
+ ROUND2B(E, A, 4, 8, 9, F, D, 6, 1, C, 0, 2, B, 7, 5, 3);
+
+ state->h[0] ^= v[0] ^ v[8];
+ state->h[1] ^= v[1] ^ v[9];
+ state->h[2] ^= v[2] ^ v[A];
+ state->h[3] ^= v[3] ^ v[B];
+ state->h[4] ^= v[4] ^ v[C];
+ state->h[5] ^= v[5] ^ v[D];
+ state->h[6] ^= v[6] ^ v[E];
+ state->h[7] ^= v[7] ^ v[F];
+}
diff --git a/libblake_internal_blake2s_compress.c b/libblake_internal_blake2s_compress.c
new file mode 100644
index 0000000..d3c4066
--- /dev/null
+++ b/libblake_internal_blake2s_compress.c
@@ -0,0 +1,97 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+#define A 10
+#define B 11
+#define C 12
+#define D 13
+#define E 14
+#define F 15
+
+static uint_least32_t
+decode_uint32_le(const unsigned char *data)
+{
+ return (((uint_least32_t)(data[0] & 255)) << 0) |
+ (((uint_least32_t)(data[1] & 255)) << 8) |
+ (((uint_least32_t)(data[2] & 255)) << 16) |
+ (((uint_least32_t)(data[3] & 255)) << 24);
+}
+
+static uint_least32_t
+rotate_right(uint_least32_t x, int n)
+{
+ return ((x >> n) | (x << (32 - n))) & UINT_LEAST32_C(0xFFFFffff);
+}
+
+void
+libblake_internal_blake2s_compress(struct libblake_blake2s_state *state, const unsigned char *data)
+{
+ uint_least32_t v[16], m[16];
+
+ memcpy(v, state->h, sizeof(state->h));
+ v[8] = UINT_LEAST32_C(0x6A09E667);
+ v[9] = UINT_LEAST32_C(0xBB67AE85);
+ v[A] = UINT_LEAST32_C(0x3C6EF372);
+ v[B] = UINT_LEAST32_C(0xA54FF53A);
+ v[C] = UINT_LEAST32_C(0x510E527F) ^ state->t[0];
+ v[D] = UINT_LEAST32_C(0x9B05688C) ^ state->t[1];
+ v[E] = UINT_LEAST32_C(0x1F83D9AB) ^ state->f[0];
+ v[F] = UINT_LEAST32_C(0x5BE0CD19) ^ state->f[1];
+
+ m[0] = decode_uint32_le(&data[0 * 4]);
+ m[1] = decode_uint32_le(&data[1 * 4]);
+ m[2] = decode_uint32_le(&data[2 * 4]);
+ m[3] = decode_uint32_le(&data[3 * 4]);
+ m[4] = decode_uint32_le(&data[4 * 4]);
+ m[5] = decode_uint32_le(&data[5 * 4]);
+ m[6] = decode_uint32_le(&data[6 * 4]);
+ m[7] = decode_uint32_le(&data[7 * 4]);
+ m[8] = decode_uint32_le(&data[8 * 4]);
+ m[9] = decode_uint32_le(&data[9 * 4]);
+ m[A] = decode_uint32_le(&data[A * 4]);
+ m[B] = decode_uint32_le(&data[B * 4]);
+ m[C] = decode_uint32_le(&data[C * 4]);
+ m[D] = decode_uint32_le(&data[D * 4]);
+ m[E] = decode_uint32_le(&data[E * 4]);
+ m[F] = decode_uint32_le(&data[F * 4]);
+
+#define G2S(mj, mk, a, b, c, d)\
+ a = (a + b + mj) & UINT_LEAST32_C(0xFFFFffff);\
+ d = rotate_right(d ^ a, 16);\
+ c = (c + d) & UINT_LEAST32_C(0xFFFFffff);\
+ b = rotate_right(b ^ c, 12);\
+ a = (a + b + mk) & UINT_LEAST32_C(0xFFFFffff);\
+ d = rotate_right(d ^ a, 8);\
+ c = (c + d) & UINT_LEAST32_C(0xFFFFffff);\
+ b = rotate_right(b ^ c, 7)
+
+#define ROUND2S(S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, SA, SB, SC, SD, SE, SF)\
+ G2S(m[S0], m[S1], v[0], v[4], v[8], v[C]);\
+ G2S(m[S2], m[S3], v[1], v[5], v[9], v[D]);\
+ G2S(m[S4], m[S5], v[2], v[6], v[A], v[E]);\
+ G2S(m[S6], m[S7], v[3], v[7], v[B], v[F]);\
+ G2S(m[S8], m[S9], v[0], v[5], v[A], v[F]);\
+ G2S(m[SA], m[SB], v[1], v[6], v[B], v[C]);\
+ G2S(m[SC], m[SD], v[2], v[7], v[8], v[D]);\
+ G2S(m[SE], m[SF], v[3], v[4], v[9], v[E])
+
+ ROUND2S(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F);
+ ROUND2S(E, A, 4, 8, 9, F, D, 6, 1, C, 0, 2, B, 7, 5, 3);
+ ROUND2S(B, 8, C, 0, 5, 2, F, D, A, E, 3, 6, 7, 1, 9, 4);
+ ROUND2S(7, 9, 3, 1, D, C, B, E, 2, 6, 5, A, 4, 0, F, 8);
+ ROUND2S(9, 0, 5, 7, 2, 4, A, F, E, 1, B, C, 6, 8, 3, D);
+ ROUND2S(2, C, 6, A, 0, B, 8, 3, 4, D, 7, 5, F, E, 1, 9);
+ ROUND2S(C, 5, 1, F, E, D, 4, A, 0, 7, 6, 3, 9, 2, 8, B);
+ ROUND2S(D, B, 7, E, C, 1, 3, 9, 5, 0, F, 4, 8, 6, 2, A);
+ ROUND2S(6, F, E, 9, B, 3, 0, 8, C, 2, D, 7, 1, 4, A, 5);
+ ROUND2S(A, 2, 8, 4, 7, 6, 1, 5, F, B, 9, E, 3, C, D, 0);
+
+ state->h[0] ^= v[0] ^ v[8];
+ state->h[1] ^= v[1] ^ v[9];
+ state->h[2] ^= v[2] ^ v[A];
+ state->h[3] ^= v[3] ^ v[B];
+ state->h[4] ^= v[4] ^ v[C];
+ state->h[5] ^= v[5] ^ v[D];
+ state->h[6] ^= v[6] ^ v[E];
+ state->h[7] ^= v[7] ^ v[F];
+}
diff --git a/libblake_internal_blakeb_update.c b/libblake_internal_blakeb_update.c
index db4f0b7..a1a88d6 100644
--- a/libblake_internal_blakeb_update.c
+++ b/libblake_internal_blakeb_update.c
@@ -47,26 +47,26 @@ rotate_right(uint_least64_t x, int n)
size_t
libblake_internal_blakeb_update(struct libblake_blakeb_state *state, const unsigned char *data, size_t len)
{
- size_t ret = 0;
+ size_t off = 0;
struct libblake_blakeb_state s;
uint_least64_t v[16], m[16];
memcpy(&s, state, sizeof(s));
- for (; len - ret >= 128; ret += 128, data = &data[128]) {
- s.t[0] += 1024;
- if ((s.t[0] & UINT_LEAST64_C(0xFFFFffffFFFFffff)) < 1024)
+ for (; len - off >= 128; off += 128, data = &data[128]) {
+ s.t[0] = (s.t[0] + 1024) & UINT_LEAST64_C(0xFFFFffffFFFFffff);
+ if (s.t[0] < 1024)
s.t[1] = (s.t[1] + 1) & UINT_LEAST64_C(0xFFFFffffFFFFffff);
memcpy(v, s.h, sizeof(s.h));
- v[8] = s.s[0] ^ CB0;
- v[9] = s.s[1] ^ CB1;
- v[10] = s.s[2] ^ CB2;
- v[11] = s.s[3] ^ CB3;
- v[12] = s.t[0] ^ CB4;
- v[13] = s.t[0] ^ CB5;
- v[14] = s.t[1] ^ CB6;
- v[15] = s.t[1] ^ CB7;
+ v[8] = s.s[0] ^ CB0;
+ v[9] = s.s[1] ^ CB1;
+ v[A] = s.s[2] ^ CB2;
+ v[B] = s.s[3] ^ CB3;
+ v[C] = s.t[0] ^ CB4;
+ v[D] = s.t[0] ^ CB5;
+ v[E] = s.t[1] ^ CB6;
+ v[F] = s.t[1] ^ CB7;
m[0] = decode_uint64_be(&data[0 * 8]);
m[1] = decode_uint64_be(&data[1 * 8]);
@@ -97,13 +97,13 @@ libblake_internal_blakeb_update(struct libblake_blakeb_state *state, const unsig
#define ROUNDB(S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, SA, SB, SC, SD, SE, SF)\
GB(m[S0], m[S1], CB##S0, CB##S1, v[0], v[4], v[8], v[C]);\
- GB(m[S2], m[S3], CB##S2, CB##S3, v[1], v[5], v[9], v[D]);\
- GB(m[S4], m[S5], CB##S4, CB##S5, v[2], v[6], v[A], v[E]);\
- GB(m[S6], m[S7], CB##S6, CB##S7, v[3], v[7], v[B], v[F]);\
- GB(m[S8], m[S9], CB##S8, CB##S9, v[0], v[5], v[A], v[F]);\
- GB(m[SA], m[SB], CB##SA, CB##SB, v[1], v[6], v[B], v[C]);\
- GB(m[SC], m[SD], CB##SC, CB##SD, v[2], v[7], v[8], v[D]);\
- GB(m[SE], m[SF], CB##SE, CB##SF, v[3], v[4], v[9], v[E])
+ GB(m[S2], m[S3], CB##S2, CB##S3, v[1], v[5], v[9], v[D]);\
+ GB(m[S4], m[S5], CB##S4, CB##S5, v[2], v[6], v[A], v[E]);\
+ GB(m[S6], m[S7], CB##S6, CB##S7, v[3], v[7], v[B], v[F]);\
+ GB(m[S8], m[S9], CB##S8, CB##S9, v[0], v[5], v[A], v[F]);\
+ GB(m[SA], m[SB], CB##SA, CB##SB, v[1], v[6], v[B], v[C]);\
+ GB(m[SC], m[SD], CB##SC, CB##SD, v[2], v[7], v[8], v[D]);\
+ GB(m[SE], m[SF], CB##SE, CB##SF, v[3], v[4], v[9], v[E])
ROUNDB(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F);
ROUNDB(E, A, 4, 8, 9, F, D, 6, 1, C, 0, 2, B, 7, 5, 3);
@@ -134,5 +134,5 @@ libblake_internal_blakeb_update(struct libblake_blakeb_state *state, const unsig
memcpy(state, &s, sizeof(s));
- return ret;
+ return off;
}
diff --git a/libblake_internal_blakes_update.c b/libblake_internal_blakes_update.c
index 389b5cc..525600a 100644
--- a/libblake_internal_blakes_update.c
+++ b/libblake_internal_blakes_update.c
@@ -43,26 +43,26 @@ rotate_right(uint_least32_t x, int n)
size_t
libblake_internal_blakes_update(struct libblake_blakes_state *state, const unsigned char *data, size_t len)
{
- size_t ret = 0;
+ size_t off = 0;
struct libblake_blakes_state s;
uint_least32_t v[16], m[16];
memcpy(&s, state, sizeof(s));
- for (; len - ret >= 64; ret += 64, data = &data[64]) {
- s.t[0] += 512;
- if ((s.t[0] & UINT_LEAST32_C(0xFFFFffff)) < 512)
+ for (; len - off >= 64; off += 64, data = &data[64]) {
+ s.t[0] = (s.t[0] + 512) & UINT_LEAST32_C(0xFFFFffff);
+ if (s.t[0] < 512)
s.t[1] = (s.t[1] + 1) & UINT_LEAST32_C(0xFFFFffff);
memcpy(v, s.h, sizeof(s.h));
- v[8] = s.s[0] ^ CS0;
- v[9] = s.s[1] ^ CS1;
- v[10] = s.s[2] ^ CS2;
- v[11] = s.s[3] ^ CS3;
- v[12] = s.t[0] ^ CS4;
- v[13] = s.t[0] ^ CS5;
- v[14] = s.t[1] ^ CS6;
- v[15] = s.t[1] ^ CS7;
+ v[8] = s.s[0] ^ CS0;
+ v[9] = s.s[1] ^ CS1;
+ v[A] = s.s[2] ^ CS2;
+ v[B] = s.s[3] ^ CS3;
+ v[C] = s.t[0] ^ CS4;
+ v[D] = s.t[0] ^ CS5;
+ v[E] = s.t[1] ^ CS6;
+ v[F] = s.t[1] ^ CS7;
m[0] = decode_uint32_be(&data[0 * 4]);
m[1] = decode_uint32_be(&data[1 * 4]);
@@ -93,13 +93,13 @@ libblake_internal_blakes_update(struct libblake_blakes_state *state, const unsig
#define ROUNDS(S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, SA, SB, SC, SD, SE, SF)\
GS(m[S0], m[S1], CS##S0, CS##S1, v[0], v[4], v[8], v[C]);\
- GS(m[S2], m[S3], CS##S2, CS##S3, v[1], v[5], v[9], v[D]);\
- GS(m[S4], m[S5], CS##S4, CS##S5, v[2], v[6], v[A], v[E]);\
- GS(m[S6], m[S7], CS##S6, CS##S7, v[3], v[7], v[B], v[F]);\
- GS(m[S8], m[S9], CS##S8, CS##S9, v[0], v[5], v[A], v[F]);\
- GS(m[SA], m[SB], CS##SA, CS##SB, v[1], v[6], v[B], v[C]);\
- GS(m[SC], m[SD], CS##SC, CS##SD, v[2], v[7], v[8], v[D]);\
- GS(m[SE], m[SF], CS##SE, CS##SF, v[3], v[4], v[9], v[E])
+ GS(m[S2], m[S3], CS##S2, CS##S3, v[1], v[5], v[9], v[D]);\
+ GS(m[S4], m[S5], CS##S4, CS##S5, v[2], v[6], v[A], v[E]);\
+ GS(m[S6], m[S7], CS##S6, CS##S7, v[3], v[7], v[B], v[F]);\
+ GS(m[S8], m[S9], CS##S8, CS##S9, v[0], v[5], v[A], v[F]);\
+ GS(m[SA], m[SB], CS##SA, CS##SB, v[1], v[6], v[B], v[C]);\
+ GS(m[SC], m[SD], CS##SC, CS##SD, v[2], v[7], v[8], v[D]);\
+ GS(m[SE], m[SF], CS##SE, CS##SF, v[3], v[4], v[9], v[E])
ROUNDS(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F);
ROUNDS(E, A, 4, 8, 9, F, D, 6, 1, C, 0, 2, B, 7, 5, 3);
@@ -128,5 +128,5 @@ libblake_internal_blakes_update(struct libblake_blakes_state *state, const unsig
memcpy(state, &s, sizeof(s));
- return ret;
+ return off;
}
diff --git a/test.c b/test.c
index 890b710..9cb85dd 100644
--- a/test.c
+++ b/test.c
@@ -123,10 +123,10 @@ check_blake1(void)
CHECK_BLAKE512_STR("", "a8cfbbd73726062df0c6864dda65defe58ef0cc52a5625090fa17601e1eecd1b628e94f396ae402a00acc9eab77b4d4c2e852aaaa25a636d80af3fc7913ef5b8");
CHECK_BLAKE512_STR("The quick brown fox jumps over the lazy dog",
- "1f7e26f63b6ad25a0896fd978fd050a1766391d2fd0471a77afb975e5034b7ad2d9ccf8dfb47abbbe656e1b82fbc634ba42ce186e8dc5e1ce09a885d41f43451");
+ "1f7e26f63b6ad25a0896fd978fd050a1766391d2fd0471a77afb975e5034b7ad2d9ccf8dfb47abbbe656e1b82fbc634ba42ce186e8dc5e1ce09a885d41f43451");
CHECK_BLAKE512_STR("The quick brown fox jumps over the lazy dof",
- "a701c2a1f9baabd8b1db6b75aee096900276f0b86dc15d247ecc03937b370324a16a4ffc0c3a85cd63229cfa15c15f4ba6d46ae2e849ed6335e9ff43b764198a");
+ "a701c2a1f9baabd8b1db6b75aee096900276f0b86dc15d247ecc03937b370324a16a4ffc0c3a85cd63229cfa15c15f4ba6d46ae2e849ed6335e9ff43b764198a");
bits = 1;
#define X(INPUT, EXPECT) CHECK_BLAKE224_BITS(INPUT, bits++, EXPECT);
@@ -343,6 +343,146 @@ check_blake1(void)
return failed;
}
+static const char *
+digest_blake2s(int length, const void *msg, size_t msglen)
+{
+ static char hex[1025];
+ unsigned char buf[512];
+ size_t req;
+ char *data;
+ struct libblake_blake2s_state s;
+ struct libblake_blake2s_params params;
+
+ memset(&params, 0, sizeof(params));
+ params.digest_len = (uint_least8_t)(length / 8);
+ params.fanout = 1;
+ params.depth = 1;
+
+ req = libblake_blake2s_digest_get_required_input_size(msglen);
+ data = malloc(req);
+ memcpy(data, msg, msglen);
+ libblake_blake2s_init(&s, &params, NULL);
+ libblake_blake2s_digest(&s, data, msglen, (size_t)length / 8, buf);
+ libblake_encode_hex(buf, (size_t)length / 8, hex, 0);
+ free(data);
+
+ return hex;
+}
+
+#define CHECK_BLAKE2S_STR(LENGTH, MSG, EXPECTED)\
+ failed |= !check_blake2s_(LENGTH, "“"MSG"”", MSG, sizeof(MSG) - 1, EXPECTED)
+#define CHECK_BLAKE2S_224_STR(MSG, EXPECTED) CHECK_BLAKE2S_STR(224, MSG, EXPECTED)
+#define CHECK_BLAKE2S_256_STR(MSG, EXPECTED) CHECK_BLAKE2S_STR(256, MSG, EXPECTED)
+
+#if 0
+# define CHECK_BLAKE2S_HEX(LENGTH, MSG, EXPECTED)\
+ failed |= !check_blake2s_(LENGTH, "0x"MSG, buf, libblake_decode_hex(MSG, SIZE_MAX, buf, &(int){0}), EXPECTED)
+# define CHECK_BLAKE2S_224_HEX(MSG, EXPECTED) CHECK_BLAKE2S_HEX(224, MSG, EXPECTED)
+# define CHECK_BLAKE2S_256_HEX(MSG, EXPECTED) CHECK_BLAKE2S_HEX(256, MSG, EXPECTED)
+#endif
+
+static int
+check_blake2s_(int length, const char *dispmsg, const void *msg, size_t msglen, const char *expected)
+{
+ const char *result;
+ result = digest_blake2s(length, msg, msglen);
+ if (strcasecmp(result, expected)) {
+ fprintf(stderr, "BLAKE2s-%i failed for %s:\n", length, dispmsg);
+ fprintf(stderr, "\tResult: %s\n", result);
+ fprintf(stderr, "\tExpected: %s\n", expected);
+ fprintf(stderr, "\n");
+ return 0;
+ }
+ return 1;
+}
+
+static int
+check_blake2s(void)
+{
+#if 0
+ char buf[1025];
+#endif
+ int failed = 0;
+
+ CHECK_BLAKE2S_224_STR("", "1fa1291e65248b37b3433475b2a0dd63d54a11ecc4e3e034e7bc1ef4");
+ CHECK_BLAKE2S_256_STR("", "69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9");
+
+ return failed;
+}
+
+static const char *
+digest_blake2b(int length, const void *msg, size_t msglen)
+{
+ static char hex[1025];
+ unsigned char buf[512];
+ size_t req;
+ char *data;
+ struct libblake_blake2b_state s;
+ struct libblake_blake2b_params params;
+
+ memset(&params, 0, sizeof(params));
+ params.digest_len = (uint_least8_t)(length / 8);
+ params.fanout = 1;
+ params.depth = 1;
+
+ req = libblake_blake2b_digest_get_required_input_size(msglen);
+ data = malloc(req);
+ memcpy(data, msg, msglen);
+ libblake_blake2b_init(&s, &params, NULL);
+ libblake_blake2b_digest(&s, data, msglen, (size_t)length / 8, buf);
+ libblake_encode_hex(buf, (size_t)length / 8, hex, 0);
+ free(data);
+
+ return hex;
+}
+
+#define CHECK_BLAKE2B_STR(LENGTH, MSG, EXPECTED)\
+ failed |= !check_blake2b_(LENGTH, "“"MSG"”", MSG, sizeof(MSG) - 1, EXPECTED)
+#define CHECK_BLAKE2B_384_STR(MSG, EXPECTED) CHECK_BLAKE2B_STR(384, MSG, EXPECTED)
+#define CHECK_BLAKE2B_512_STR(MSG, EXPECTED) CHECK_BLAKE2B_STR(512, MSG, EXPECTED)
+
+#if 0
+# define CHECK_BLAKE2B_HEX(LENGTH, MSG, EXPECTED)\
+ failed |= !check_blake2b_(LENGTH, "0x"MSG, buf, libblake_decode_hex(MSG, SIZE_MAX, buf, &(int){0}), EXPECTED)
+# define CHECK_BLAKE2B_384_HEX(MSG, EXPECTED) CHECK_BLAKE2B_HEX(384, MSG, EXPECTED)
+# define CHECK_BLAKE2B_512_HEX(MSG, EXPECTED) CHECK_BLAKE2B_HEX(512, MSG, EXPECTED)
+#endif
+
+static int
+check_blake2b_(int length, const char *dispmsg, const void *msg, size_t msglen, const char *expected)
+{
+ const char *result;
+ result = digest_blake2b(length, msg, msglen);
+ if (strcasecmp(result, expected)) {
+ fprintf(stderr, "BLAKE2b-%i failed for %s:\n", length, dispmsg);
+ fprintf(stderr, "\tResult: %s\n", result);
+ fprintf(stderr, "\tExpected: %s\n", expected);
+ fprintf(stderr, "\n");
+ return 0;
+ }
+ return 1;
+}
+
+static int
+check_blake2b(void)
+{
+#if 0
+ char buf[1025];
+#endif
+ int failed = 0;
+
+ CHECK_BLAKE2B_384_STR("", "b32811423377f52d7862286ee1a72ee540524380fda1724a6f25d7978c6fd3244a6caf0498812673c5e05ef583825100");
+ CHECK_BLAKE2B_512_STR("", "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce");
+
+ CHECK_BLAKE2B_512_STR("The quick brown fox jumps over the lazy dog",
+ "a8add4bdddfd93e4877d2746e62817b116364a1fa7bc148d95090bc7333b3673f82401cf7aa2e4cb1ecd90296e3f14cb5413f8ed77be73045b13914cdcd6a918");
+
+ CHECK_BLAKE2B_512_STR("The quick brown fox jumps over the lazy dof",
+ "ab6b007747d8068c02e25a6008db8a77c218d94f3b40d2291a7dc8a62090a744c082ea27af01521a102e42f480a31e9844053f456b4b41e8aa78bbe5c12957bb");
+
+ return failed;
+}
+
int
main(void)
{
@@ -352,6 +492,8 @@ main(void)
CHECK_HEX(0, 00, 12, 32, 00, 45, 67, 82, 9a, b0, cd, fe, ff, 80, 08, cc, 28);
failed |= check_blake1();
+ failed |= check_blake2s();
+ failed |= check_blake2b();
return failed;
}