1 /*	$OpenBSD: mlkem_tests_util.c,v 1.5 2024/12/26 00:04:24 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 <err.h>
21 #include <stdint.h>
22 #include <stdio.h>
23 #include <string.h>
24 
25 #include "bytestring.h"
26 #include "mlkem.h"
27 
28 #include "mlkem_internal.h"
29 
30 #include "mlkem_tests_util.h"
31 
32 static void
hexdump(const uint8_t * buf,size_t len,const uint8_t * compare)33 hexdump(const uint8_t *buf, size_t len, const uint8_t *compare)
34 {
35 	const char *mark = "";
36 	size_t i;
37 
38 	for (i = 1; i <= len; i++) {
39 		if (compare != NULL)
40 			mark = (buf[i - 1] != compare[i - 1]) ? "*" : " ";
41 		fprintf(stderr, " %s0x%02hhx,%s", mark, buf[i - 1],
42 		    i % 8 && i != len ? "" : "\n");
43 	}
44 	fprintf(stderr, "\n");
45 }
46 
47 int
compare_data(const uint8_t * want,const uint8_t * got,size_t len,const char * msg)48 compare_data(const uint8_t *want, const uint8_t *got, size_t len, const char *msg)
49 {
50 	if (memcmp(want, got, len) == 0)
51 		return 0;
52 
53 	warnx("FAIL: %s differs", msg);
54 	fprintf(stderr, "want:\n");
55 	hexdump(want, len, got);
56 	fprintf(stderr, "got:\n");
57 	hexdump(got, len, want);
58 	fprintf(stderr, "\n");
59 
60 	return 1;
61 }
62 
63 int
mlkem768_encode_private_key(const void * private_key,uint8_t ** out_buf,size_t * out_len)64 mlkem768_encode_private_key(const void *private_key, uint8_t **out_buf,
65     size_t *out_len)
66 {
67 	CBB cbb;
68 	int ret = 0;
69 
70 	if (!CBB_init(&cbb, MLKEM768_PUBLIC_KEY_BYTES))
71 		goto err;
72 	if (!MLKEM768_marshal_private_key(&cbb, private_key))
73 		goto err;
74 	if (!CBB_finish(&cbb, out_buf, out_len))
75 		goto err;
76 
77 	ret = 1;
78 
79  err:
80 	CBB_cleanup(&cbb);
81 
82 	return ret;
83 }
84 
85 int
mlkem768_encode_public_key(const void * public_key,uint8_t ** out_buf,size_t * out_len)86 mlkem768_encode_public_key(const void *public_key, uint8_t **out_buf,
87     size_t *out_len)
88 {
89 	CBB cbb;
90 	int ret = 0;
91 
92 	if (!CBB_init(&cbb, MLKEM768_PUBLIC_KEY_BYTES))
93 		goto err;
94 	if (!MLKEM768_marshal_public_key(&cbb, public_key))
95 		goto err;
96 	if (!CBB_finish(&cbb, out_buf, out_len))
97 		goto err;
98 
99 	ret = 1;
100 
101  err:
102 	CBB_cleanup(&cbb);
103 
104 	return ret;
105 }
106 
107 int
mlkem1024_encode_private_key(const void * private_key,uint8_t ** out_buf,size_t * out_len)108 mlkem1024_encode_private_key(const void *private_key, uint8_t **out_buf,
109     size_t *out_len)
110 {
111 	CBB cbb;
112 	int ret = 0;
113 
114 	if (!CBB_init(&cbb, MLKEM1024_PUBLIC_KEY_BYTES))
115 		goto err;
116 	if (!MLKEM1024_marshal_private_key(&cbb, private_key))
117 		goto err;
118 	if (!CBB_finish(&cbb, out_buf, out_len))
119 		goto err;
120 
121 	ret = 1;
122 
123  err:
124 	CBB_cleanup(&cbb);
125 
126 	return ret;
127 }
128 
129 int
mlkem1024_encode_public_key(const void * public_key,uint8_t ** out_buf,size_t * out_len)130 mlkem1024_encode_public_key(const void *public_key, uint8_t **out_buf,
131     size_t *out_len)
132 {
133 	CBB cbb;
134 	int ret = 0;
135 
136 	if (!CBB_init(&cbb, MLKEM1024_PUBLIC_KEY_BYTES))
137 		goto err;
138 	if (!MLKEM1024_marshal_public_key(&cbb, public_key))
139 		goto err;
140 	if (!CBB_finish(&cbb, out_buf, out_len))
141 		goto err;
142 
143 	ret = 1;
144 
145  err:
146 	CBB_cleanup(&cbb);
147 
148 	return ret;
149 }
150 
151 int
mlkem768_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],const uint8_t * ciphertext,size_t ciphertext_len,const void * private_key)152 mlkem768_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],
153     const uint8_t *ciphertext, size_t ciphertext_len, const void *private_key)
154 {
155 	return MLKEM768_decap(out_shared_secret, ciphertext, ciphertext_len,
156 	    private_key);
157 }
158 
159 void
mlkem768_encap(uint8_t * out_ciphertext,uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],const void * public_key)160 mlkem768_encap(uint8_t *out_ciphertext,
161     uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],
162     const void *public_key)
163 {
164 	MLKEM768_encap(out_ciphertext, out_shared_secret, public_key);
165 }
166 
167 void
mlkem768_encap_external_entropy(uint8_t * out_ciphertext,uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],const void * public_key,const uint8_t entropy[MLKEM_ENCAP_ENTROPY])168 mlkem768_encap_external_entropy(uint8_t *out_ciphertext,
169     uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],
170     const void *public_key, const uint8_t entropy[MLKEM_ENCAP_ENTROPY])
171 {
172 	MLKEM768_encap_external_entropy(out_ciphertext, out_shared_secret,
173 	    public_key, entropy);
174 }
175 
176 void
mlkem768_generate_key(uint8_t * out_encoded_public_key,uint8_t optional_out_seed[MLKEM_SEED_BYTES],void * out_private_key)177 mlkem768_generate_key(uint8_t *out_encoded_public_key,
178     uint8_t optional_out_seed[MLKEM_SEED_BYTES], void *out_private_key)
179 {
180 	MLKEM768_generate_key(out_encoded_public_key, optional_out_seed,
181 	    out_private_key);
182 }
183 
184 void
mlkem768_generate_key_external_entropy(uint8_t * out_encoded_public_key,void * out_private_key,const uint8_t entropy[MLKEM_SEED_BYTES])185 mlkem768_generate_key_external_entropy(uint8_t *out_encoded_public_key,
186     void *out_private_key, const uint8_t entropy[MLKEM_SEED_BYTES])
187 {
188 	MLKEM768_generate_key_external_entropy(out_encoded_public_key,
189 	    out_private_key, entropy);
190 }
191 
192 int
mlkem768_parse_private_key(void * out_private_key,CBS * private_key_cbs)193 mlkem768_parse_private_key(void *out_private_key, CBS *private_key_cbs)
194 {
195 	return MLKEM768_parse_private_key(out_private_key, private_key_cbs);
196 }
197 
198 int
mlkem768_parse_public_key(void * out_public_key,CBS * public_key_cbs)199 mlkem768_parse_public_key(void *out_public_key, CBS *public_key_cbs)
200 {
201 	return MLKEM768_parse_public_key(out_public_key, public_key_cbs);
202 }
203 
204 void
mlkem768_public_from_private(void * out_public_key,const void * private_key)205 mlkem768_public_from_private(void *out_public_key, const void *private_key)
206 {
207 	MLKEM768_public_from_private(out_public_key, private_key);
208 }
209 
210 int
mlkem1024_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],const uint8_t * ciphertext,size_t ciphertext_len,const void * private_key)211 mlkem1024_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],
212     const uint8_t *ciphertext, size_t ciphertext_len, const void *private_key)
213 {
214 	return MLKEM1024_decap(out_shared_secret, ciphertext, ciphertext_len,
215 	    private_key);
216 }
217 
218 void
mlkem1024_encap(uint8_t * out_ciphertext,uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],const void * public_key)219 mlkem1024_encap(uint8_t *out_ciphertext,
220     uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],
221     const void *public_key)
222 {
223 	MLKEM1024_encap(out_ciphertext, out_shared_secret, public_key);
224 }
225 
226 void
mlkem1024_encap_external_entropy(uint8_t * out_ciphertext,uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],const void * public_key,const uint8_t entropy[MLKEM_ENCAP_ENTROPY])227 mlkem1024_encap_external_entropy(uint8_t *out_ciphertext,
228     uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],
229     const void *public_key, const uint8_t entropy[MLKEM_ENCAP_ENTROPY])
230 {
231 	MLKEM1024_encap_external_entropy(out_ciphertext, out_shared_secret,
232 	    public_key, entropy);
233 }
234 
235 void
mlkem1024_generate_key(uint8_t * out_encoded_public_key,uint8_t optional_out_seed[MLKEM_SEED_BYTES],void * out_private_key)236 mlkem1024_generate_key(uint8_t *out_encoded_public_key,
237     uint8_t optional_out_seed[MLKEM_SEED_BYTES], void *out_private_key)
238 {
239 	MLKEM1024_generate_key(out_encoded_public_key, optional_out_seed,
240 	    out_private_key);
241 }
242 
243 void
mlkem1024_generate_key_external_entropy(uint8_t * out_encoded_public_key,void * out_private_key,const uint8_t entropy[MLKEM_SEED_BYTES])244 mlkem1024_generate_key_external_entropy(uint8_t *out_encoded_public_key,
245     void *out_private_key, const uint8_t entropy[MLKEM_SEED_BYTES])
246 {
247 	MLKEM1024_generate_key_external_entropy(out_encoded_public_key,
248 	    out_private_key, entropy);
249 }
250 
251 int
mlkem1024_parse_private_key(void * out_private_key,CBS * private_key_cbs)252 mlkem1024_parse_private_key(void *out_private_key, CBS *private_key_cbs)
253 {
254 	return MLKEM1024_parse_private_key(out_private_key, private_key_cbs);
255 }
256 
257 void
mlkem1024_public_from_private(void * out_public_key,const void * private_key)258 mlkem1024_public_from_private(void *out_public_key, const void *private_key)
259 {
260 	MLKEM1024_public_from_private(out_public_key, private_key);
261 }
262 
263 int
mlkem1024_parse_public_key(void * out_public_key,CBS * public_key_cbs)264 mlkem1024_parse_public_key(void *out_public_key, CBS *public_key_cbs)
265 {
266 	return MLKEM1024_parse_public_key(out_public_key, public_key_cbs);
267 }
268