diff options
author | beck <> | 2024-12-13 00:17:18 +0000 |
---|---|---|
committer | beck <> | 2024-12-13 00:17:18 +0000 |
commit | d9dfb4af218b8d9fe842f363b39f2dc52cc54fc3 (patch) | |
tree | 96342312b2f330ea5c3d02d4c28c8c50ece4ee37 /src/regress/lib/libcrypto/mlkem/mlkem_unittest.c | |
parent | c1d2232367daaf8b4eb64a789c2280bf931a6b99 (diff) | |
download | openbsd-d9dfb4af218b8d9fe842f363b39f2dc52cc54fc3.tar.gz openbsd-d9dfb4af218b8d9fe842f363b39f2dc52cc54fc3.tar.bz2 openbsd-d9dfb4af218b8d9fe842f363b39f2dc52cc54fc3.zip |
Add ML-KEM 1024 from BoringSSL
Changes include conversion from C++, basic KNF, then adaptation to
use our sha3 functions for sha3 and shake instead of the BorinSSL
version. This Adds units tests to run against BoringSSL and NIST test
vectors.
The future public API is the same as Boring's - but is not yet exposed
pending making bytestring.h public (which will happen separately) and
a minor bump
Currently this will just ensure we build and run regress.
ok tb@ to get it into the tree and massage from there.
Diffstat (limited to 'src/regress/lib/libcrypto/mlkem/mlkem_unittest.c')
-rw-r--r-- | src/regress/lib/libcrypto/mlkem/mlkem_unittest.c | 136 |
1 files changed, 134 insertions, 2 deletions
diff --git a/src/regress/lib/libcrypto/mlkem/mlkem_unittest.c b/src/regress/lib/libcrypto/mlkem/mlkem_unittest.c index 71bfe60179..14832f1b41 100644 --- a/src/regress/lib/libcrypto/mlkem/mlkem_unittest.c +++ b/src/regress/lib/libcrypto/mlkem/mlkem_unittest.c | |||
@@ -52,8 +52,8 @@ encode_private_key(const struct MLKEM768_private_key *priv, uint8_t **out_buf, | |||
52 | return 1; | 52 | return 1; |
53 | } | 53 | } |
54 | 54 | ||
55 | int | 55 | static void |
56 | main(int argc, char **argv) | 56 | MlKem768UnitTest() |
57 | { | 57 | { |
58 | struct MLKEM768_private_key *priv, *priv2; | 58 | struct MLKEM768_private_key *priv, *priv2; |
59 | struct MLKEM768_public_key *pub, *pub2; | 59 | struct MLKEM768_public_key *pub, *pub2; |
@@ -145,5 +145,137 @@ main(int argc, char **argv) | |||
145 | free(priv); | 145 | free(priv); |
146 | free(priv2); | 146 | free(priv2); |
147 | 147 | ||
148 | } | ||
149 | |||
150 | static int | ||
151 | encode_1024public_key(const struct MLKEM1024_public_key *pub, uint8_t **out_buf, | ||
152 | size_t *out_len) | ||
153 | { | ||
154 | CBB cbb; | ||
155 | if (!CBB_init(&cbb, MLKEM1024_PUBLIC_KEY_BYTES)) | ||
156 | return 0; | ||
157 | if (!MLKEM1024_marshal_public_key(&cbb, pub)) | ||
158 | return 0; | ||
159 | if (!CBB_finish(&cbb, out_buf, out_len)) | ||
160 | return 0; | ||
161 | CBB_cleanup(&cbb); | ||
162 | return 1; | ||
163 | } | ||
164 | |||
165 | static int | ||
166 | encode_1024private_key(const struct MLKEM1024_private_key *priv, uint8_t **out_buf, | ||
167 | size_t *out_len) | ||
168 | { | ||
169 | CBB cbb; | ||
170 | if (!CBB_init(&cbb, MLKEM1024_PUBLIC_KEY_BYTES)) | ||
171 | return 0; | ||
172 | if (!MLKEM1024_marshal_private_key(&cbb, priv)) | ||
173 | return 0; | ||
174 | if (!CBB_finish(&cbb, out_buf, out_len)) | ||
175 | return 0; | ||
176 | CBB_cleanup(&cbb); | ||
177 | return 1; | ||
178 | } | ||
179 | |||
180 | static void | ||
181 | MlKem1024UnitTest() | ||
182 | { | ||
183 | struct MLKEM1024_private_key *priv, *priv2; | ||
184 | struct MLKEM1024_public_key *pub, *pub2; | ||
185 | uint8_t encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES]; | ||
186 | uint8_t ciphertext[MLKEM1024_CIPHERTEXT_BYTES]; | ||
187 | uint8_t shared_secret1[MLKEM_SHARED_SECRET_BYTES]; | ||
188 | uint8_t shared_secret2[MLKEM_SHARED_SECRET_BYTES]; | ||
189 | uint8_t first_two_bytes[2]; | ||
190 | uint8_t *encoded_private_key = NULL, *tmp_buf = NULL; | ||
191 | size_t encoded_private_key_len, tmp_buf_len; | ||
192 | CBS cbs; | ||
193 | |||
194 | fprintf(stderr, "ML-KEM 1024...\n"); | ||
195 | |||
196 | MALLOC(priv, sizeof(struct MLKEM1024_private_key)); | ||
197 | MLKEM1024_generate_key(encoded_public_key, NULL, priv); | ||
198 | |||
199 | memcpy(first_two_bytes, encoded_public_key, sizeof(first_two_bytes)); | ||
200 | memset(encoded_public_key, 0xff, sizeof(first_two_bytes)); | ||
201 | CBS_init(&cbs, encoded_public_key, | ||
202 | sizeof(encoded_public_key)); | ||
203 | MALLOC(pub, sizeof(struct MLKEM1024_public_key)); | ||
204 | /* Parsing should fail because the first coefficient is >= kPrime; */ | ||
205 | TEST(MLKEM1024_parse_public_key(pub, &cbs), | ||
206 | "Kyber_parse_public_key should have failed"); | ||
207 | |||
208 | memcpy(encoded_public_key, first_two_bytes, sizeof(first_two_bytes)); | ||
209 | CBS_init(&cbs, encoded_public_key, sizeof(encoded_public_key)); | ||
210 | TEST(!MLKEM1024_parse_public_key(pub, &cbs), | ||
211 | "MLKEM1024_parse_public_key"); | ||
212 | TEST(CBS_len(&cbs) != 0u, "CBS_len must be 0"); | ||
213 | |||
214 | TEST(!encode_1024public_key(pub, &tmp_buf, &tmp_buf_len), | ||
215 | "encode_1024public_key"); | ||
216 | TEST(sizeof(encoded_public_key) != tmp_buf_len, | ||
217 | "encoded public key lengths differ"); | ||
218 | TEST_DATAEQ(tmp_buf, encoded_public_key, tmp_buf_len, | ||
219 | "encoded public keys"); | ||
220 | free(tmp_buf); | ||
221 | tmp_buf = NULL; | ||
222 | |||
223 | MALLOC(pub2, sizeof(struct MLKEM1024_public_key)); | ||
224 | MLKEM1024_public_from_private(pub2, priv); | ||
225 | TEST(!encode_1024public_key(pub2, &tmp_buf, &tmp_buf_len), | ||
226 | "encode_public_key"); | ||
227 | TEST(sizeof(encoded_public_key) != tmp_buf_len, | ||
228 | "encoded public key lengths differ"); | ||
229 | TEST_DATAEQ(tmp_buf, encoded_public_key, tmp_buf_len, | ||
230 | "encoded pubic keys"); | ||
231 | free(tmp_buf); | ||
232 | tmp_buf = NULL; | ||
233 | |||
234 | TEST(!encode_1024private_key(priv, &encoded_private_key, | ||
235 | &encoded_private_key_len), "encode_1024private_key"); | ||
236 | |||
237 | memcpy(first_two_bytes, encoded_private_key, sizeof(first_two_bytes)); | ||
238 | memset(encoded_private_key, 0xff, sizeof(first_two_bytes)); | ||
239 | CBS_init(&cbs, encoded_private_key, encoded_private_key_len); | ||
240 | MALLOC(priv2, sizeof(struct MLKEM1024_private_key)); | ||
241 | /* Parsing should fail because the first coefficient is >= kPrime. */ | ||
242 | TEST(MLKEM1024_parse_private_key(priv2, &cbs), "Should not have parsed"); | ||
243 | |||
244 | memcpy(encoded_private_key, first_two_bytes, sizeof(first_two_bytes)); | ||
245 | CBS_init(&cbs, encoded_private_key, encoded_private_key_len); | ||
246 | TEST(!MLKEM1024_parse_private_key(priv2, &cbs), | ||
247 | "MLKEM1024_parse_private_key"); | ||
248 | TEST(!encode_1024private_key(priv2, &tmp_buf, &tmp_buf_len), | ||
249 | "encode_private_key"); | ||
250 | TEST(encoded_private_key_len != tmp_buf_len, | ||
251 | "encoded private key lengths differ"); | ||
252 | TEST_DATAEQ(tmp_buf, encoded_private_key, encoded_private_key_len, | ||
253 | "encoded private keys"); | ||
254 | free(tmp_buf); | ||
255 | tmp_buf = NULL; | ||
256 | |||
257 | MLKEM1024_encap(ciphertext, shared_secret1, pub); | ||
258 | MLKEM1024_decap(shared_secret2, ciphertext, MLKEM1024_CIPHERTEXT_BYTES, | ||
259 | priv); | ||
260 | TEST_DATAEQ(shared_secret1, shared_secret2, MLKEM_SHARED_SECRET_BYTES, | ||
261 | "shared secrets with priv"); | ||
262 | MLKEM1024_decap(shared_secret2, ciphertext, MLKEM1024_CIPHERTEXT_BYTES, | ||
263 | priv2); | ||
264 | TEST_DATAEQ(shared_secret1, shared_secret2, MLKEM_SHARED_SECRET_BYTES, | ||
265 | "shared secrets with priv2"); | ||
266 | |||
267 | free(encoded_private_key); | ||
268 | free(pub); | ||
269 | free(pub2); | ||
270 | free(priv); | ||
271 | free(priv2); | ||
272 | } | ||
273 | |||
274 | int | ||
275 | main(int argc, char **argv) | ||
276 | { | ||
277 | MlKem768UnitTest(); | ||
278 | MlKem1024UnitTest(); | ||
279 | |||
148 | exit(failure); | 280 | exit(failure); |
149 | } | 281 | } |