ec-field-test.c: Make the field-element type use internal format.
[secnet] / crypto-test.h
1 /*
2 * crypto-test.h: common test vector processing
3 */
4 /*
5 * This file is Free Software. It was originally written for secnet.
6 *
7 * Copyright 2017, 2019 Mark Wooding
8 *
9 * You may redistribute secnet as a whole and/or modify it under the
10 * terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 3, or (at your option) any
12 * later version.
13 *
14 * You may redistribute this file and/or modify it under the terms of
15 * the GNU General Public License as published by the Free Software
16 * Foundation; either version 2, or (at your option) any later
17 * version.
18 *
19 * This software is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this software; if not, see
26 * https://www.gnu.org/licenses/gpl.html.
27 */
28
29 #ifndef crypto_test_h
30 #define crypto_test_h
31
32 /* Basic model.
33 *
34 * There is a collection of `registers', each of which can store a value.
35 * Some registers are designated as `input': their values are set while
36 * reading the test vector. Other registers are designated as `output': the
37 * test function is expected to calculate their values, which are then
38 * compared against final values supplied by the test vector. Any
39 * discrepancies are reported.
40 *
41 * While a test suite is running, there is a single vector of registers, and
42 * registers are identified by index, starting from zero. The number of
43 * registers, `nreg', and a threshold `nrout', are defined by the test suite:
44 * registers with index less than `nrout' are for output; other registers up
45 * to, but not including, `nreg' are for input. Finally, the test suite
46 * defines the size of a register. The common test machinery treats
47 * registers as entirely opaque, acting on them only through their defined
48 * types.
49 *
50 * Each kind of test defines a register mapping, which assigns types and
51 * (textual) names to some subset of the registers. A register can be marked
52 * optional; by default, the test vector parser will report an error if a
53 * defined register is not assigned a value.
54 *
55 * The register type is responsible for handling the register on behalf of
56 * the common code. (Test functions can have built-in knowledge of which
57 * registers have which types, and can manipulate registers directly, of
58 * course.)
59 *
60 * Finally, each test defines a test runner, which is responsible for
61 * invoking the test function and checking that the output registers are
62 * correct. There is a generic test runner, but some tests might benefit
63 * from special arrangements.
64 */
65
66 union regval {
67 long i; /* signed integer */
68 unsigned long u; /* unsigned integer */
69 struct { unsigned char *p; size_t sz; } bytes; /* buffer of bytes */
70 struct { char *p; size_t sz; } str; /* text string */
71 #ifdef REG_MEMBERS
72 REG_MEMBERS /* your members here */
73 #endif
74 };
75
76 struct reg {
77 unsigned f; /* flags */
78 #define REGF_LIVE 1u /* input register has a value */
79 union regval v; /* register value */
80 };
81
82 struct regty {
83 void (*init)(union regval *v); /* set up raw memory */
84 void (*parse)(union regval *v, char *p); /* parse text input as value */
85 void (*dump)(FILE *fp, const union regval *v); /* dump value as text */
86 int (*eq)(const union regval *v0, const union regval *v1); /* equal? */
87 void (*release)(union regval *v); /* release any resources */
88 };
89
90 struct regdef {
91 const char *name; /* register name (for input files) */
92 unsigned i; /* register index */
93 const struct regty *ty; /* register type descriptor */
94 unsigned f; /* flags */
95 #define REGF_OPT 1u /* (input) register is optional */
96 };
97 #define REGLIST_END { 0 }
98
99 struct test_state {
100 struct reg *in, *out; /* vectors of registers */
101 unsigned nrout; /* number of output registers */
102 unsigned nreg; /* total number of registers */
103 size_t regsz; /* size of an individual register */
104 int win, lose; /* number of tests passed/failed */
105 };
106
107 struct test {
108 const char *name; /* name of the test */
109 void (*run)(struct test_state *state, const struct test *test);
110 /* test runner (`run_test') */
111 const struct regdef *regs; /* register definitions */
112 void (*fn)(struct reg *out, const struct reg *in, void *ctx);
113 /* test function */
114 };
115
116 /* Utility functions. */
117 extern NORETURN(bail(const char *msg, ...))
118 FORMAT(printf, 1, 2);
119 extern void parse_hex(uint8_t *b, size_t sz, char *p);
120 extern void dump_hex(FILE *fp, const uint8_t *b, size_t sz);
121 extern void trivial_regty_init(union regval *v);
122 extern void trivial_regty_release(union regval *v);
123 extern void allocate_bytes(union regval *v, size_t sz);
124 extern void allocate_string(union regval *v, size_t sz);
125
126 /* Built-in register types. */
127 extern const struct regty
128 regty_int,
129 regty_uint,
130 regty_bytes,
131 regty_string;
132
133 /* Running tests. */
134 extern void check_test_output(struct test_state *state,
135 const struct test *test);
136 extern void run_test(struct test_state *state, const struct test *test);
137 extern int run_test_suite(unsigned nrout, unsigned nreg, size_t regsz,
138 const struct test *tests, FILE *fp);
139
140 #endif