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
); }