summaryrefslogtreecommitdiff
path: root/src/regress/lib/libcrypto/mlkem/mlkem_unittest.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/regress/lib/libcrypto/mlkem/mlkem_unittest.c')
-rw-r--r--src/regress/lib/libcrypto/mlkem/mlkem_unittest.c283
1 files changed, 101 insertions, 182 deletions
diff --git a/src/regress/lib/libcrypto/mlkem/mlkem_unittest.c b/src/regress/lib/libcrypto/mlkem/mlkem_unittest.c
index 18bf128bea..3f7e2886b9 100644
--- a/src/regress/lib/libcrypto/mlkem/mlkem_unittest.c
+++ b/src/regress/lib/libcrypto/mlkem/mlkem_unittest.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mlkem_unittest.c,v 1.4 2024/12/20 00:07:12 tb Exp $ */ 1/* $OpenBSD: mlkem_unittest.c,v 1.5 2024/12/26 00:04:24 tb Exp $ */
2/* 2/*
3 * Copyright (c) 2024 Google Inc. 3 * Copyright (c) 2024 Google Inc.
4 * Copyright (c) 2024 Bob Beck <beck@obtuse.com> 4 * Copyright (c) 2024 Bob Beck <beck@obtuse.com>
@@ -27,13 +27,28 @@
27 27
28#include "mlkem_tests_util.h" 28#include "mlkem_tests_util.h"
29 29
30struct unittest_ctx {
31 void *priv;
32 void *pub;
33 void *priv2;
34 void *pub2;
35 uint8_t *encoded_public_key;
36 size_t encoded_public_key_len;
37 uint8_t *ciphertext;
38 size_t ciphertext_len;
39 mlkem_decap_fn decap;
40 mlkem_encap_fn encap;
41 mlkem_generate_key_fn generate_key;
42 mlkem_parse_private_key_fn parse_private_key;
43 mlkem_parse_public_key_fn parse_public_key;
44 mlkem_encode_private_key_fn encode_private_key;
45 mlkem_encode_public_key_fn encode_public_key;
46 mlkem_public_from_private_fn public_from_private;
47};
48
30static int 49static int
31MlKem768UnitTest(void) 50MlKemUnitTest(struct unittest_ctx *ctx)
32{ 51{
33 struct MLKEM768_private_key priv = { 0 }, priv2 = { 0 };
34 struct MLKEM768_public_key pub = { 0 }, pub2 = { 0 };
35 uint8_t encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES];
36 uint8_t ciphertext[MLKEM768_CIPHERTEXT_BYTES];
37 uint8_t shared_secret1[MLKEM_SHARED_SECRET_BYTES]; 52 uint8_t shared_secret1[MLKEM_SHARED_SECRET_BYTES];
38 uint8_t shared_secret2[MLKEM_SHARED_SECRET_BYTES]; 53 uint8_t shared_secret2[MLKEM_SHARED_SECRET_BYTES];
39 uint8_t first_two_bytes[2]; 54 uint8_t first_two_bytes[2];
@@ -42,22 +57,22 @@ MlKem768UnitTest(void)
42 CBS cbs; 57 CBS cbs;
43 int failed = 0; 58 int failed = 0;
44 59
45 MLKEM768_generate_key(encoded_public_key, NULL, &priv); 60 ctx->generate_key(ctx->encoded_public_key, NULL, ctx->priv);
46 61
47 memcpy(first_two_bytes, encoded_public_key, sizeof(first_two_bytes)); 62 memcpy(first_two_bytes, ctx->encoded_public_key, sizeof(first_two_bytes));
48 memset(encoded_public_key, 0xff, sizeof(first_two_bytes)); 63 memset(ctx->encoded_public_key, 0xff, sizeof(first_two_bytes));
49 64
50 CBS_init(&cbs, encoded_public_key, sizeof(encoded_public_key)); 65 CBS_init(&cbs, ctx->encoded_public_key, ctx->encoded_public_key_len);
51 66
52 /* Parsing should fail because the first coefficient is >= kPrime. */ 67 /* Parsing should fail because the first coefficient is >= kPrime. */
53 if (MLKEM768_parse_public_key(&pub, &cbs)) { 68 if (ctx->parse_public_key(ctx->pub, &cbs)) {
54 warnx("MLKEM768_parse_public_key should have failed"); 69 warnx("parse_public_key should have failed");
55 failed |= 1; 70 failed |= 1;
56 } 71 }
57 72
58 memcpy(encoded_public_key, first_two_bytes, sizeof(first_two_bytes)); 73 memcpy(ctx->encoded_public_key, first_two_bytes, sizeof(first_two_bytes));
59 CBS_init(&cbs, encoded_public_key, sizeof(encoded_public_key)); 74 CBS_init(&cbs, ctx->encoded_public_key, ctx->encoded_public_key_len);
60 if (!MLKEM768_parse_public_key(&pub, &cbs)) { 75 if (!ctx->parse_public_key(ctx->pub, &cbs)) {
61 warnx("MLKEM768_parse_public_key"); 76 warnx("MLKEM768_parse_public_key");
62 failed |= 1; 77 failed |= 1;
63 } 78 }
@@ -67,16 +82,16 @@ MlKem768UnitTest(void)
67 failed |= 1; 82 failed |= 1;
68 } 83 }
69 84
70 if (!mlkem768_encode_public_key(&pub, &tmp_buf, &tmp_buf_len)) { 85 if (!ctx->encode_public_key(ctx->pub, &tmp_buf, &tmp_buf_len)) {
71 warnx("encode_public_key"); 86 warnx("encode_public_key");
72 failed |= 1; 87 failed |= 1;
73 } 88 }
74 if (sizeof(encoded_public_key) != tmp_buf_len) { 89 if (ctx->encoded_public_key_len != tmp_buf_len) {
75 warnx("mlkem768 encoded public key lengths differ"); 90 warnx("encoded public key lengths differ");
76 failed |= 1; 91 failed |= 1;
77 } 92 }
78 93
79 if (compare_data(encoded_public_key, tmp_buf, tmp_buf_len, 768, 94 if (compare_data(ctx->encoded_public_key, tmp_buf, tmp_buf_len,
80 "encoded public keys") != 0) { 95 "encoded public keys") != 0) {
81 warnx("compare_data"); 96 warnx("compare_data");
82 failed |= 1; 97 failed |= 1;
@@ -84,17 +99,17 @@ MlKem768UnitTest(void)
84 free(tmp_buf); 99 free(tmp_buf);
85 tmp_buf = NULL; 100 tmp_buf = NULL;
86 101
87 MLKEM768_public_from_private(&pub2, &priv); 102 ctx->public_from_private(ctx->pub2, ctx->priv);
88 if (!mlkem768_encode_public_key(&pub2, &tmp_buf, &tmp_buf_len)) { 103 if (!ctx->encode_public_key(ctx->pub2, &tmp_buf, &tmp_buf_len)) {
89 warnx("mlkem768_encode_public_key"); 104 warnx("encode_public_key");
90 failed |= 1; 105 failed |= 1;
91 } 106 }
92 if (sizeof(encoded_public_key) != tmp_buf_len) { 107 if (ctx->encoded_public_key_len != tmp_buf_len) {
93 warnx("mlkem768 encoded public key lengths differ"); 108 warnx("encoded public key lengths differ");
94 failed |= 1; 109 failed |= 1;
95 } 110 }
96 111
97 if (compare_data(encoded_public_key, tmp_buf, tmp_buf_len, 768, 112 if (compare_data(ctx->encoded_public_key, tmp_buf, tmp_buf_len,
98 "encoded public keys") != 0) { 113 "encoded public keys") != 0) {
99 warnx("compare_data"); 114 warnx("compare_data");
100 failed |= 1; 115 failed |= 1;
@@ -102,7 +117,7 @@ MlKem768UnitTest(void)
102 free(tmp_buf); 117 free(tmp_buf);
103 tmp_buf = NULL; 118 tmp_buf = NULL;
104 119
105 if (!mlkem768_encode_private_key(&priv, &encoded_private_key, 120 if (!ctx->encode_private_key(ctx->priv, &encoded_private_key,
106 &encoded_private_key_len)) { 121 &encoded_private_key_len)) {
107 warnx("mlkem768_encode_private_key"); 122 warnx("mlkem768_encode_private_key");
108 failed |= 1; 123 failed |= 1;
@@ -113,7 +128,7 @@ MlKem768UnitTest(void)
113 CBS_init(&cbs, encoded_private_key, encoded_private_key_len); 128 CBS_init(&cbs, encoded_private_key, encoded_private_key_len);
114 129
115 /* Parsing should fail because the first coefficient is >= kPrime. */ 130 /* Parsing should fail because the first coefficient is >= kPrime. */
116 if (MLKEM768_parse_private_key(&priv2, &cbs)) { 131 if (ctx->parse_private_key(ctx->priv2, &cbs)) {
117 warnx("MLKEM768_parse_private_key should have failed"); 132 warnx("MLKEM768_parse_private_key should have failed");
118 failed |= 1; 133 failed |= 1;
119 } 134 }
@@ -121,162 +136,22 @@ MlKem768UnitTest(void)
121 memcpy(encoded_private_key, first_two_bytes, sizeof(first_two_bytes)); 136 memcpy(encoded_private_key, first_two_bytes, sizeof(first_two_bytes));
122 CBS_init(&cbs, encoded_private_key, encoded_private_key_len); 137 CBS_init(&cbs, encoded_private_key, encoded_private_key_len);
123 138
124 if (!MLKEM768_parse_private_key(&priv2, &cbs)) { 139 if (!ctx->parse_private_key(ctx->priv2, &cbs)) {
125 warnx("MLKEM768_parse_private_key"); 140 warnx("MLKEM768_parse_private_key");
126 failed |= 1; 141 failed |= 1;
127 } 142 }
128 143
129 if (!mlkem768_encode_private_key(&priv2, &tmp_buf, &tmp_buf_len)) { 144 if (!ctx->encode_private_key(ctx->priv2, &tmp_buf, &tmp_buf_len)) {
130 warnx("mlkem768_encode_private_key"); 145 warnx("encode_private_key");
131 failed |= 1;
132 }
133
134 if (encoded_private_key_len != tmp_buf_len) {
135 warnx("mlkem768 encode private key lengths differ");
136 failed |= 1;
137 }
138
139 if (compare_data(encoded_private_key, tmp_buf, tmp_buf_len, 768,
140 "encoded private key") != 0) {
141 warnx("compare_data");
142 failed |= 1;
143 }
144
145 free(tmp_buf);
146 tmp_buf = NULL;
147
148 MLKEM768_encap(ciphertext, shared_secret1, &pub);
149 MLKEM768_decap(shared_secret2, ciphertext, MLKEM768_CIPHERTEXT_BYTES,
150 &priv);
151 if (compare_data(shared_secret1, shared_secret2, MLKEM_SHARED_SECRET_BYTES,
152 768, "shared secrets with priv") != 0) {
153 warnx("compare_data");
154 failed |= 1;
155 }
156
157 MLKEM768_decap(shared_secret2, ciphertext, MLKEM768_CIPHERTEXT_BYTES,
158 &priv2);
159 if (compare_data(shared_secret1, shared_secret2, MLKEM_SHARED_SECRET_BYTES,
160 768, "shared secrets with priv2") != 0) {
161 warnx("compare_data");
162 failed |= 1;
163 }
164
165 free(encoded_private_key);
166
167 return failed;
168}
169
170static int
171MlKem1024UnitTest(void)
172{
173 struct MLKEM1024_private_key priv = { 0 }, priv2 = { 0 };
174 struct MLKEM1024_public_key pub = { 0 }, pub2 = { 0 };
175 uint8_t encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES];
176 uint8_t ciphertext[MLKEM1024_CIPHERTEXT_BYTES];
177 uint8_t shared_secret1[MLKEM_SHARED_SECRET_BYTES];
178 uint8_t shared_secret2[MLKEM_SHARED_SECRET_BYTES];
179 uint8_t first_two_bytes[2];
180 uint8_t *encoded_private_key = NULL, *tmp_buf = NULL;
181 size_t encoded_private_key_len, tmp_buf_len;
182 CBS cbs;
183 int failed = 0;
184
185 MLKEM1024_generate_key(encoded_public_key, NULL, &priv);
186
187 memcpy(first_two_bytes, encoded_public_key, sizeof(first_two_bytes));
188 memset(encoded_public_key, 0xff, sizeof(first_two_bytes));
189
190 CBS_init(&cbs, encoded_public_key, sizeof(encoded_public_key));
191
192 /* Parsing should fail because the first coefficient is >= kPrime. */
193 if (MLKEM1024_parse_public_key(&pub, &cbs)) {
194 warnx("MLKEM1024_parse_public_key should have failed");
195 failed |= 1;
196 }
197
198 memcpy(encoded_public_key, first_two_bytes, sizeof(first_two_bytes));
199 CBS_init(&cbs, encoded_public_key, sizeof(encoded_public_key));
200 if (!MLKEM1024_parse_public_key(&pub, &cbs)) {
201 warnx("MLKEM1024_parse_public_key");
202 failed |= 1;
203 }
204
205 if (CBS_len(&cbs) != 0u) {
206 warnx("CBS_len must be 0");
207 failed |= 1;
208 }
209
210 if (!mlkem1024_encode_public_key(&pub, &tmp_buf, &tmp_buf_len)) {
211 warnx("encode_public_key");
212 failed |= 1;
213 }
214 if (sizeof(encoded_public_key) != tmp_buf_len) {
215 warnx("mlkem1024 encoded public key lengths differ");
216 failed |= 1;
217 }
218
219 if (compare_data(encoded_public_key, tmp_buf, tmp_buf_len, 1024,
220 "encoded public keys") != 0) {
221 warnx("compare_data");
222 failed |= 1;
223 }
224 free(tmp_buf);
225 tmp_buf = NULL;
226
227 MLKEM1024_public_from_private(&pub2, &priv);
228 if (!mlkem1024_encode_public_key(&pub2, &tmp_buf, &tmp_buf_len)) {
229 warnx("mlkem1024_encode_public_key");
230 failed |= 1;
231 }
232 if (sizeof(encoded_public_key) != tmp_buf_len) {
233 warnx("mlkem1024 encoded public key lengths differ");
234 failed |= 1;
235 }
236
237 if (compare_data(encoded_public_key, tmp_buf, tmp_buf_len, 1024,
238 "encoded public keys") != 0) {
239 warnx("compare_data");
240 failed |= 1;
241 }
242 free(tmp_buf);
243 tmp_buf = NULL;
244
245 if (!mlkem1024_encode_private_key(&priv, &encoded_private_key,
246 &encoded_private_key_len)) {
247 warnx("mlkem1024_encode_private_key");
248 failed |= 1;
249 }
250
251 memcpy(first_two_bytes, encoded_private_key, sizeof(first_two_bytes));
252 memset(encoded_private_key, 0xff, sizeof(first_two_bytes));
253 CBS_init(&cbs, encoded_private_key, encoded_private_key_len);
254
255 /* Parsing should fail because the first coefficient is >= kPrime. */
256 if (MLKEM1024_parse_private_key(&priv2, &cbs)) {
257 warnx("MLKEM1024_parse_private_key should have failed");
258 failed |= 1;
259 }
260
261 memcpy(encoded_private_key, first_two_bytes, sizeof(first_two_bytes));
262 CBS_init(&cbs, encoded_private_key, encoded_private_key_len);
263
264 if (!MLKEM1024_parse_private_key(&priv2, &cbs)) {
265 warnx("MLKEM1024_parse_private_key");
266 failed |= 1;
267 }
268
269 if (!mlkem1024_encode_private_key(&priv2, &tmp_buf, &tmp_buf_len)) {
270 warnx("mlkem1024_encode_private_key");
271 failed |= 1; 146 failed |= 1;
272 } 147 }
273 148
274 if (encoded_private_key_len != tmp_buf_len) { 149 if (encoded_private_key_len != tmp_buf_len) {
275 warnx("mlkem1024 encode private key lengths differ"); 150 warnx("encode private key lengths differ");
276 failed |= 1; 151 failed |= 1;
277 } 152 }
278 153
279 if (compare_data(encoded_private_key, tmp_buf, tmp_buf_len, 1024, 154 if (compare_data(encoded_private_key, tmp_buf, tmp_buf_len,
280 "encoded private key") != 0) { 155 "encoded private key") != 0) {
281 warnx("compare_data"); 156 warnx("compare_data");
282 failed |= 1; 157 failed |= 1;
@@ -285,19 +160,19 @@ MlKem1024UnitTest(void)
285 free(tmp_buf); 160 free(tmp_buf);
286 tmp_buf = NULL; 161 tmp_buf = NULL;
287 162
288 MLKEM1024_encap(ciphertext, shared_secret1, &pub); 163 ctx->encap(ctx->ciphertext, shared_secret1, ctx->pub);
289 MLKEM1024_decap(shared_secret2, ciphertext, MLKEM1024_CIPHERTEXT_BYTES, 164 ctx->decap(shared_secret2, ctx->ciphertext, ctx->ciphertext_len,
290 &priv); 165 ctx->priv);
291 if (compare_data(shared_secret1, shared_secret2, MLKEM_SHARED_SECRET_BYTES, 166 if (compare_data(shared_secret1, shared_secret2, MLKEM_SHARED_SECRET_BYTES,
292 1024, "shared secrets with priv") != 0) { 167 "shared secrets with priv") != 0) {
293 warnx("compare_data"); 168 warnx("compare_data");
294 failed |= 1; 169 failed |= 1;
295 } 170 }
296 171
297 MLKEM1024_decap(shared_secret2, ciphertext, MLKEM1024_CIPHERTEXT_BYTES, 172 ctx->decap(shared_secret2, ctx->ciphertext, ctx->ciphertext_len,
298 &priv2); 173 ctx->priv2);
299 if (compare_data(shared_secret1, shared_secret2, MLKEM_SHARED_SECRET_BYTES, 174 if (compare_data(shared_secret1, shared_secret2, MLKEM_SHARED_SECRET_BYTES,
300 1024, "shared secrets with priv2") != 0) { 175 "shared secrets with priv2") != 0) {
301 warnx("compare_data"); 176 warnx("compare_data");
302 failed |= 1; 177 failed |= 1;
303 } 178 }
@@ -308,12 +183,56 @@ MlKem1024UnitTest(void)
308} 183}
309 184
310int 185int
311main(int argc, char **argv) 186main(void)
312{ 187{
188 struct MLKEM768_private_key mlkem768_priv, mlkem768_priv2;
189 struct MLKEM768_public_key mlkem768_pub, mlkem768_pub2;
190 uint8_t mlkem768_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES];
191 uint8_t mlkem768_ciphertext[MLKEM768_CIPHERTEXT_BYTES];
192 struct unittest_ctx mlkem768_test = {
193 .priv = &mlkem768_priv,
194 .pub = &mlkem768_pub,
195 .priv2 = &mlkem768_priv2,
196 .pub2 = &mlkem768_pub2,
197 .encoded_public_key = mlkem768_encoded_public_key,
198 .encoded_public_key_len = sizeof(mlkem768_encoded_public_key),
199 .ciphertext = mlkem768_ciphertext,
200 .ciphertext_len = sizeof(mlkem768_ciphertext),
201 .decap = mlkem768_decap,
202 .encap = mlkem768_encap,
203 .generate_key = mlkem768_generate_key,
204 .parse_private_key = mlkem768_parse_private_key,
205 .parse_public_key = mlkem768_parse_public_key,
206 .encode_private_key = mlkem768_encode_private_key,
207 .encode_public_key = mlkem768_encode_public_key,
208 .public_from_private = mlkem768_public_from_private,
209 };
210 struct MLKEM1024_private_key mlkem1024_priv, mlkem1024_priv2;
211 struct MLKEM1024_public_key mlkem1024_pub, mlkem1024_pub2;
212 uint8_t mlkem1024_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES];
213 uint8_t mlkem1024_ciphertext[MLKEM1024_CIPHERTEXT_BYTES];
214 struct unittest_ctx mlkem1024_test = {
215 .priv = &mlkem1024_priv,
216 .pub = &mlkem1024_pub,
217 .priv2 = &mlkem1024_priv2,
218 .pub2 = &mlkem1024_pub2,
219 .encoded_public_key = mlkem1024_encoded_public_key,
220 .encoded_public_key_len = sizeof(mlkem1024_encoded_public_key),
221 .ciphertext = mlkem1024_ciphertext,
222 .ciphertext_len = sizeof(mlkem1024_ciphertext),
223 .decap = mlkem1024_decap,
224 .encap = mlkem1024_encap,
225 .generate_key = mlkem1024_generate_key,
226 .parse_private_key = mlkem1024_parse_private_key,
227 .parse_public_key = mlkem1024_parse_public_key,
228 .encode_private_key = mlkem1024_encode_private_key,
229 .encode_public_key = mlkem1024_encode_public_key,
230 .public_from_private = mlkem1024_public_from_private,
231 };
313 int failed = 0; 232 int failed = 0;
314 233
315 failed |= MlKem768UnitTest(); 234 failed |= MlKemUnitTest(&mlkem768_test);
316 failed |= MlKem1024UnitTest(); 235 failed |= MlKemUnitTest(&mlkem1024_test);
317 236
318 return failed; 237 return failed;
319} 238}