diff options
Diffstat (limited to 'src/regress/lib/libcrypto/mlkem/mlkem_unittest.c')
-rw-r--r-- | src/regress/lib/libcrypto/mlkem/mlkem_unittest.c | 149 |
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 | |||
25 | static int | ||
26 | encode_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 | |||
40 | static int | ||
41 | encode_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 | |||
55 | int | ||
56 | main(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 | } | ||