]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
Implement blake2b and blake2s.
authorNiels Möller <nisse@lysator.liu.se>
Thu, 13 Nov 2025 20:53:52 +0000 (21:53 +0100)
committerNiels Möller <nisse@lysator.liu.se>
Fri, 14 Nov 2025 16:24:21 +0000 (17:24 +0100)
Makefile.in
blake2.h [new file with mode: 0644]
blake2b.c [new file with mode: 0644]
blake2s.c [new file with mode: 0644]
examples/nettle-benchmark.c
non-nettle.c
non-nettle.h
testsuite/Makefile.in
testsuite/blake2b-test.c [new file with mode: 0644]
testsuite/blake2s-test.c [new file with mode: 0644]

index c08e589a8d03f9f4d4a5ce0c1e0e7b1c461235e5..0a106cd9dd556779b6f2916c5adc38a7e3e9c784 100644 (file)
@@ -97,6 +97,7 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt-table.c \
                 base16-encode.c base16-decode.c \
                 base64-encode.c base64-decode.c \
                 base64url-encode.c base64url-decode.c \
+                blake2b.c blake2s.c \
                 buffer.c buffer-init.c \
                 camellia-crypt-internal.c camellia-table.c \
                 camellia-absorb.c camellia-invert-key.c \
@@ -241,7 +242,7 @@ hogweed_SOURCES = sexp.c sexp-format.c \
 OPT_SOURCES = fat-arm.c fat-arm64.c fat-ppc.c fat-s390x.c fat-x86_64.c mini-gmp.c
 
 HEADERS = aes.h arcfour.h arctwo.h asn1.h blowfish.h balloon.h \
-         base16.h base64.h bignum.h buffer.h camellia.h cast128.h \
+         base16.h base64.h bignum.h blake2.h buffer.h camellia.h cast128.h \
          cbc.h ccm.h cfb.h chacha.h chacha-poly1305.h ctr.h \
          curve25519.h curve448.h des.h dsa.h eax.h \
          ecc-curve.h ecc.h ecdsa.h eddsa.h \
diff --git a/blake2.h b/blake2.h
new file mode 100644 (file)
index 0000000..8741f5a
--- /dev/null
+++ b/blake2.h
@@ -0,0 +1,107 @@
+/* blake2.h
+
+   The blake2 hash function, see RFC 7693
+
+   Copyright (C) 2025 Niels Möller
+
+   This file is part of GNU Nettle.
+
+   GNU Nettle is free software: you can redistribute it and/or
+   modify it under the terms of either:
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at your
+       option) any later version.
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at your
+       option) any later version.
+
+   or both in parallel, as here.
+
+   GNU Nettle is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see http://www.gnu.org/licenses/.
+*/
+
+#ifndef NETTLE_BLAKE2_H_INCLUDED
+#define NETTLE_BLAKE2_H_INCLUDED
+
+#include "nettle-types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Name mangling */
+#define blake2b_init nettle_blake2b_init
+#define blake2b_update nettle_blake2b_update
+#define blake2b_digest nettle_blake2b_digest
+#define blake2b_512_init nettle_blake2b_512_init
+#define blake2s_init nettle_blake2s_init
+#define blake2s_update nettle_blake2s_update
+#define blake2s_digest nettle_blake2s_digest
+#define blake2s_256_init nettle_blake2s_256_init
+
+#define BLAKE2B_DIGEST_SIZE 64
+#define BLAKE2B_BLOCK_SIZE 128
+
+struct blake2b_ctx
+{
+  uint64_t state[8];
+  uint64_t count_low, count_high;      /* 128-bit byte count */
+  unsigned short digest_size;
+  unsigned short index;                        /* index into buffer */
+  uint8_t block[BLAKE2B_BLOCK_SIZE];   /* data buffer */
+};
+
+void
+blake2b_init (struct blake2b_ctx *ctx, unsigned digest_size);
+
+void
+blake2b_update (struct blake2b_ctx *ctx,
+               size_t length, const uint8_t *data);
+
+void
+blake2b_digest (struct blake2b_ctx *ctx, uint8_t *digest);
+
+void
+blake2b_512_init (struct blake2b_ctx *ctx);
+
+#define BLAKE2S_DIGEST_SIZE 32
+#define BLAKE2S_BLOCK_SIZE 64
+
+struct blake2s_ctx
+{
+  uint32_t state[8];
+  uint64_t count;                      /* 64-bit byte count */
+  unsigned short digest_size;
+  unsigned short index;                        /* index into buffer */
+  uint8_t block[BLAKE2S_BLOCK_SIZE];   /* data buffer */
+};
+
+void
+blake2s_init (struct blake2s_ctx *ctx, unsigned digest_size);
+
+void
+blake2s_update (struct blake2s_ctx *ctx,
+               size_t length, const uint8_t *data);
+
+void
+blake2s_digest (struct blake2s_ctx *ctx, uint8_t *digest);
+
+void
+blake2s_256_init (struct blake2s_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NETTLE_BLAKE2_H_INCLUDED */
diff --git a/blake2b.c b/blake2b.c
new file mode 100644 (file)
index 0000000..153acd3
--- /dev/null
+++ b/blake2b.c
@@ -0,0 +1,177 @@
+/* blake2b.c
+
+   Copyright (C) 2025 Niels Möller
+
+   This file is part of GNU Nettle.
+
+   GNU Nettle is free software: you can redistribute it and/or
+   modify it under the terms of either:
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at your
+       option) any later version.
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at your
+       option) any later version.
+
+   or both in parallel, as here.
+
+   GNU Nettle is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see http://www.gnu.org/licenses/.
+*/
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <string.h>
+
+#include "blake2.h"
+#include "macros.h"
+#include "nettle-write.h"
+
+/* Blake2 mixing function G, similar to a chacha qround. */
+/* R1, R2, R3, R4 = 32, 24, 16, 63, defined as rotations right. */
+#define BLAKE2B_G(x0, x1, x2, x3, w0, w1) do {         \
+    x0 += x1 + (w0); x3 = ROTL64 (32, (x0 ^ x3));      \
+    x2 += x3;        x1 = ROTL64 (40, (x1 ^ x2));      \
+    x0 += x1 + (w1); x3 = ROTL64 (48, (x0 ^ x3));      \
+    x2 += x3;        x1 = ROTL64 (1,  (x1 ^ x2));      \
+  } while (0)
+
+
+/* Same as sha512 H0. */
+static const uint64_t iv[8] =
+  {
+    0x6A09E667F3BCC908ULL,0xBB67AE8584CAA73BULL,
+    0x3C6EF372FE94F82BULL,0xA54FF53A5F1D36F1ULL,
+    0x510E527FADE682D1ULL,0x9B05688C2B3E6C1FULL,
+    0x1F83D9ABFB41BD6BULL,0x5BE0CD19137E2179ULL,
+  };
+
+static void
+blake2b_compress (uint64_t *h, const uint8_t *input,
+                 uint64_t count_low, uint64_t count_high, int final)
+{
+  static const unsigned char sigma[12][16] =
+    {
+      { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
+      { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
+      { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
+      { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
+      { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
+      { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
+      { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
+      { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
+      { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
+      { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 },
+      { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
+      { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
+    };
+  uint64_t v[16];
+  uint64_t m[16];
+  unsigned i;
+
+  for (i = 0; i < 16; i++, input += 8)
+    m[i] = LE_READ_UINT64(input);
+
+  for (i = 0; i < 8; i++)
+    {
+      v[i] = h[i];
+      v[8+i] = iv[i];
+    }
+  v[12] ^= count_low;
+  v[13] ^= count_high;
+  v[14] ^= - (uint64_t) final;
+
+  for (i = 0; i < 12; i++)
+    {
+      BLAKE2B_G (v[0], v[4], v[ 8], v[12], m[sigma[i][ 0]], m[sigma[i][ 1]]);
+      BLAKE2B_G (v[1], v[5], v[ 9], v[13], m[sigma[i][ 2]], m[sigma[i][ 3]]);
+      BLAKE2B_G (v[2], v[6], v[10], v[14], m[sigma[i][ 4]], m[sigma[i][ 5]]);
+      BLAKE2B_G (v[3], v[7], v[11], v[15], m[sigma[i][ 6]], m[sigma[i][ 7]]);
+
+      BLAKE2B_G (v[0], v[5], v[10], v[15], m[sigma[i][ 8]], m[sigma[i][ 9]]);
+      BLAKE2B_G (v[1], v[6], v[11], v[12], m[sigma[i][10]], m[sigma[i][11]]);
+      BLAKE2B_G (v[2], v[7], v[ 8], v[13], m[sigma[i][12]], m[sigma[i][13]]);
+      BLAKE2B_G (v[3], v[4], v[ 9], v[14], m[sigma[i][14]], m[sigma[i][15]]);
+    }
+  for (i = 0; i < 8; i++)
+    h[i] ^= v[i] ^ v[8+i];
+}
+
+void
+blake2b_init (struct blake2b_ctx *ctx, unsigned digest_size)
+{
+  assert (digest_size > 0 && digest_size <= BLAKE2B_DIGEST_SIZE);
+  memcpy (ctx->state, iv, sizeof (ctx->state));
+  ctx->state[0] ^= 0x01010000 ^ digest_size;
+  ctx->count_low = ctx->count_high = ctx->index = 0;
+  ctx->digest_size = digest_size;
+}
+
+void
+blake2b_update (struct blake2b_ctx *ctx,
+               size_t length, const uint8_t *data)
+{
+  if (!length)
+    return;
+
+  /* To be able to pass the finalization flag, don't call the
+     compression function until we have input exceeding one block. */
+  if (ctx->index)
+    {
+      unsigned left = BLAKE2B_BLOCK_SIZE - ctx->index;
+      if (length <= left)
+       {
+         memcpy (ctx->block + ctx->index, data, length);
+         ctx->index += length;
+         return;
+       }
+      memcpy (ctx->block + ctx->index, data, left);
+      ctx->count_low += BLAKE2B_BLOCK_SIZE;
+      ctx->count_high += ctx->count_low < BLAKE2B_BLOCK_SIZE;
+      blake2b_compress (ctx->state, ctx->block, ctx->count_low, ctx->count_high, 0);
+      data += left; length -= left;
+    }
+  for (; length > BLAKE2B_BLOCK_SIZE;
+       data += BLAKE2B_BLOCK_SIZE, length -= BLAKE2B_BLOCK_SIZE)
+    {
+      ctx->count_low += BLAKE2B_BLOCK_SIZE;
+      ctx->count_high += ctx->count_low < BLAKE2B_BLOCK_SIZE;
+      blake2b_compress (ctx->state, data, ctx->count_low, ctx->count_high, 0);
+    }
+
+  memcpy (ctx->block, data, length);
+  ctx->index = length;
+}
+
+void
+blake2b_digest (struct blake2b_ctx *ctx, uint8_t *digest)
+{
+  memset (ctx->block + ctx->index, 0, BLAKE2B_BLOCK_SIZE - ctx->index);
+  ctx->count_low += ctx->index;
+  ctx->count_high += ctx->count_low < ctx->index;
+  blake2b_compress (ctx->state, ctx->block, ctx->count_low, ctx->count_high, 1);
+
+  assert (ctx->digest_size <= BLAKE2B_DIGEST_SIZE);
+  _nettle_write_le64 (ctx->digest_size, digest, ctx->state);
+
+  blake2b_init (ctx, ctx->digest_size);
+}
+
+void
+blake2b_512_init (struct blake2b_ctx *ctx)
+{
+  blake2b_init (ctx, BLAKE2B_DIGEST_SIZE);
+}
diff --git a/blake2s.c b/blake2s.c
new file mode 100644 (file)
index 0000000..0e585b0
--- /dev/null
+++ b/blake2s.c
@@ -0,0 +1,168 @@
+/* blake2s.c
+
+   Copyright (C) 2025 Niels Möller
+
+   This file is part of GNU Nettle.
+
+   GNU Nettle is free software: you can redistribute it and/or
+   modify it under the terms of either:
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at your
+       option) any later version.
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at your
+       option) any later version.
+
+   or both in parallel, as here.
+
+   GNU Nettle is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see http://www.gnu.org/licenses/.
+*/
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <string.h>
+
+#include "blake2.h"
+#include "macros.h"
+#include "nettle-write.h"
+
+/* Blake2 mixing function G, similar to a chacha qround. */
+/* R1, R2, R3, R4 = 16, 12, 8, 7, defined as rotation right */
+#define BLAKE2S_G(x0, x1, x2, x3, w0, w1) do {         \
+    x0 += x1 + (w0); x3 = ROTL32 (16, (x0 ^ x3));      \
+    x2 += x3;        x1 = ROTL32 (20, (x1 ^ x2));      \
+    x0 += x1 + (w1); x3 = ROTL32 (24, (x0 ^ x3));      \
+    x2 += x3;        x1 = ROTL32 (25, (x1 ^ x2));      \
+  } while (0)
+
+/* Same as sha256 H0. */
+static const uint32_t iv[8] =
+  {
+    0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL,
+    0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL,
+  };
+
+static void
+blake2s_compress (uint32_t *h, const uint8_t *input,
+                 uint64_t count, int final)
+{
+  static const unsigned char sigma[10][16] =
+    {
+      { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
+      { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
+      { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
+      { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
+      { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
+      { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
+      { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
+      { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
+      { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
+      { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 },
+    };
+  uint32_t v[16];
+  uint32_t m[16];
+  unsigned i;
+
+  for (i = 0; i < 16; i++, input += 4)
+    m[i] = LE_READ_UINT32(input);
+
+  for (i = 0; i < 8; i++)
+    {
+      v[i] = h[i];
+      v[8+i] = iv[i];
+    }
+  v[12] ^= count;
+  v[13] ^= (count >> 32);
+  v[14] ^= - (uint32_t) final;
+
+  for (i = 0; i < 10; i++)
+    {
+      BLAKE2S_G (v[0], v[4], v[ 8], v[12], m[sigma[i][ 0]], m[sigma[i][ 1]]);
+      BLAKE2S_G (v[1], v[5], v[ 9], v[13], m[sigma[i][ 2]], m[sigma[i][ 3]]);
+      BLAKE2S_G (v[2], v[6], v[10], v[14], m[sigma[i][ 4]], m[sigma[i][ 5]]);
+      BLAKE2S_G (v[3], v[7], v[11], v[15], m[sigma[i][ 6]], m[sigma[i][ 7]]);
+
+      BLAKE2S_G (v[0], v[5], v[10], v[15], m[sigma[i][ 8]], m[sigma[i][ 9]]);
+      BLAKE2S_G (v[1], v[6], v[11], v[12], m[sigma[i][10]], m[sigma[i][11]]);
+      BLAKE2S_G (v[2], v[7], v[ 8], v[13], m[sigma[i][12]], m[sigma[i][13]]);
+      BLAKE2S_G (v[3], v[4], v[ 9], v[14], m[sigma[i][14]], m[sigma[i][15]]);
+    }
+  for (i = 0; i < 8; i++)
+    h[i] ^= v[i] ^ v[8+i];
+}
+
+void
+blake2s_init (struct blake2s_ctx *ctx, unsigned digest_size)
+{
+  assert (digest_size > 0 && digest_size <= BLAKE2S_DIGEST_SIZE);
+  memcpy (ctx->state, iv, sizeof (ctx->state));
+  ctx->state[0] ^= 0x01010000 ^ digest_size;
+  ctx->count = ctx->index = 0;
+  ctx->digest_size = digest_size;
+}
+
+void
+blake2s_update (struct blake2s_ctx *ctx,
+               size_t length, const uint8_t *data)
+{
+  if (!length)
+    return;
+
+  /* To be able to pass the finalization flag, don't call the
+     compression function until we have input exceeding one block. */
+  if (ctx->index)
+    {
+      unsigned left = BLAKE2S_BLOCK_SIZE - ctx->index;
+      if (length <= left)
+       {
+         memcpy (ctx->block + ctx->index, data, length);
+         ctx->index += length;
+         return;
+       }
+      memcpy (ctx->block + ctx->index, data, left);
+      ctx->count += BLAKE2S_BLOCK_SIZE;
+      blake2s_compress (ctx->state, ctx->block, ctx->count, 0);
+      data += left; length -= left;
+    }
+  for (; length > BLAKE2S_BLOCK_SIZE;
+       data += BLAKE2S_BLOCK_SIZE, length -= BLAKE2S_BLOCK_SIZE)
+    {
+      ctx->count += BLAKE2S_BLOCK_SIZE;
+      blake2s_compress (ctx->state, data, ctx->count, 0);
+    }
+
+  memcpy (ctx->block, data, length);
+  ctx->index = length;
+}
+
+void
+blake2s_digest (struct blake2s_ctx *ctx, uint8_t *digest)
+{
+  memset (ctx->block + ctx->index, 0, BLAKE2S_BLOCK_SIZE - ctx->index);
+  blake2s_compress (ctx->state, ctx->block, ctx->count + ctx->index, 1);
+
+  assert (ctx->digest_size <= BLAKE2S_DIGEST_SIZE);
+  _nettle_write_le32 (ctx->digest_size, digest, ctx->state);
+
+  blake2s_init (ctx, ctx->digest_size);
+}
+
+void
+blake2s_256_init (struct blake2s_ctx *ctx)
+{
+  blake2s_init (ctx, BLAKE2S_DIGEST_SIZE);
+}
index 70c4513e6112d3e1c7f22845ac464ef57d13e2e3..41041c14c20e48e5173907af487398b32c59bb2f 100644 (file)
@@ -913,6 +913,7 @@ main(int argc, char **argv)
       &nettle_sha512_224, &nettle_sha512_256,
       &nettle_sha3_224, &nettle_sha3_256,
       &nettle_sha3_384, &nettle_sha3_512,
+      &nettle_blake2s_256, &nettle_blake2b_512,
       &nettle_ripemd160, &nettle_gosthash94,
       &nettle_gosthash94cp, &nettle_streebog256,
       &nettle_streebog512, &nettle_sm3,
index 6ab1a098cf45e7577078b57d9198513327a995d9..3ef3673b8346c94025c7c36c6ae5a64002e11813 100644 (file)
@@ -42,6 +42,7 @@
 
 #include "non-nettle.h"
 #include "arcfour.h"
+#include "blake2.h"
 #include "blowfish.h"
 #include "cbc.h"
 #include "chacha.h"
@@ -336,3 +337,27 @@ nettle_ocb_aes128_t96 =
     (nettle_crypt_func *) ocb_aes128_decrypt_wrapper,
     (nettle_hash_digest_func *) ocb_aes128_t96_digest,
   };
+
+const struct nettle_hash
+nettle_blake2b_512 =
+  {
+    "blake2b_512",
+    sizeof (struct blake2b_ctx),
+    BLAKE2B_DIGEST_SIZE,
+    BLAKE2B_BLOCK_SIZE,
+    (nettle_hash_init_func *) blake2b_512_init,
+    (nettle_hash_update_func *) blake2b_update,
+    (nettle_hash_digest_func *) blake2b_digest,
+  };
+
+const struct nettle_hash
+nettle_blake2s_256 =
+  {
+    "blake2s_256",
+    sizeof (struct blake2s_ctx),
+    BLAKE2S_DIGEST_SIZE,
+    BLAKE2S_BLOCK_SIZE,
+    (nettle_hash_init_func *) blake2s_256_init,
+    (nettle_hash_update_func *) blake2s_update,
+    (nettle_hash_digest_func *) blake2s_digest,
+  };
index e36c8f9ce60ee058f580478e7a2ff350a5e2ee81..056b83b50ca6edae957cce409f94fd548ea8ec4f 100644 (file)
@@ -92,5 +92,7 @@ struct ocb_aes128_ctx
 extern const struct nettle_aead nettle_ocb_aes128;
 extern const struct nettle_aead nettle_ocb_aes128_t96;
 
+extern const struct nettle_hash nettle_blake2b_512;
+extern const struct nettle_hash nettle_blake2s_256;
 
 #endif /* NETTLE_NON_NETTLE_H_INCLUDED */
index b2f0518cf1a111266b5e511ef8331b760c088a67..63ed188d1559b35011dd14d36b7127b3f41af9da 100644 (file)
@@ -13,6 +13,7 @@ PRE_LDFLAGS = -L..
 TS_NETTLE_SOURCES = aes-test.c aes-keywrap-test.c arcfour-test.c arctwo-test.c \
                    balloon-test.c blowfish-test.c bcrypt-test.c cast128-test.c \
                    base16-test.c base64-test.c \
+                   blake2b-test.c blake2s-test.c \
                    camellia-test.c chacha-test.c \
                    cnd-memcpy-test.c \
                    des-test.c des3-test.c \
diff --git a/testsuite/blake2b-test.c b/testsuite/blake2b-test.c
new file mode 100644 (file)
index 0000000..1843cc9
--- /dev/null
@@ -0,0 +1,13 @@
+#include "testutils.h"
+
+#include "non-nettle.h"
+
+void
+test_main(void)
+{
+  test_hash(&nettle_blake2b_512, SDATA("abc"),
+           SHEX("BA 80 A5 3F 98 1C 4D 0D 6A 27 97 B6 9F 12 F6 E9"
+                "4C 21 2F 14 68 5A C4 B7 4B 12 BB 6F DB FF A2 D1"
+                "7D 87 C5 39 2A AB 79 2D C2 52 D5 DE 45 33 CC 95"
+                "18 D3 8A A8 DB F1 92 5A B9 23 86 ED D4 00 99 23"));
+}
diff --git a/testsuite/blake2s-test.c b/testsuite/blake2s-test.c
new file mode 100644 (file)
index 0000000..2a44728
--- /dev/null
@@ -0,0 +1,11 @@
+#include "testutils.h"
+
+#include "non-nettle.h"
+
+void
+test_main(void)
+{
+  test_hash(&nettle_blake2s_256, SDATA("abc"),
+           SHEX("50 8C 5E 8C 32 7C 14 E2 E1 A7 2B A3 4E EB 45 2F"
+                "37 45 8B 20 9E D6 3A 29 4D 99 9B 4C 86 67 59 82"));
+}