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.c149
1 files changed, 149 insertions, 0 deletions
diff --git a/src/regress/lib/libcrypto/mlkem/mlkem_unittest.c b/src/regress/lib/libcrypto/mlkem/mlkem_unittest.c
new file mode 100644
index 0000000000..71bfe60179
--- /dev/null
+++ b/src/regress/lib/libcrypto/mlkem/mlkem_unittest.c
@@ -0,0 +1,149 @@
1/* Copyright (c) 2024, Google Inc.
2 * Copyright (c) 2024, Bob Beck <beck@obtuse.com>
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
15
16#include <stdlib.h>
17#include <stdio.h>
18#include <string.h>
19
20#include "bytestring.h"
21#include "mlkem.h"
22#include "mlkem_internal.h"
23#include "mlkem_tests_util.h"
24
25static int
26encode_public_key(const struct MLKEM768_public_key *pub, uint8_t **out_buf,
27 size_t *out_len)
28{
29 CBB cbb;
30 if (!CBB_init(&cbb, MLKEM768_PUBLIC_KEY_BYTES))
31 return 0;
32 if (!MLKEM768_marshal_public_key(&cbb, pub))
33 return 0;
34 if (!CBB_finish(&cbb, out_buf, out_len))
35 return 0;
36 CBB_cleanup(&cbb);
37 return 1;
38}
39
40static int
41encode_private_key(const struct MLKEM768_private_key *priv, uint8_t **out_buf,
42 size_t *out_len)
43{
44 CBB cbb;
45 if (!CBB_init(&cbb, MLKEM768_PUBLIC_KEY_BYTES))
46 return 0;
47 if (!MLKEM768_marshal_private_key(&cbb, priv))
48 return 0;
49 if (!CBB_finish(&cbb, out_buf, out_len))
50 return 0;
51 CBB_cleanup(&cbb);
52 return 1;
53}
54
55int
56main(int argc, char **argv)
57{
58 struct MLKEM768_private_key *priv, *priv2;
59 struct MLKEM768_public_key *pub, *pub2;
60 uint8_t encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES];
61 uint8_t ciphertext[MLKEM768_CIPHERTEXT_BYTES];
62 uint8_t shared_secret1[MLKEM_SHARED_SECRET_BYTES];
63 uint8_t shared_secret2[MLKEM_SHARED_SECRET_BYTES];
64 uint8_t first_two_bytes[2];
65 uint8_t *encoded_private_key = NULL, *tmp_buf = NULL;
66 size_t encoded_private_key_len, tmp_buf_len;
67 CBS cbs;
68
69 fprintf(stderr, "ML-KEM 768...\n");
70
71 MALLOC(priv, sizeof(struct MLKEM768_private_key));
72 MLKEM768_generate_key(encoded_public_key, NULL, priv);
73
74 memcpy(first_two_bytes, encoded_public_key, sizeof(first_two_bytes));
75 memset(encoded_public_key, 0xff, sizeof(first_two_bytes));
76 CBS_init(&cbs, encoded_public_key,
77 sizeof(encoded_public_key));
78 MALLOC(pub, sizeof(struct MLKEM768_public_key));
79 /* Parsing should fail because the first coefficient is >= kPrime; */
80 TEST(MLKEM768_parse_public_key(pub, &cbs),
81 "Kyber_parse_public_key should have failed");
82
83 memcpy(encoded_public_key, first_two_bytes, sizeof(first_two_bytes));
84 CBS_init(&cbs, encoded_public_key, sizeof(encoded_public_key));
85 TEST(!MLKEM768_parse_public_key(pub, &cbs),
86 "MLKEM768_parse_public_key");
87 TEST(CBS_len(&cbs) != 0u, "CBS_len must be 0");
88
89 TEST(!encode_public_key(pub, &tmp_buf, &tmp_buf_len),
90 "encode_public_key");
91 TEST(sizeof(encoded_public_key) != tmp_buf_len,
92 "encoded public key lengths differ");
93 TEST_DATAEQ(tmp_buf, encoded_public_key, tmp_buf_len,
94 "encoded public keys");
95 free(tmp_buf);
96 tmp_buf = NULL;
97
98 MALLOC(pub2, sizeof(struct MLKEM768_public_key));
99 MLKEM768_public_from_private(pub2, priv);
100 TEST(!encode_public_key(pub2, &tmp_buf, &tmp_buf_len),
101 "encode_public_key");
102 TEST(sizeof(encoded_public_key) != tmp_buf_len,
103 "encoded public key lengths differ");
104 TEST_DATAEQ(tmp_buf, encoded_public_key, tmp_buf_len,
105 "encoded pubic keys");
106 free(tmp_buf);
107 tmp_buf = NULL;
108
109 TEST(!encode_private_key(priv, &encoded_private_key,
110 &encoded_private_key_len), "encode_private_key");
111
112 memcpy(first_two_bytes, encoded_private_key, sizeof(first_two_bytes));
113 memset(encoded_private_key, 0xff, sizeof(first_two_bytes));
114 CBS_init(&cbs, encoded_private_key, encoded_private_key_len);
115 MALLOC(priv2, sizeof(struct MLKEM768_private_key));
116 /* Parsing should fail because the first coefficient is >= kPrime. */
117 TEST(MLKEM768_parse_private_key(priv2, &cbs), "Should not have parsed");
118
119 memcpy(encoded_private_key, first_two_bytes, sizeof(first_two_bytes));
120 CBS_init(&cbs, encoded_private_key, encoded_private_key_len);
121 TEST(!MLKEM768_parse_private_key(priv2, &cbs),
122 "MLKEM768_parse_private_key");
123 TEST(!encode_private_key(priv2, &tmp_buf, &tmp_buf_len),
124 "encode_private_key");
125 TEST(encoded_private_key_len != tmp_buf_len,
126 "encoded private key lengths differ");
127 TEST_DATAEQ(tmp_buf, encoded_private_key, encoded_private_key_len,
128 "encoded private keys");
129 free(tmp_buf);
130 tmp_buf = NULL;
131
132 MLKEM768_encap(ciphertext, shared_secret1, pub);
133 MLKEM768_decap(shared_secret2, ciphertext, MLKEM768_CIPHERTEXT_BYTES,
134 priv);
135 TEST_DATAEQ(shared_secret1, shared_secret2, MLKEM_SHARED_SECRET_BYTES,
136 "shared secrets with priv");
137 MLKEM768_decap(shared_secret2, ciphertext, MLKEM768_CIPHERTEXT_BYTES,
138 priv2);
139 TEST_DATAEQ(shared_secret1, shared_secret2, MLKEM_SHARED_SECRET_BYTES,
140 "shared secrets with priv2");
141
142 free(encoded_private_key);
143 free(pub);
144 free(pub2);
145 free(priv);
146 free(priv2);
147
148 exit(failure);
149}