aboutsummaryrefslogtreecommitdiff
path: root/lib/tst/blake2s_selftest.cc
blob: 58199f621c3440bdc7b14db3d262cfdc18628c1e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// Self test Modules for  BLAKE2s
#include <gtest/gtest.h>

#include "../blake2/blake2s.c"
#include "blake2s_kat.h"

static_assert(sizeof(BLAKE2s_param) == (8 * sizeof(uint32_t)), "sizeof struct BLAKE2s_param");

// Deterministic sequences (Fibonacci generator).
static void
selftest_seq(uint8_t *out, size_t len, uint32_t seed)
{
  size_t i;
  uint32_t t, a, b;

  a = 0xDEAD4BAD * seed; // prime
  b = 1;

  for (i = 0; i < len; i++) { // fill the buf
    t = a + b;
    a = b;
    b = t;
    out[i] = (t >> 24) & 0xFF;
  }
}

// BLAKE2s self-test validation. Return 0 when OK.
int
blake2s_selftest()
{
  // Grand hash of hash results.
  const uint8_t blake2s_res[32] = {0x6A, 0x41, 0x1F, 0x08, 0xCE, 0x25, 0xAD, 0xCD, 0xFB, 0x02, 0xAB,
                                   0xA6, 0x41, 0x45, 0x1C, 0xEC, 0x53, 0xC5, 0x98, 0xB2, 0x4F, 0x4F,
                                   0xC7, 0x87, 0xFB, 0xDC, 0x88, 0x79, 0x7F, 0x4C, 0x1D, 0xFE};
  // Parameter sets.
  const size_t b2s_md_len[4] = {16, 20, 28, 32};
  const size_t b2s_in_len[6] = {0, 3, 64, 65, 255, 1024};

  size_t i, j, outlen, inlen;
  uint8_t in[1024], md[32], key[32];
  struct BLAKE2s_ctx ctx;

  // 256-bit hash for testing.
  if (BLAKE2s_init(&ctx, 32, NULL, 0)) return -1;

  for (i = 0; i < 4; i++) {
    outlen = b2s_md_len[i];
    for (j = 0; j < 6; j++) {
      inlen = b2s_in_len[j];

      selftest_seq(in, inlen, inlen); // unkeyed hash
      BLAKE2s(md, outlen, NULL, 0, in, inlen);
      BLAKE2s_update(&ctx, md, outlen); // hash the hash

      selftest_seq(key, outlen, outlen); // keyed hash
      BLAKE2s(md, outlen, key, outlen, in, inlen);
      BLAKE2s_update(&ctx, md, outlen); // hash the hash
    }
  }

  // Compute and compare the hash of hashes.
  BLAKE2s_final(&ctx, md);
  for (i = 0; i < 32; i++) {
    if (md[i] != blake2s_res[i]) return -1;
  }

  return 0;
}

TEST(blake2s, rotr_u32)
{
  EXPECT_EQ(rotr_u32(0xdecafade, 16), 0xfadedeca);
  EXPECT_EQ(rotr_u32(0xdecafade, 8), 0xdedecafa);
}

TEST(blake2s, selftest) { EXPECT_EQ(blake2s_selftest(), 0); }

TEST(blake2s, selftestAllInOne)
{
  const char *in = "abc";
  size_t inlen = 3;

  uint8_t out[32];
  BLAKE2s(out, 32, NULL, 0, in, inlen);

  const uint8_t blake2s_res[32] = {0x50, 0x8C, 0x5E, 0x8C, 0x32, 0x7C, 0x14, 0xE2, 0xE1, 0xA7, 0x2B,
                                   0xA3, 0x4E, 0xEB, 0x45, 0x2F, 0x37, 0x45, 0x8B, 0x20, 0x9E, 0xD6,
                                   0x3A, 0x29, 0x4D, 0x99, 0x9B, 0x4C, 0x86, 0x67, 0x59, 0x82};

  for (unsigned i = 0; i < 32; i++) {
    EXPECT_EQ(out[i], blake2s_res[i]) << "position=" << i;
  }
}

TEST(blake2s, KnownAnswerTest)
{
  uint8_t in[256];
  for (int i = 0; i < 256; ++i) in[i] = i;
  uint8_t out[32];

  for (unsigned i = 0; i < KATs_len; ++i) {
    EXPECT_EQ(BLAKE2s(out, 32, NULL, 0, in, i), 0);
    for (unsigned j = 0; j < 32; ++j) EXPECT_EQ(out[j], KATs[i][j]) << "on test=" << i << " pos=" << j;
  }
}

TEST(blake2s, KnownAnswerTestKeyed)
{
  uint8_t in[256];
  for (int i = 0; i < 256; ++i) in[i] = i;
  uint8_t out[32];

  for (unsigned i = 0; i < KATs_len; ++i) {
    EXPECT_EQ(BLAKE2s(out, 32, KAT_secret, 32, in, i), 0);
    for (unsigned j = 0; j < 32; ++j) EXPECT_EQ(out[j], secret_KATs[i][j]) << "on test=" << i << " pos=" << j;
  }
}