summaryrefslogtreecommitdiff
path: root/src/regress/lib/libcrypto/mlkem/mlkem768_decap_tests.c
diff options
context:
space:
mode:
authortb <>2024-12-26 00:04:24 +0000
committertb <>2024-12-26 00:04:24 +0000
commit31d1b04da9af806cdb66a2b49ed6490e67479eef (patch)
treef187d226245651988501e2fb8891081ff9eea9f2 /src/regress/lib/libcrypto/mlkem/mlkem768_decap_tests.c
parentfe8b80dbfd7a71d866da84cfdab5d2ce23feac28 (diff)
downloadopenbsd-31d1b04da9af806cdb66a2b49ed6490e67479eef.tar.gz
openbsd-31d1b04da9af806cdb66a2b49ed6490e67479eef.tar.bz2
openbsd-31d1b04da9af806cdb66a2b49ed6490e67479eef.zip
Overhaul ML-KEM regress once more
Implement a file parser that drives a state machine to extract the test data from the .txt files and manages the parsed data. Comments and empty lines are ignored. The code currently assumes that instruction lines are at the start of the file (which isn't generally true) and only supports two line types for now. This is good enough for all the ML-KEM tests but should be easy enough to extend. Once all data for a test case is parsed in the expected order, a test handler is called which can retrieve the test data via a simple API and throw warnings and errors with information on the test case line number, etc. Merge the tests into three programs: one parsing the .txt files and running the corresponding test cases, a unit test and the iteration tests. Deduplicate the actual test code and let the caller pass in an object containing the API functions, private keys and arrays that need to be different between the 768 version and the 1024 version. This way we don't have two sets of half a dozen .c files differing only in 3 or 4 occurrences of 768 and 1024. All this will also make it a lot easier to hook these tests into portable.
Diffstat (limited to 'src/regress/lib/libcrypto/mlkem/mlkem768_decap_tests.c')
-rw-r--r--src/regress/lib/libcrypto/mlkem/mlkem768_decap_tests.c195
1 files changed, 0 insertions, 195 deletions
diff --git a/src/regress/lib/libcrypto/mlkem/mlkem768_decap_tests.c b/src/regress/lib/libcrypto/mlkem/mlkem768_decap_tests.c
deleted file mode 100644
index a58f005644..0000000000
--- a/src/regress/lib/libcrypto/mlkem/mlkem768_decap_tests.c
+++ /dev/null
@@ -1,195 +0,0 @@
1/* $OpenBSD: mlkem768_decap_tests.c,v 1.4 2024/12/20 00:32:15 tb Exp $ */
2/*
3 * Copyright (c) 2024 Google Inc.
4 * Copyright (c) 2024 Bob Beck <beck@obtuse.com>
5 * Copyright (c) 2024 Theo Buehler <tb@openbsd.org>
6 *
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
14 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
16 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
17 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include <assert.h>
21#include <err.h>
22#include <stdint.h>
23#include <stdio.h>
24#include <stdlib.h>
25
26#include "bytestring.h"
27#include "mlkem.h"
28
29#include "mlkem_tests_util.h"
30
31static int
32MlkemDecapFileTest(CBB *ciphertext_cbb, CBB *shared_secret_cbb,
33 CBB *private_key_cbb, int should_fail, size_t line)
34{
35 struct MLKEM768_private_key priv;
36 uint8_t *ciphertext = NULL, *shared_secret = NULL, *private_key = NULL;
37 size_t ciphertext_len = 0, shared_secret_len = 0, private_key_len = 0;
38 uint8_t shared_secret_buf[MLKEM_SHARED_SECRET_BYTES];
39 CBS private_key_cbs;
40 int failed = 1;
41
42 if (!CBB_finish(ciphertext_cbb, &ciphertext, &ciphertext_len))
43 goto err;
44 if (!CBB_finish(shared_secret_cbb, &shared_secret, &shared_secret_len))
45 goto err;
46 if (!CBB_finish(private_key_cbb, &private_key, &private_key_len))
47 goto err;
48
49 CBS_init(&private_key_cbs, private_key, private_key_len);
50
51 if (!MLKEM768_parse_private_key(&priv, &private_key_cbs)) {
52 if ((failed = !should_fail))
53 warnx("#%zu: parse_private_key", line);
54 goto err;
55 }
56 if (!MLKEM768_decap(shared_secret_buf, ciphertext, ciphertext_len,
57 &priv)) {
58 if ((failed = !should_fail))
59 warnx("#%zu: decap", line);
60 goto err;
61 }
62
63 failed = compare_data(shared_secret, shared_secret_buf,
64 MLKEM_SHARED_SECRET_BYTES, line, "shared_secret");
65
66 if (should_fail != failed) {
67 warnx("FAIL: #%zu: should_fail %d, failed %d",
68 line, should_fail, failed);
69 failed = 1;
70 }
71
72 err:
73 CBB_cleanup(ciphertext_cbb);
74 CBB_cleanup(shared_secret_cbb);
75 CBB_cleanup(private_key_cbb);
76 freezero(ciphertext, ciphertext_len);
77 freezero(shared_secret, shared_secret_len);
78 freezero(private_key, private_key_len);
79
80 return failed;
81}
82
83#define S_START 0
84#define S_COMMENT 1
85#define S_PRIVATE_KEY 2
86#define S_CIPHERTEXT 3
87#define S_RESULT 4
88#define S_SHARED_SECRET 5
89
90#define S2S(x) case x: return #x
91
92static const char *
93state2str(int state)
94{
95 switch (state) {
96 S2S(S_START);
97 S2S(S_COMMENT);
98 S2S(S_PRIVATE_KEY);
99 S2S(S_CIPHERTEXT);
100 S2S(S_RESULT);
101 S2S(S_SHARED_SECRET);
102 default:
103 errx(1, "unknown state %d", state);
104 }
105}
106
107int
108main(int argc, char **argv)
109{
110 CBB ciphertext = { 0 }, shared_secret = { 0 }, private_key = { 0 };
111 int should_fail = 0;
112 const char *test;
113 size_t line = 0;
114 char *buf = NULL;
115 size_t buflen = 0;
116 ssize_t len;
117 FILE *fp;
118 int state;
119 int failed = 0;
120
121 if (argc < 2)
122 errx(1, "%s: missing test file", argv[0]);
123
124 test = argv[1];
125
126 if ((fp = fopen(test, "r")) == NULL)
127 err(1, "can't open test file");
128
129 state = S_COMMENT;
130 line = 0;
131
132 while ((len = getline(&buf, &buflen, fp)) != -1) {
133 const char *msg = state2str(state);
134 CBS cbs;
135 uint8_t u8;
136
137 line++;
138 CBS_init(&cbs, buf, len);
139
140 if (!CBS_get_last_u8(&cbs, &u8))
141 errx(1, "#%zu %s: CBB_get_last_u8", line, msg);
142 assert(u8 == '\n');
143
144 switch (state) {
145 case S_START:
146 state = S_COMMENT;
147 break;
148 case S_COMMENT:
149 if (!CBS_get_u8(&cbs, &u8))
150 errx(1, "#%zu %s: CBB_get_u8", line, msg);
151 assert(u8 == '#');
152 if (!CBS_skip(&cbs, CBS_len(&cbs)))
153 errx(1, "#%zu %s: CBB_skip", line, msg);
154 state = S_PRIVATE_KEY;
155 break;
156 case S_PRIVATE_KEY:
157 if (!get_string_cbs(&cbs, "private_key: ", line, msg))
158 errx(1, "#%zu %s: get_string_cbs", line, msg);
159 hex_decode_cbs(&cbs, &private_key, line, msg);
160 state = S_CIPHERTEXT;
161 break;
162 case S_CIPHERTEXT:
163 if (!get_string_cbs(&cbs, "ciphertext: ", line, msg))
164 errx(1, "#%zu %s: get_string_cbs", line, msg);
165 hex_decode_cbs(&cbs, &ciphertext, line, msg);
166 state = S_RESULT;
167 break;
168 case S_RESULT:
169 if (!get_string_cbs(&cbs, "result: ", line, msg))
170 errx(1, "#%zu %s: get_string_cbs", line, msg);
171 should_fail = get_string_cbs(&cbs, "fail", line, msg);
172 state = S_SHARED_SECRET;
173 break;
174 case S_SHARED_SECRET:
175 if (!get_string_cbs(&cbs, "shared_secret: ", line, msg))
176 errx(1, "#%zu %s: get_string_cbs", line, msg);
177 hex_decode_cbs(&cbs, &shared_secret, line, msg);
178
179 failed |= MlkemDecapFileTest(&ciphertext, &shared_secret,
180 &private_key, should_fail, line);
181
182 state = S_START;
183 break;
184 }
185 if (CBS_len(&cbs) > 0)
186 errx(1, "#%zu %s: CBS_len", line, msg);
187 }
188 free(buf);
189
190 if (ferror(fp))
191 err(1, NULL);
192 fclose(fp);
193
194 return failed;
195}