2 * sha3-test.c: test harness for SHA3 and related functions
4 * (The implementations originally came with different test arrangements,
5 * with complicated external dependencies. This file replicates the original
6 * tests, but without the dependencies.)
9 * This file is Free Software. It was originally written for secnet.
11 * Copyright 2019 Mark Wooding
13 * You may redistribute secnet as a whole and/or modify it under the
14 * terms of the GNU General Public License as published by the Free
15 * Software Foundation; either version 3, or (at your option) any
18 * You may redistribute this file and/or modify it under the terms of
19 * the GNU General Public License as published by the Free Software
20 * Foundation; either version 2, or (at your option) any later
23 * This software is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this software; if not, see
30 * https://www.gnu.org/licenses/gpl.html.
37 #include "keccak1600.h"
39 #include "crypto-test.h"
43 RM = NROUT, RN, RFUNC, RPERSO, NREG
51 static void run_sha3_kat(struct test_state *state, const struct test *test)
53 static const unsigned steps[] = { 1, 7, 192, -1 };
55 struct test_context ctx;
57 ctx.outsz = state->in[RH].v.bytes.sz;
60 test->fn(state->out, state->in, &ctx);
61 check_test_output(state, test);
62 } while (steps[i++] != (unsigned)-1);
65 #define SHA3_VARIANTS(_) _(224) _(256) _(384) _(512)
67 #define SHA3_TESTFUNCS(w) \
69 static void test_sha3_##w##_kat(struct reg *out, \
70 const struct reg *in, void *vctx) \
72 struct test_context *ctx = vctx; \
74 const octet *p = in[RM].v.bytes.p; \
75 size_t sz = in[RM].v.bytes.sz, n; \
77 allocate_bytes(&out[RH].v, SHA3_##w##_HASHSZ); \
78 sha3_##w##_init(&hctx); \
80 n = ctx->step; if (n > sz) n = sz; \
81 sha3_hash(&hctx, p, n); p += n; sz -= n; \
83 sha3_done(&hctx, out[RH].v.bytes.p); \
86 static void test_sha3_##w##_mct(struct reg *out, \
87 const struct reg *in, void *vctx) \
91 unsigned i, n = in[RN].v.u; \
93 allocate_bytes(&out[RH].v, SHA3_##w##_HASHSZ); \
94 p = out[RH].v.bytes.p; \
95 memcpy(p, in[RM].v.bytes.p, SHA3_##w##_HASHSZ); \
96 for (i = 0; i < n; i++) { \
97 sha3_##w##_init(&hctx); \
98 sha3_hash(&hctx, p, SHA3_##w##_HASHSZ); \
99 sha3_done(&hctx, p); \
103 SHA3_VARIANTS(SHA3_TESTFUNCS)
105 #define SHAKE_VARIANTS(_) _(128) _(256)
107 #define SHAKE_TESTFUNCS(w) \
109 static void test_shake##w##_kat(struct reg *out, \
110 const struct reg *in, void *vctx) \
112 struct test_context *ctx = vctx; \
114 const octet *p = in[RM].v.bytes.p; octet *q; \
115 size_t sz = in[RM].v.bytes.sz, n; \
117 allocate_bytes(&out[RH].v, ctx->outsz); \
118 shake##w##_init(&hctx); \
120 n = ctx->step; if (n > sz) n = sz; \
121 shake_hash(&hctx, p, n); p += n; sz -= n; \
124 q = out[RH].v.bytes.p; sz = ctx->outsz; \
126 n = ctx->step; if (n > sz) n = sz; \
127 shake_get(&hctx, q, n); q += n; sz -= n; \
131 static void test_cshake##w##_kat(struct reg *out, \
132 const struct reg *in, void *vctx) \
134 struct test_context *ctx = vctx; \
136 const octet *p = in[RM].v.bytes.p; octet *q; \
137 size_t sz = in[RM].v.bytes.sz, n; \
139 allocate_bytes(&out[RH].v, ctx->outsz); \
140 cshake##w##_init(&hctx, \
141 in[RFUNC].v.str.p, in[RFUNC].v.str.sz, \
142 in[RPERSO].v.str.p, in[RPERSO].v.str.sz); \
144 n = ctx->step; if (n > sz) n = sz; \
145 shake_hash(&hctx, p, n); p += n; sz -= n; \
148 q = out[RH].v.bytes.p; sz = ctx->outsz; \
150 n = ctx->step; if (n > sz) n = sz; \
151 shake_get(&hctx, q, n); q += n; sz -= n; \
155 SHAKE_VARIANTS(SHAKE_TESTFUNCS)
157 #define REG_M { "m", RM, ®ty_bytes, 0 }
158 #define REG_N { "n", RN, ®ty_uint, 0 }
159 #define REG_FUNC { "func", RFUNC, ®ty_string, 0 }
160 #define REG_PERSO { "perso", RPERSO, ®ty_string, 0 }
161 #define REG_H { "h", RH, ®ty_bytes, 0 }
162 static const struct regdef
163 hash_kat_regs[] = { REG_M, REG_H, REGLIST_END },
164 hash_mct_regs[] = { REG_M, REG_N, REG_H, REGLIST_END },
165 cshake_regs[] = { REG_M, REG_FUNC, REG_PERSO, REG_H, REGLIST_END };
167 #define SHA3_TESTDEFS(w) \
168 { "sha3-" #w "-hex", run_sha3_kat, \
169 hash_kat_regs, test_sha3_##w##_kat }, \
170 { "sha3-" #w "-mct", run_test, \
171 hash_mct_regs, test_sha3_##w##_mct },
172 #define SHAKE_TESTDEFS(w) \
173 { "shake" #w, run_sha3_kat, \
174 hash_kat_regs, test_shake##w##_kat }, \
175 { "cshake" #w, run_sha3_kat, \
176 cshake_regs, test_cshake##w##_kat },
177 static const struct test tests[] = {
178 SHA3_VARIANTS(SHA3_TESTDEFS)
179 SHAKE_VARIANTS(SHAKE_TESTDEFS)
184 { return run_test_suite(NROUT, NREG, sizeof(struct reg), tests, stdin); }