summaryrefslogtreecommitdiff
path: root/src/regress/lib/libcrypto/mlkem/mlkem_iteration_tests.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/regress/lib/libcrypto/mlkem/mlkem_iteration_tests.c')
-rw-r--r--src/regress/lib/libcrypto/mlkem/mlkem_iteration_tests.c179
1 files changed, 77 insertions, 102 deletions
diff --git a/src/regress/lib/libcrypto/mlkem/mlkem_iteration_tests.c b/src/regress/lib/libcrypto/mlkem/mlkem_iteration_tests.c
index b93243023c..10c4b1f4e0 100644
--- a/src/regress/lib/libcrypto/mlkem/mlkem_iteration_tests.c
+++ b/src/regress/lib/libcrypto/mlkem/mlkem_iteration_tests.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mlkem_iteration_tests.c,v 1.5 2025/05/20 00:33:41 beck Exp $ */ 1/* $OpenBSD: mlkem_iteration_tests.c,v 1.6 2025/08/14 15:48:48 beck 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>
@@ -21,6 +21,7 @@
21#include <stdint.h> 21#include <stdint.h>
22#include <stdio.h> 22#include <stdio.h>
23#include <stdlib.h> 23#include <stdlib.h>
24#include <string.h>
24 25
25#include "mlkem.h" 26#include "mlkem.h"
26 27
@@ -63,46 +64,49 @@ const uint8_t kExpectedAdam1024[32] = {
63 0x04, 0xab, 0xdb, 0x94, 0x8b, 0x90, 0x8b, 0x75, 0xba, 0xd5 64 0x04, 0xab, 0xdb, 0x94, 0x8b, 0x90, 0x8b, 0x75, 0xba, 0xd5
64}; 65};
65 66
66struct iteration_ctx {
67 uint8_t *encoded_public_key;
68 size_t encoded_public_key_len;
69 uint8_t *ciphertext;
70 size_t ciphertext_len;
71 uint8_t *invalid_ciphertext;
72 size_t invalid_ciphertext_len;
73 void *priv;
74 void *pub;
75
76 mlkem_marshal_private_key_fn marshal_private_key;
77 mlkem_encap_external_entropy_fn encap_external_entropy;
78 mlkem_generate_key_external_entropy_fn generate_key_external_entropy;
79 mlkem_public_from_private_fn public_from_private;
80 mlkem_decap_fn decap;
81
82 const uint8_t *start;
83 size_t start_len;
84
85 const uint8_t *expected;
86 size_t expected_len;
87};
88
89static int 67static int
90MlkemIterativeTest(struct iteration_ctx *ctx) 68MlkemIterativeTest(int rank)
91{ 69{
92 uint8_t shared_secret[MLKEM_SHARED_SECRET_BYTES]; 70 const uint8_t *start, *expected;
71 size_t start_len;
93 uint8_t encap_entropy[MLKEM_ENCAP_ENTROPY]; 72 uint8_t encap_entropy[MLKEM_ENCAP_ENTROPY];
94 uint8_t seed[MLKEM_SEED_BYTES] = {0}; 73 uint8_t seed[MLKEM_SEED_LENGTH] = {0};
74 uint8_t *shared_secret = NULL;
95 sha3_ctx drng, results; 75 sha3_ctx drng, results;
96 uint8_t out[32]; 76 uint8_t out[32];
97 int i; 77 int i;
98 78
79 start = kExpectedSeedStart;
80 start_len = sizeof(kExpectedSeedStart);
81 switch(rank){
82 case RANK768:
83 expected = kExpectedAdam768;
84 break;
85 case RANK1024:
86 expected = kExpectedAdam1024;
87 break;
88 default:
89 errx(1, "invalid rank %d", rank);
90 }
91
99 shake128_init(&drng); 92 shake128_init(&drng);
100 shake128_init(&results); 93 shake128_init(&results);
101 94
102 shake_xof(&drng); 95 shake_xof(&drng);
103 for (i = 0; i < 10000; i++) { 96 for (i = 0; i < 10000; i++) {
104 uint8_t *encoded_private_key = NULL; 97 uint8_t *encoded_public_key = NULL, *ciphertext = NULL,
105 size_t encoded_private_key_len; 98 *encoded_private_key = NULL, *invalid_ciphertext = NULL;
99 size_t encoded_public_key_len, ciphertext_len,
100 encoded_private_key_len, invalid_ciphertext_len;
101 MLKEM_private_key *priv;
102 MLKEM_public_key *pub;
103 size_t s_len = 0;
104
105 /* allocate keys for this iteration */
106 if ((priv = MLKEM_private_key_new(rank)) == NULL)
107 errx(1, "malloc");
108 if ((pub = MLKEM_public_key_new(rank)) == NULL)
109 errx(1, "malloc");
106 110
107 /* 111 /*
108 * This should draw both d and z from DRNG concatenating in 112 * This should draw both d and z from DRNG concatenating in
@@ -110,120 +114,91 @@ MlkemIterativeTest(struct iteration_ctx *ctx)
110 */ 114 */
111 shake_out(&drng, seed, sizeof(seed)); 115 shake_out(&drng, seed, sizeof(seed));
112 if (i == 0) { 116 if (i == 0) {
113 if (compare_data(seed, ctx->start, ctx->start_len, 117 if (compare_data(seed, start, start_len,
114 "seed start") != 0) 118 "seed start") != 0)
115 errx(1, "compare_data"); 119 errx(1, "compare_data");
116 } 120 }
117 121
118 /* generate ek as encoded_public_key */ 122 /* generate ek as encoded_public_key */
119 if (!ctx->generate_key_external_entropy(ctx->encoded_public_key, 123 if (!MLKEM_generate_key_external_entropy(priv,
120 ctx->priv, seed)) { 124 &encoded_public_key, &encoded_public_key_len,
125 seed))
121 errx(1, "generate_key_external_entropy"); 126 errx(1, "generate_key_external_entropy");
122 } 127
123 ctx->public_from_private(ctx->pub, ctx->priv); 128 if (!MLKEM_public_from_private(priv, pub))
129 errx(1, "public_from_private");
124 130
125 /* hash in ek */ 131 /* hash in ek */
126 shake_update(&results, ctx->encoded_public_key, 132 shake_update(&results, encoded_public_key,
127 ctx->encoded_public_key_len); 133 encoded_public_key_len);
128 134
129 /* marshal priv to dk as encoded_private_key */ 135 /* marshal priv to dk as encoded_private_key */
130 if (!ctx->marshal_private_key(ctx->priv, &encoded_private_key, 136 if (!MLKEM_marshal_private_key(priv, &encoded_private_key,
131 &encoded_private_key_len)) 137 &encoded_private_key_len))
132 errx(1, "encode private key"); 138 errx(1, "marshal private key");
133 139
134 /* hash in dk */ 140 /* hash in dk */
135 shake_update(&results, encoded_private_key, 141 shake_update(&results, encoded_private_key,
136 encoded_private_key_len); 142 encoded_private_key_len);
137 143
138 free(encoded_private_key); 144 freezero(encoded_private_key, encoded_private_key_len);
139 145
140 /* draw m as encap entropy from DRNG */ 146 /* draw m as encap entropy from DRNG */
141 shake_out(&drng, encap_entropy, sizeof(encap_entropy)); 147 shake_out(&drng, encap_entropy, sizeof(encap_entropy));
142 148
143 /* generate ct as ciphertext, k as shared_secret */ 149 /* generate ct as ciphertext, k as shared_secret */
144 ctx->encap_external_entropy(ctx->ciphertext, shared_secret, 150 if (!MLKEM_encap_external_entropy(pub, encap_entropy,
145 ctx->pub, encap_entropy); 151 &ciphertext, &ciphertext_len, &shared_secret, &s_len))
152 errx(1, "encap_external_entropy");
146 153
147 /* hash in ct */ 154 /* hash in ct */
148 shake_update(&results, ctx->ciphertext, ctx->ciphertext_len); 155 shake_update(&results, ciphertext, ciphertext_len);
149 /* hash in k */ 156 /* hash in k */
150 shake_update(&results, shared_secret, sizeof(shared_secret)); 157 shake_update(&results, shared_secret, s_len);
158
159 freezero(shared_secret, s_len);
160 shared_secret = NULL;
161
162 invalid_ciphertext_len = ciphertext_len;
163 if ((invalid_ciphertext = calloc(1, invalid_ciphertext_len))
164 == NULL)
165 errx(1, "malloc");
151 166
152 /* draw ct as invalid_ciphertxt from DRNG */ 167 /* draw ct as invalid_ciphertxt from DRNG */
153 shake_out(&drng, ctx->invalid_ciphertext, 168 shake_out(&drng, invalid_ciphertext, invalid_ciphertext_len);
154 ctx->invalid_ciphertext_len);
155 169
156 /* generate k as shared secret from invalid ciphertext */ 170 /* generate k as shared secret from invalid ciphertext */
157 if (!ctx->decap(shared_secret, ctx->invalid_ciphertext, 171 if (!MLKEM_decap(priv, invalid_ciphertext,
158 ctx->invalid_ciphertext_len, ctx->priv)) 172 invalid_ciphertext_len, &shared_secret, &s_len))
159 errx(1, "decap failed"); 173 errx(1, "decap failed, iteration %d", i);
160 174
161 /* hash in k */ 175 /* hash in k */
162 shake_update(&results, shared_secret, sizeof(shared_secret)); 176 shake_update(&results, shared_secret, s_len);
177
178 freezero(shared_secret, s_len);
179 shared_secret = NULL;
180 freezero(invalid_ciphertext, invalid_ciphertext_len);
181 invalid_ciphertext = NULL;
182
183 /* free keys and intermediate products for this iteration */
184 MLKEM_private_key_free(priv);
185 MLKEM_public_key_free(pub);
186 freezero(encoded_public_key, encoded_public_key_len);
187 freezero(ciphertext, ciphertext_len);
163 } 188 }
164 shake_xof(&results); 189 shake_xof(&results);
165 shake_out(&results, out, sizeof(out)); 190 shake_out(&results, out, sizeof(out));
166 191
167 return compare_data(ctx->expected, out, sizeof(out), "final result hash"); 192 return compare_data(expected, out, sizeof(out), "final result hash");
168} 193}
169 194
170int 195int
171main(void) 196main(void)
172{ 197{
173 uint8_t encoded_public_key768[MLKEM768_PUBLIC_KEY_BYTES];
174 uint8_t ciphertext768[MLKEM768_CIPHERTEXT_BYTES];
175 uint8_t invalid_ciphertext768[MLKEM768_CIPHERTEXT_BYTES];
176 struct MLKEM768_private_key priv768;
177 struct MLKEM768_public_key pub768;
178 struct iteration_ctx iteration768 = {
179 .encoded_public_key = encoded_public_key768,
180 .encoded_public_key_len = sizeof(encoded_public_key768),
181 .ciphertext = ciphertext768,
182 .ciphertext_len = sizeof(ciphertext768),
183 .invalid_ciphertext = invalid_ciphertext768,
184 .invalid_ciphertext_len = sizeof(invalid_ciphertext768),
185 .priv = &priv768,
186 .pub = &pub768,
187 .encap_external_entropy = mlkem768_encap_external_entropy,
188 .marshal_private_key = mlkem768_marshal_private_key,
189 .generate_key_external_entropy =
190 mlkem768_generate_key_external_entropy,
191 .public_from_private = mlkem768_public_from_private,
192 .decap = mlkem768_decap,
193 .start = kExpectedSeedStart,
194 .start_len = sizeof(kExpectedSeedStart),
195 .expected = kExpectedAdam768,
196 .expected_len = sizeof(kExpectedAdam768),
197 };
198 uint8_t encoded_public_key1024[MLKEM1024_PUBLIC_KEY_BYTES];
199 uint8_t ciphertext1024[MLKEM1024_CIPHERTEXT_BYTES];
200 uint8_t invalid_ciphertext1024[MLKEM1024_CIPHERTEXT_BYTES];
201 struct MLKEM1024_private_key priv1024;
202 struct MLKEM1024_public_key pub1024;
203 struct iteration_ctx iteration1024 = {
204 .encoded_public_key = encoded_public_key1024,
205 .encoded_public_key_len = sizeof(encoded_public_key1024),
206 .ciphertext = ciphertext1024,
207 .ciphertext_len = sizeof(ciphertext1024),
208 .invalid_ciphertext = invalid_ciphertext1024,
209 .invalid_ciphertext_len = sizeof(invalid_ciphertext1024),
210 .priv = &priv1024,
211 .pub = &pub1024,
212 .encap_external_entropy = mlkem1024_encap_external_entropy,
213 .marshal_private_key = mlkem1024_marshal_private_key,
214 .generate_key_external_entropy =
215 mlkem1024_generate_key_external_entropy,
216 .public_from_private = mlkem1024_public_from_private,
217 .decap = mlkem1024_decap,
218 .start = kExpectedSeedStart,
219 .start_len = sizeof(kExpectedSeedStart),
220 .expected = kExpectedAdam1024,
221 .expected_len = sizeof(kExpectedAdam1024),
222 };
223 int failed = 0; 198 int failed = 0;
224 199
225 failed |= MlkemIterativeTest(&iteration768); 200 failed |= MlkemIterativeTest(RANK768);
226 failed |= MlkemIterativeTest(&iteration1024); 201 failed |= MlkemIterativeTest(RANK1024);
227 202
228 return failed; 203 return failed;
229} 204}