libcrux_mlkem_portable.c (302318B)
1 /* 2 * SPDX-FileCopyrightText: 2025 Cryspen Sarl <info@cryspen.com> 3 * 4 * SPDX-License-Identifier: MIT or Apache-2.0 5 * 6 * This code was generated with the following revisions: 7 * Charon: 667d2fc98984ff7f3df989c2367e6c1fa4a000e7 8 * Eurydice: 2381cbc416ef2ad0b561c362c500bc84f36b6785 9 * Karamel: 80f5435f2fc505973c469a4afcc8d875cddd0d8b 10 * F*: 71d8221589d4d438af3706d89cb653cf53e18aab 11 * Libcrux: 68dfed5a4a9e40277f62828471c029afed1ecdcc 12 */ 13 14 #include "internal/libcrux_mlkem_portable.h" 15 16 #include "internal/libcrux_core.h" 17 #include "libcrux_core.h" 18 #include "libcrux_sha3_portable.h" 19 20 inline void 21 libcrux_ml_kem_hash_functions_portable_G(Eurydice_slice input, 22 uint8_t ret[64U]) 23 { 24 uint8_t digest[64U] = { 0U }; 25 libcrux_sha3_portable_sha512( 26 Eurydice_array_to_slice((size_t)64U, digest, uint8_t), input); 27 memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); 28 } 29 30 inline void 31 libcrux_ml_kem_hash_functions_portable_H(Eurydice_slice input, 32 uint8_t ret[32U]) 33 { 34 uint8_t digest[32U] = { 0U }; 35 libcrux_sha3_portable_sha256( 36 Eurydice_array_to_slice((size_t)32U, digest, uint8_t), input); 37 memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); 38 } 39 40 static const int16_t ZETAS_TIMES_MONTGOMERY_R[128U] = { 41 (int16_t)-1044, (int16_t)-758, (int16_t)-359, (int16_t)-1517, 42 (int16_t)1493, (int16_t)1422, (int16_t)287, (int16_t)202, 43 (int16_t)-171, (int16_t)622, (int16_t)1577, (int16_t)182, 44 (int16_t)962, (int16_t)-1202, (int16_t)-1474, (int16_t)1468, 45 (int16_t)573, (int16_t)-1325, (int16_t)264, (int16_t)383, 46 (int16_t)-829, (int16_t)1458, (int16_t)-1602, (int16_t)-130, 47 (int16_t)-681, (int16_t)1017, (int16_t)732, (int16_t)608, 48 (int16_t)-1542, (int16_t)411, (int16_t)-205, (int16_t)-1571, 49 (int16_t)1223, (int16_t)652, (int16_t)-552, (int16_t)1015, 50 (int16_t)-1293, (int16_t)1491, (int16_t)-282, (int16_t)-1544, 51 (int16_t)516, (int16_t)-8, (int16_t)-320, (int16_t)-666, 52 (int16_t)-1618, (int16_t)-1162, (int16_t)126, (int16_t)1469, 53 (int16_t)-853, (int16_t)-90, (int16_t)-271, (int16_t)830, 54 (int16_t)107, (int16_t)-1421, (int16_t)-247, (int16_t)-951, 55 (int16_t)-398, (int16_t)961, (int16_t)-1508, (int16_t)-725, 56 (int16_t)448, (int16_t)-1065, (int16_t)677, (int16_t)-1275, 57 (int16_t)-1103, (int16_t)430, (int16_t)555, (int16_t)843, 58 (int16_t)-1251, (int16_t)871, (int16_t)1550, (int16_t)105, 59 (int16_t)422, (int16_t)587, (int16_t)177, (int16_t)-235, 60 (int16_t)-291, (int16_t)-460, (int16_t)1574, (int16_t)1653, 61 (int16_t)-246, (int16_t)778, (int16_t)1159, (int16_t)-147, 62 (int16_t)-777, (int16_t)1483, (int16_t)-602, (int16_t)1119, 63 (int16_t)-1590, (int16_t)644, (int16_t)-872, (int16_t)349, 64 (int16_t)418, (int16_t)329, (int16_t)-156, (int16_t)-75, 65 (int16_t)817, (int16_t)1097, (int16_t)603, (int16_t)610, 66 (int16_t)1322, (int16_t)-1285, (int16_t)-1465, (int16_t)384, 67 (int16_t)-1215, (int16_t)-136, (int16_t)1218, (int16_t)-1335, 68 (int16_t)-874, (int16_t)220, (int16_t)-1187, (int16_t)-1659, 69 (int16_t)-1185, (int16_t)-1530, (int16_t)-1278, (int16_t)794, 70 (int16_t)-1510, (int16_t)-854, (int16_t)-870, (int16_t)478, 71 (int16_t)-108, (int16_t)-308, (int16_t)996, (int16_t)991, 72 (int16_t)958, (int16_t)-1460, (int16_t)1522, (int16_t)1628 73 }; 74 75 static KRML_MUSTINLINE int16_t 76 zeta(size_t i) 77 { 78 return ZETAS_TIMES_MONTGOMERY_R[i]; 79 } 80 81 #define VECTORS_IN_RING_ELEMENT ((size_t)16U) 82 83 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 84 libcrux_ml_kem_vector_portable_vector_type_zero(void) 85 { 86 libcrux_ml_kem_vector_portable_vector_type_PortableVector lit; 87 int16_t ret[16U]; 88 int16_t buf[16U] = { 0U }; 89 libcrux_secrets_int_public_integers_classify_27_46(buf, ret); 90 memcpy(lit.elements, ret, (size_t)16U * sizeof(int16_t)); 91 return lit; 92 } 93 94 /** 95 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 96 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 97 */ 98 libcrux_ml_kem_vector_portable_vector_type_PortableVector 99 libcrux_ml_kem_vector_portable_ZERO_b8(void) 100 { 101 return libcrux_ml_kem_vector_portable_vector_type_zero(); 102 } 103 104 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 105 libcrux_ml_kem_vector_portable_vector_type_from_i16_array( 106 Eurydice_slice array) 107 { 108 libcrux_ml_kem_vector_portable_vector_type_PortableVector lit; 109 int16_t ret[16U]; 110 core_result_Result_0a dst; 111 Eurydice_slice_to_array2( 112 &dst, Eurydice_slice_subslice3(array, (size_t)0U, (size_t)16U, int16_t *), 113 Eurydice_slice, int16_t[16U], core_array_TryFromSliceError); 114 core_result_unwrap_26_00(dst, ret); 115 memcpy(lit.elements, ret, (size_t)16U * sizeof(int16_t)); 116 return lit; 117 } 118 119 /** 120 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 121 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 122 */ 123 libcrux_ml_kem_vector_portable_vector_type_PortableVector 124 libcrux_ml_kem_vector_portable_from_i16_array_b8(Eurydice_slice array) 125 { 126 return libcrux_ml_kem_vector_portable_vector_type_from_i16_array( 127 libcrux_secrets_int_classify_public_classify_ref_9b_39(array)); 128 } 129 130 KRML_MUSTINLINE void 131 libcrux_ml_kem_vector_portable_vector_type_to_i16_array( 132 libcrux_ml_kem_vector_portable_vector_type_PortableVector x, 133 int16_t ret[16U]) 134 { 135 memcpy(ret, x.elements, (size_t)16U * sizeof(int16_t)); 136 } 137 138 /** 139 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 140 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 141 */ 142 void 143 libcrux_ml_kem_vector_portable_to_i16_array_b8( 144 libcrux_ml_kem_vector_portable_vector_type_PortableVector x, 145 int16_t ret[16U]) 146 { 147 int16_t ret0[16U]; 148 libcrux_ml_kem_vector_portable_vector_type_to_i16_array(x, ret0); 149 libcrux_secrets_int_public_integers_declassify_d8_46(ret0, ret); 150 } 151 152 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 153 libcrux_ml_kem_vector_portable_vector_type_from_bytes(Eurydice_slice array) 154 { 155 int16_t elements[16U]; 156 KRML_MAYBE_FOR16(i, (size_t)0U, (size_t)16U, (size_t)1U, 157 elements[i] = libcrux_secrets_int_I16((int16_t)0);); 158 for (size_t i = (size_t)0U; 159 i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { 160 size_t i0 = i; 161 elements[i0] = 162 libcrux_secrets_int_as_i16_59( 163 Eurydice_slice_index(array, (size_t)2U * i0, uint8_t, uint8_t *)) 164 << 8U | 165 libcrux_secrets_int_as_i16_59(Eurydice_slice_index( 166 array, (size_t)2U * i0 + (size_t)1U, uint8_t, uint8_t *)); 167 } 168 /* Passing arrays by value in Rust generates a copy in C */ 169 int16_t copy_of_elements[16U]; 170 memcpy(copy_of_elements, elements, (size_t)16U * sizeof(int16_t)); 171 libcrux_ml_kem_vector_portable_vector_type_PortableVector lit; 172 memcpy(lit.elements, copy_of_elements, (size_t)16U * sizeof(int16_t)); 173 return lit; 174 } 175 176 /** 177 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 178 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 179 */ 180 libcrux_ml_kem_vector_portable_vector_type_PortableVector 181 libcrux_ml_kem_vector_portable_from_bytes_b8(Eurydice_slice array) 182 { 183 return libcrux_ml_kem_vector_portable_vector_type_from_bytes( 184 libcrux_secrets_int_classify_public_classify_ref_9b_90(array)); 185 } 186 187 KRML_MUSTINLINE void 188 libcrux_ml_kem_vector_portable_vector_type_to_bytes( 189 libcrux_ml_kem_vector_portable_vector_type_PortableVector x, 190 Eurydice_slice bytes) 191 { 192 for (size_t i = (size_t)0U; 193 i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { 194 size_t i0 = i; 195 Eurydice_slice_index(bytes, (size_t)2U * i0, uint8_t, uint8_t *) = 196 libcrux_secrets_int_as_u8_f5(x.elements[i0] >> 8U); 197 Eurydice_slice_index(bytes, (size_t)2U * i0 + (size_t)1U, uint8_t, 198 uint8_t *) = 199 libcrux_secrets_int_as_u8_f5(x.elements[i0]); 200 } 201 } 202 203 /** 204 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 205 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 206 */ 207 void 208 libcrux_ml_kem_vector_portable_to_bytes_b8( 209 libcrux_ml_kem_vector_portable_vector_type_PortableVector x, 210 Eurydice_slice bytes) 211 { 212 libcrux_ml_kem_vector_portable_vector_type_to_bytes( 213 x, libcrux_secrets_int_public_integers_classify_mut_slice_ba(bytes)); 214 } 215 216 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 217 libcrux_ml_kem_vector_portable_arithmetic_add( 218 libcrux_ml_kem_vector_portable_vector_type_PortableVector lhs, 219 libcrux_ml_kem_vector_portable_vector_type_PortableVector *rhs) 220 { 221 for (size_t i = (size_t)0U; 222 i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { 223 size_t i0 = i; 224 size_t uu____0 = i0; 225 lhs.elements[uu____0] = lhs.elements[uu____0] + rhs->elements[i0]; 226 } 227 return lhs; 228 } 229 230 /** 231 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 232 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 233 */ 234 libcrux_ml_kem_vector_portable_vector_type_PortableVector 235 libcrux_ml_kem_vector_portable_add_b8( 236 libcrux_ml_kem_vector_portable_vector_type_PortableVector lhs, 237 libcrux_ml_kem_vector_portable_vector_type_PortableVector *rhs) 238 { 239 return libcrux_ml_kem_vector_portable_arithmetic_add(lhs, rhs); 240 } 241 242 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 243 libcrux_ml_kem_vector_portable_arithmetic_sub( 244 libcrux_ml_kem_vector_portable_vector_type_PortableVector lhs, 245 libcrux_ml_kem_vector_portable_vector_type_PortableVector *rhs) 246 { 247 for (size_t i = (size_t)0U; 248 i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { 249 size_t i0 = i; 250 size_t uu____0 = i0; 251 lhs.elements[uu____0] = lhs.elements[uu____0] - rhs->elements[i0]; 252 } 253 return lhs; 254 } 255 256 /** 257 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 258 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 259 */ 260 libcrux_ml_kem_vector_portable_vector_type_PortableVector 261 libcrux_ml_kem_vector_portable_sub_b8( 262 libcrux_ml_kem_vector_portable_vector_type_PortableVector lhs, 263 libcrux_ml_kem_vector_portable_vector_type_PortableVector *rhs) 264 { 265 return libcrux_ml_kem_vector_portable_arithmetic_sub(lhs, rhs); 266 } 267 268 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 269 libcrux_ml_kem_vector_portable_arithmetic_multiply_by_constant( 270 libcrux_ml_kem_vector_portable_vector_type_PortableVector vec, int16_t c) 271 { 272 for (size_t i = (size_t)0U; 273 i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { 274 size_t i0 = i; 275 size_t uu____0 = i0; 276 vec.elements[uu____0] = vec.elements[uu____0] * c; 277 } 278 return vec; 279 } 280 281 /** 282 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 283 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 284 */ 285 libcrux_ml_kem_vector_portable_vector_type_PortableVector 286 libcrux_ml_kem_vector_portable_multiply_by_constant_b8( 287 libcrux_ml_kem_vector_portable_vector_type_PortableVector vec, int16_t c) 288 { 289 return libcrux_ml_kem_vector_portable_arithmetic_multiply_by_constant(vec, c); 290 } 291 292 /** 293 Note: This function is not secret independent 294 Only use with public values. 295 */ 296 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 297 libcrux_ml_kem_vector_portable_arithmetic_cond_subtract_3329( 298 libcrux_ml_kem_vector_portable_vector_type_PortableVector vec) 299 { 300 for (size_t i = (size_t)0U; 301 i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { 302 size_t i0 = i; 303 if (libcrux_secrets_int_public_integers_declassify_d8_39( 304 vec.elements[i0]) >= (int16_t)3329) { 305 size_t uu____0 = i0; 306 vec.elements[uu____0] = vec.elements[uu____0] - (int16_t)3329; 307 } 308 } 309 return vec; 310 } 311 312 /** 313 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 314 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 315 */ 316 libcrux_ml_kem_vector_portable_vector_type_PortableVector 317 libcrux_ml_kem_vector_portable_cond_subtract_3329_b8( 318 libcrux_ml_kem_vector_portable_vector_type_PortableVector v) 319 { 320 return libcrux_ml_kem_vector_portable_arithmetic_cond_subtract_3329(v); 321 } 322 323 /** 324 Signed Barrett Reduction 325 326 Given an input `value`, `barrett_reduce` outputs a representative `result` 327 such that: 328 329 - result ≡ value (mod FIELD_MODULUS) 330 - the absolute value of `result` is bound as follows: 331 332 `|result| ≤ FIELD_MODULUS / 2 · (|value|/BARRETT_R + 1) 333 334 Note: The input bound is 28296 to prevent overflow in the multiplication of 335 quotient by FIELD_MODULUS 336 337 */ 338 int16_t 339 libcrux_ml_kem_vector_portable_arithmetic_barrett_reduce_element( 340 int16_t value) 341 { 342 int32_t t = libcrux_secrets_int_as_i32_f5(value) * 343 LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_BARRETT_MULTIPLIER + 344 (LIBCRUX_ML_KEM_VECTOR_TRAITS_BARRETT_R >> 1U); 345 int16_t quotient = libcrux_secrets_int_as_i16_36( 346 t >> (uint32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_BARRETT_SHIFT); 347 return value - quotient * LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; 348 } 349 350 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 351 libcrux_ml_kem_vector_portable_arithmetic_barrett_reduce( 352 libcrux_ml_kem_vector_portable_vector_type_PortableVector vec) 353 { 354 for (size_t i = (size_t)0U; 355 i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { 356 size_t i0 = i; 357 int16_t vi = 358 libcrux_ml_kem_vector_portable_arithmetic_barrett_reduce_element( 359 vec.elements[i0]); 360 vec.elements[i0] = vi; 361 } 362 return vec; 363 } 364 365 /** 366 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 367 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 368 */ 369 libcrux_ml_kem_vector_portable_vector_type_PortableVector 370 libcrux_ml_kem_vector_portable_barrett_reduce_b8( 371 libcrux_ml_kem_vector_portable_vector_type_PortableVector vector) 372 { 373 return libcrux_ml_kem_vector_portable_arithmetic_barrett_reduce(vector); 374 } 375 376 /** 377 Signed Montgomery Reduction 378 379 Given an input `value`, `montgomery_reduce` outputs a representative `o` 380 such that: 381 382 - o ≡ value · MONTGOMERY_R^(-1) (mod FIELD_MODULUS) 383 - the absolute value of `o` is bound as follows: 384 385 `|result| ≤ ceil(|value| / MONTGOMERY_R) + 1665 386 387 In particular, if `|value| ≤ FIELD_MODULUS-1 * FIELD_MODULUS-1`, then `|o| <= 388 FIELD_MODULUS-1`. And, if `|value| ≤ pow2 16 * FIELD_MODULUS-1`, then `|o| <= 389 FIELD_MODULUS + 1664 390 391 */ 392 int16_t 393 libcrux_ml_kem_vector_portable_arithmetic_montgomery_reduce_element( 394 int32_t value) 395 { 396 int32_t k = 397 libcrux_secrets_int_as_i32_f5(libcrux_secrets_int_as_i16_36(value)) * 398 libcrux_secrets_int_as_i32_b8( 399 libcrux_secrets_int_public_integers_classify_27_df( 400 LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R)); 401 int32_t k_times_modulus = 402 libcrux_secrets_int_as_i32_f5(libcrux_secrets_int_as_i16_36(k)) * 403 libcrux_secrets_int_as_i32_f5( 404 libcrux_secrets_int_public_integers_classify_27_39( 405 LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); 406 int16_t c = libcrux_secrets_int_as_i16_36( 407 k_times_modulus >> 408 (uint32_t)LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_MONTGOMERY_SHIFT); 409 int16_t value_high = libcrux_secrets_int_as_i16_36( 410 value >> 411 (uint32_t)LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_MONTGOMERY_SHIFT); 412 return value_high - c; 413 } 414 415 /** 416 If `fe` is some field element 'x' of the Kyber field and `fer` is congruent to 417 `y · MONTGOMERY_R`, this procedure outputs a value that is congruent to 418 `x · y`, as follows: 419 420 `fe · fer ≡ x · y · MONTGOMERY_R (mod FIELD_MODULUS)` 421 422 `montgomery_reduce` takes the value `x · y · MONTGOMERY_R` and outputs a 423 representative `x · y · MONTGOMERY_R * MONTGOMERY_R^{-1} ≡ x · y (mod 424 FIELD_MODULUS)`. 425 */ 426 KRML_MUSTINLINE int16_t 427 libcrux_ml_kem_vector_portable_arithmetic_montgomery_multiply_fe_by_fer( 428 int16_t fe, int16_t fer) 429 { 430 int32_t product = 431 libcrux_secrets_int_as_i32_f5(fe) * libcrux_secrets_int_as_i32_f5(fer); 432 return libcrux_ml_kem_vector_portable_arithmetic_montgomery_reduce_element( 433 product); 434 } 435 436 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 437 libcrux_ml_kem_vector_portable_arithmetic_montgomery_multiply_by_constant( 438 libcrux_ml_kem_vector_portable_vector_type_PortableVector vec, int16_t c) 439 { 440 for (size_t i = (size_t)0U; 441 i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { 442 size_t i0 = i; 443 vec.elements[i0] = 444 libcrux_ml_kem_vector_portable_arithmetic_montgomery_multiply_fe_by_fer( 445 vec.elements[i0], c); 446 } 447 return vec; 448 } 449 450 /** 451 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 452 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 453 */ 454 libcrux_ml_kem_vector_portable_vector_type_PortableVector 455 libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_b8( 456 libcrux_ml_kem_vector_portable_vector_type_PortableVector vector, 457 int16_t constant) 458 { 459 return libcrux_ml_kem_vector_portable_arithmetic_montgomery_multiply_by_constant( 460 vector, libcrux_secrets_int_public_integers_classify_27_39(constant)); 461 } 462 463 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 464 libcrux_ml_kem_vector_portable_arithmetic_bitwise_and_with_constant( 465 libcrux_ml_kem_vector_portable_vector_type_PortableVector vec, int16_t c) 466 { 467 for (size_t i = (size_t)0U; 468 i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { 469 size_t i0 = i; 470 size_t uu____0 = i0; 471 vec.elements[uu____0] = vec.elements[uu____0] & c; 472 } 473 return vec; 474 } 475 476 /** 477 A monomorphic instance of libcrux_ml_kem.vector.portable.arithmetic.shift_right 478 with const generics 479 - SHIFT_BY= 15 480 */ 481 static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 482 shift_right_ef(libcrux_ml_kem_vector_portable_vector_type_PortableVector vec) 483 { 484 for (size_t i = (size_t)0U; 485 i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { 486 size_t i0 = i; 487 vec.elements[i0] = vec.elements[i0] >> (uint32_t)(int32_t)15; 488 } 489 return vec; 490 } 491 492 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 493 libcrux_ml_kem_vector_portable_arithmetic_to_unsigned_representative( 494 libcrux_ml_kem_vector_portable_vector_type_PortableVector a) 495 { 496 libcrux_ml_kem_vector_portable_vector_type_PortableVector t = 497 shift_right_ef(a); 498 libcrux_ml_kem_vector_portable_vector_type_PortableVector fm = 499 libcrux_ml_kem_vector_portable_arithmetic_bitwise_and_with_constant( 500 t, LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); 501 return libcrux_ml_kem_vector_portable_arithmetic_add(a, &fm); 502 } 503 504 /** 505 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 506 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 507 */ 508 libcrux_ml_kem_vector_portable_vector_type_PortableVector 509 libcrux_ml_kem_vector_portable_to_unsigned_representative_b8( 510 libcrux_ml_kem_vector_portable_vector_type_PortableVector a) 511 { 512 return libcrux_ml_kem_vector_portable_arithmetic_to_unsigned_representative( 513 a); 514 } 515 516 /** 517 The `compress_*` functions implement the `Compress` function specified in the 518 NIST FIPS 203 standard (Page 18, Expression 4.5), which is defined as: 519 520 ```plaintext 521 Compress_d: ℤq -> ℤ_{2ᵈ} 522 Compress_d(x) = ⌈(2ᵈ/q)·x⌋ 523 ``` 524 525 Since `⌈x⌋ = ⌊x + 1/2⌋` we have: 526 527 ```plaintext 528 Compress_d(x) = ⌊(2ᵈ/q)·x + 1/2⌋ 529 = ⌊(2^{d+1}·x + q) / 2q⌋ 530 ``` 531 532 For further information about the function implementations, consult the 533 `implementation_notes.pdf` document in this directory. 534 535 The NIST FIPS 203 standard can be found at 536 <https://csrc.nist.gov/pubs/fips/203/ipd>. 537 */ 538 uint8_t 539 libcrux_ml_kem_vector_portable_compress_compress_message_coefficient( 540 uint16_t fe) 541 { 542 int16_t shifted = 543 libcrux_secrets_int_public_integers_classify_27_39((int16_t)1664) - 544 libcrux_secrets_int_as_i16_ca(fe); 545 int16_t mask = shifted >> 15U; 546 int16_t shifted_to_positive = mask ^ shifted; 547 int16_t shifted_positive_in_range = shifted_to_positive - (int16_t)832; 548 int16_t r0 = shifted_positive_in_range >> 15U; 549 int16_t r1 = r0 & (int16_t)1; 550 return libcrux_secrets_int_as_u8_f5(r1); 551 } 552 553 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 554 libcrux_ml_kem_vector_portable_compress_compress_1( 555 libcrux_ml_kem_vector_portable_vector_type_PortableVector a) 556 { 557 for (size_t i = (size_t)0U; 558 i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { 559 size_t i0 = i; 560 a.elements[i0] = libcrux_secrets_int_as_i16_59( 561 libcrux_ml_kem_vector_portable_compress_compress_message_coefficient( 562 libcrux_secrets_int_as_u16_f5(a.elements[i0]))); 563 } 564 return a; 565 } 566 567 /** 568 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 569 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 570 */ 571 libcrux_ml_kem_vector_portable_vector_type_PortableVector 572 libcrux_ml_kem_vector_portable_compress_1_b8( 573 libcrux_ml_kem_vector_portable_vector_type_PortableVector a) 574 { 575 return libcrux_ml_kem_vector_portable_compress_compress_1(a); 576 } 577 578 KRML_MUSTINLINE uint32_t 579 libcrux_ml_kem_vector_portable_arithmetic_get_n_least_significant_bits( 580 uint8_t n, uint32_t value) 581 { 582 return value & ((1U << (uint32_t)n) - 1U); 583 } 584 585 int16_t 586 libcrux_ml_kem_vector_portable_compress_compress_ciphertext_coefficient( 587 uint8_t coefficient_bits, uint16_t fe) 588 { 589 uint64_t compressed = libcrux_secrets_int_as_u64_ca(fe) 590 << (uint32_t)coefficient_bits; 591 compressed = compressed + 1664ULL; 592 compressed = compressed * 10321340ULL; 593 compressed = compressed >> 35U; 594 return libcrux_secrets_int_as_i16_b8( 595 libcrux_ml_kem_vector_portable_arithmetic_get_n_least_significant_bits( 596 coefficient_bits, libcrux_secrets_int_as_u32_a3(compressed))); 597 } 598 599 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 600 libcrux_ml_kem_vector_portable_compress_decompress_1( 601 libcrux_ml_kem_vector_portable_vector_type_PortableVector a) 602 { 603 libcrux_ml_kem_vector_portable_vector_type_PortableVector z = 604 libcrux_ml_kem_vector_portable_vector_type_zero(); 605 libcrux_ml_kem_vector_portable_vector_type_PortableVector s = 606 libcrux_ml_kem_vector_portable_arithmetic_sub(z, &a); 607 libcrux_ml_kem_vector_portable_vector_type_PortableVector res = 608 libcrux_ml_kem_vector_portable_arithmetic_bitwise_and_with_constant( 609 s, (int16_t)1665); 610 return res; 611 } 612 613 /** 614 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 615 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 616 */ 617 libcrux_ml_kem_vector_portable_vector_type_PortableVector 618 libcrux_ml_kem_vector_portable_decompress_1_b8( 619 libcrux_ml_kem_vector_portable_vector_type_PortableVector a) 620 { 621 return libcrux_ml_kem_vector_portable_compress_decompress_1(a); 622 } 623 624 KRML_MUSTINLINE void 625 libcrux_ml_kem_vector_portable_ntt_ntt_step( 626 libcrux_ml_kem_vector_portable_vector_type_PortableVector *vec, 627 int16_t zeta, size_t i, size_t j) 628 { 629 int16_t t = 630 libcrux_ml_kem_vector_portable_arithmetic_montgomery_multiply_fe_by_fer( 631 vec->elements[j], 632 libcrux_secrets_int_public_integers_classify_27_39(zeta)); 633 int16_t a_minus_t = vec->elements[i] - t; 634 int16_t a_plus_t = vec->elements[i] + t; 635 vec->elements[j] = a_minus_t; 636 vec->elements[i] = a_plus_t; 637 } 638 639 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 640 libcrux_ml_kem_vector_portable_ntt_ntt_layer_1_step( 641 libcrux_ml_kem_vector_portable_vector_type_PortableVector vec, 642 int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3) 643 { 644 libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta0, (size_t)0U, 645 (size_t)2U); 646 libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta0, (size_t)1U, 647 (size_t)3U); 648 libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta1, (size_t)4U, 649 (size_t)6U); 650 libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta1, (size_t)5U, 651 (size_t)7U); 652 libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta2, (size_t)8U, 653 (size_t)10U); 654 libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta2, (size_t)9U, 655 (size_t)11U); 656 libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta3, (size_t)12U, 657 (size_t)14U); 658 libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta3, (size_t)13U, 659 (size_t)15U); 660 return vec; 661 } 662 663 /** 664 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 665 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 666 */ 667 libcrux_ml_kem_vector_portable_vector_type_PortableVector 668 libcrux_ml_kem_vector_portable_ntt_layer_1_step_b8( 669 libcrux_ml_kem_vector_portable_vector_type_PortableVector a, int16_t zeta0, 670 int16_t zeta1, int16_t zeta2, int16_t zeta3) 671 { 672 return libcrux_ml_kem_vector_portable_ntt_ntt_layer_1_step(a, zeta0, zeta1, 673 zeta2, zeta3); 674 } 675 676 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 677 libcrux_ml_kem_vector_portable_ntt_ntt_layer_2_step( 678 libcrux_ml_kem_vector_portable_vector_type_PortableVector vec, 679 int16_t zeta0, int16_t zeta1) 680 { 681 libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta0, (size_t)0U, 682 (size_t)4U); 683 libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta0, (size_t)1U, 684 (size_t)5U); 685 libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta0, (size_t)2U, 686 (size_t)6U); 687 libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta0, (size_t)3U, 688 (size_t)7U); 689 libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta1, (size_t)8U, 690 (size_t)12U); 691 libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta1, (size_t)9U, 692 (size_t)13U); 693 libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta1, (size_t)10U, 694 (size_t)14U); 695 libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta1, (size_t)11U, 696 (size_t)15U); 697 return vec; 698 } 699 700 /** 701 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 702 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 703 */ 704 libcrux_ml_kem_vector_portable_vector_type_PortableVector 705 libcrux_ml_kem_vector_portable_ntt_layer_2_step_b8( 706 libcrux_ml_kem_vector_portable_vector_type_PortableVector a, int16_t zeta0, 707 int16_t zeta1) 708 { 709 return libcrux_ml_kem_vector_portable_ntt_ntt_layer_2_step(a, zeta0, zeta1); 710 } 711 712 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 713 libcrux_ml_kem_vector_portable_ntt_ntt_layer_3_step( 714 libcrux_ml_kem_vector_portable_vector_type_PortableVector vec, 715 int16_t zeta) 716 { 717 libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta, (size_t)0U, 718 (size_t)8U); 719 libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta, (size_t)1U, 720 (size_t)9U); 721 libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta, (size_t)2U, 722 (size_t)10U); 723 libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta, (size_t)3U, 724 (size_t)11U); 725 libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta, (size_t)4U, 726 (size_t)12U); 727 libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta, (size_t)5U, 728 (size_t)13U); 729 libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta, (size_t)6U, 730 (size_t)14U); 731 libcrux_ml_kem_vector_portable_ntt_ntt_step(&vec, zeta, (size_t)7U, 732 (size_t)15U); 733 return vec; 734 } 735 736 /** 737 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 738 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 739 */ 740 libcrux_ml_kem_vector_portable_vector_type_PortableVector 741 libcrux_ml_kem_vector_portable_ntt_layer_3_step_b8( 742 libcrux_ml_kem_vector_portable_vector_type_PortableVector a, int16_t zeta) 743 { 744 return libcrux_ml_kem_vector_portable_ntt_ntt_layer_3_step(a, zeta); 745 } 746 747 KRML_MUSTINLINE void 748 libcrux_ml_kem_vector_portable_ntt_inv_ntt_step( 749 libcrux_ml_kem_vector_portable_vector_type_PortableVector *vec, 750 int16_t zeta, size_t i, size_t j) 751 { 752 int16_t a_minus_b = vec->elements[j] - vec->elements[i]; 753 int16_t a_plus_b = vec->elements[j] + vec->elements[i]; 754 int16_t o0 = libcrux_ml_kem_vector_portable_arithmetic_barrett_reduce_element( 755 a_plus_b); 756 int16_t o1 = 757 libcrux_ml_kem_vector_portable_arithmetic_montgomery_multiply_fe_by_fer( 758 a_minus_b, libcrux_secrets_int_public_integers_classify_27_39(zeta)); 759 vec->elements[i] = o0; 760 vec->elements[j] = o1; 761 } 762 763 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 764 libcrux_ml_kem_vector_portable_ntt_inv_ntt_layer_1_step( 765 libcrux_ml_kem_vector_portable_vector_type_PortableVector vec, 766 int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3) 767 { 768 libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta0, (size_t)0U, 769 (size_t)2U); 770 libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta0, (size_t)1U, 771 (size_t)3U); 772 libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta1, (size_t)4U, 773 (size_t)6U); 774 libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta1, (size_t)5U, 775 (size_t)7U); 776 libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta2, (size_t)8U, 777 (size_t)10U); 778 libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta2, (size_t)9U, 779 (size_t)11U); 780 libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta3, (size_t)12U, 781 (size_t)14U); 782 libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta3, (size_t)13U, 783 (size_t)15U); 784 return vec; 785 } 786 787 /** 788 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 789 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 790 */ 791 libcrux_ml_kem_vector_portable_vector_type_PortableVector 792 libcrux_ml_kem_vector_portable_inv_ntt_layer_1_step_b8( 793 libcrux_ml_kem_vector_portable_vector_type_PortableVector a, int16_t zeta0, 794 int16_t zeta1, int16_t zeta2, int16_t zeta3) 795 { 796 return libcrux_ml_kem_vector_portable_ntt_inv_ntt_layer_1_step( 797 a, zeta0, zeta1, zeta2, zeta3); 798 } 799 800 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 801 libcrux_ml_kem_vector_portable_ntt_inv_ntt_layer_2_step( 802 libcrux_ml_kem_vector_portable_vector_type_PortableVector vec, 803 int16_t zeta0, int16_t zeta1) 804 { 805 libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta0, (size_t)0U, 806 (size_t)4U); 807 libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta0, (size_t)1U, 808 (size_t)5U); 809 libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta0, (size_t)2U, 810 (size_t)6U); 811 libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta0, (size_t)3U, 812 (size_t)7U); 813 libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta1, (size_t)8U, 814 (size_t)12U); 815 libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta1, (size_t)9U, 816 (size_t)13U); 817 libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta1, (size_t)10U, 818 (size_t)14U); 819 libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta1, (size_t)11U, 820 (size_t)15U); 821 return vec; 822 } 823 824 /** 825 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 826 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 827 */ 828 libcrux_ml_kem_vector_portable_vector_type_PortableVector 829 libcrux_ml_kem_vector_portable_inv_ntt_layer_2_step_b8( 830 libcrux_ml_kem_vector_portable_vector_type_PortableVector a, int16_t zeta0, 831 int16_t zeta1) 832 { 833 return libcrux_ml_kem_vector_portable_ntt_inv_ntt_layer_2_step(a, zeta0, 834 zeta1); 835 } 836 837 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 838 libcrux_ml_kem_vector_portable_ntt_inv_ntt_layer_3_step( 839 libcrux_ml_kem_vector_portable_vector_type_PortableVector vec, 840 int16_t zeta) 841 { 842 libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta, (size_t)0U, 843 (size_t)8U); 844 libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta, (size_t)1U, 845 (size_t)9U); 846 libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta, (size_t)2U, 847 (size_t)10U); 848 libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta, (size_t)3U, 849 (size_t)11U); 850 libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta, (size_t)4U, 851 (size_t)12U); 852 libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta, (size_t)5U, 853 (size_t)13U); 854 libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta, (size_t)6U, 855 (size_t)14U); 856 libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&vec, zeta, (size_t)7U, 857 (size_t)15U); 858 return vec; 859 } 860 861 /** 862 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 863 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 864 */ 865 libcrux_ml_kem_vector_portable_vector_type_PortableVector 866 libcrux_ml_kem_vector_portable_inv_ntt_layer_3_step_b8( 867 libcrux_ml_kem_vector_portable_vector_type_PortableVector a, int16_t zeta) 868 { 869 return libcrux_ml_kem_vector_portable_ntt_inv_ntt_layer_3_step(a, zeta); 870 } 871 872 /** 873 Compute the product of two Kyber binomials with respect to the 874 modulus `X² - zeta`. 875 876 This function almost implements <strong>Algorithm 11</strong> of the 877 NIST FIPS 203 standard, which is reproduced below: 878 879 ```plaintext 880 Input: a₀, a₁, b₀, b₁ ∈ ℤq. 881 Input: γ ∈ ℤq. 882 Output: c₀, c₁ ∈ ℤq. 883 884 c₀ ← a₀·b₀ + a₁·b₁·γ 885 c₁ ← a₀·b₁ + a₁·b₀ 886 return c₀, c₁ 887 ``` 888 We say "almost" because the coefficients output by this function are in 889 the Montgomery domain (unlike in the specification). 890 891 The NIST FIPS 203 standard can be found at 892 <https://csrc.nist.gov/pubs/fips/203/ipd>. 893 */ 894 KRML_MUSTINLINE void 895 libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials( 896 libcrux_ml_kem_vector_portable_vector_type_PortableVector *a, 897 libcrux_ml_kem_vector_portable_vector_type_PortableVector *b, int16_t zeta, 898 size_t i, libcrux_ml_kem_vector_portable_vector_type_PortableVector *out) 899 { 900 int16_t ai = a->elements[(size_t)2U * i]; 901 int16_t bi = b->elements[(size_t)2U * i]; 902 int16_t aj = a->elements[(size_t)2U * i + (size_t)1U]; 903 int16_t bj = b->elements[(size_t)2U * i + (size_t)1U]; 904 int32_t ai_bi = 905 libcrux_secrets_int_as_i32_f5(ai) * libcrux_secrets_int_as_i32_f5(bi); 906 int32_t aj_bj_ = 907 libcrux_secrets_int_as_i32_f5(aj) * libcrux_secrets_int_as_i32_f5(bj); 908 int16_t aj_bj = 909 libcrux_ml_kem_vector_portable_arithmetic_montgomery_reduce_element( 910 aj_bj_); 911 int32_t aj_bj_zeta = libcrux_secrets_int_as_i32_f5(aj_bj) * 912 libcrux_secrets_int_as_i32_f5(zeta); 913 int32_t ai_bi_aj_bj = ai_bi + aj_bj_zeta; 914 int16_t o0 = 915 libcrux_ml_kem_vector_portable_arithmetic_montgomery_reduce_element( 916 ai_bi_aj_bj); 917 int32_t ai_bj = 918 libcrux_secrets_int_as_i32_f5(ai) * libcrux_secrets_int_as_i32_f5(bj); 919 int32_t aj_bi = 920 libcrux_secrets_int_as_i32_f5(aj) * libcrux_secrets_int_as_i32_f5(bi); 921 int32_t ai_bj_aj_bi = ai_bj + aj_bi; 922 int16_t o1 = 923 libcrux_ml_kem_vector_portable_arithmetic_montgomery_reduce_element( 924 ai_bj_aj_bi); 925 out->elements[(size_t)2U * i] = o0; 926 out->elements[(size_t)2U * i + (size_t)1U] = o1; 927 } 928 929 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 930 libcrux_ml_kem_vector_portable_ntt_ntt_multiply( 931 libcrux_ml_kem_vector_portable_vector_type_PortableVector *lhs, 932 libcrux_ml_kem_vector_portable_vector_type_PortableVector *rhs, 933 int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3) 934 { 935 int16_t nzeta0 = -zeta0; 936 int16_t nzeta1 = -zeta1; 937 int16_t nzeta2 = -zeta2; 938 int16_t nzeta3 = -zeta3; 939 libcrux_ml_kem_vector_portable_vector_type_PortableVector out = 940 libcrux_ml_kem_vector_portable_vector_type_zero(); 941 libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials( 942 lhs, rhs, libcrux_secrets_int_public_integers_classify_27_39(zeta0), 943 (size_t)0U, &out); 944 libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials( 945 lhs, rhs, libcrux_secrets_int_public_integers_classify_27_39(nzeta0), 946 (size_t)1U, &out); 947 libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials( 948 lhs, rhs, libcrux_secrets_int_public_integers_classify_27_39(zeta1), 949 (size_t)2U, &out); 950 libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials( 951 lhs, rhs, libcrux_secrets_int_public_integers_classify_27_39(nzeta1), 952 (size_t)3U, &out); 953 libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials( 954 lhs, rhs, libcrux_secrets_int_public_integers_classify_27_39(zeta2), 955 (size_t)4U, &out); 956 libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials( 957 lhs, rhs, libcrux_secrets_int_public_integers_classify_27_39(nzeta2), 958 (size_t)5U, &out); 959 libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials( 960 lhs, rhs, libcrux_secrets_int_public_integers_classify_27_39(zeta3), 961 (size_t)6U, &out); 962 libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials( 963 lhs, rhs, libcrux_secrets_int_public_integers_classify_27_39(nzeta3), 964 (size_t)7U, &out); 965 return out; 966 } 967 968 /** 969 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 970 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 971 */ 972 libcrux_ml_kem_vector_portable_vector_type_PortableVector 973 libcrux_ml_kem_vector_portable_ntt_multiply_b8( 974 libcrux_ml_kem_vector_portable_vector_type_PortableVector *lhs, 975 libcrux_ml_kem_vector_portable_vector_type_PortableVector *rhs, 976 int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3) 977 { 978 return libcrux_ml_kem_vector_portable_ntt_ntt_multiply(lhs, rhs, zeta0, zeta1, 979 zeta2, zeta3); 980 } 981 982 KRML_MUSTINLINE void 983 libcrux_ml_kem_vector_portable_serialize_serialize_1( 984 libcrux_ml_kem_vector_portable_vector_type_PortableVector v, 985 uint8_t ret[2U]) 986 { 987 uint8_t result0 = 988 (((((((uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[0U]) | 989 (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[1U]) << 1U) | 990 (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[2U]) << 2U) | 991 (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[3U]) << 3U) | 992 (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[4U]) << 4U) | 993 (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[5U]) << 5U) | 994 (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[6U]) << 6U) | 995 (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[7U]) << 7U; 996 uint8_t result1 = 997 (((((((uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[8U]) | 998 (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[9U]) << 1U) | 999 (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[10U]) << 2U) | 1000 (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[11U]) << 3U) | 1001 (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[12U]) << 4U) | 1002 (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[13U]) << 5U) | 1003 (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[14U]) << 6U) | 1004 (uint32_t)libcrux_secrets_int_as_u8_f5(v.elements[15U]) << 7U; 1005 ret[0U] = result0; 1006 ret[1U] = result1; 1007 } 1008 1009 void 1010 libcrux_ml_kem_vector_portable_serialize_1( 1011 libcrux_ml_kem_vector_portable_vector_type_PortableVector a, 1012 uint8_t ret[2U]) 1013 { 1014 uint8_t ret0[2U]; 1015 libcrux_ml_kem_vector_portable_serialize_serialize_1(a, ret0); 1016 libcrux_secrets_int_public_integers_declassify_d8_d4(ret0, ret); 1017 } 1018 1019 /** 1020 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 1021 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 1022 */ 1023 void 1024 libcrux_ml_kem_vector_portable_serialize_1_b8( 1025 libcrux_ml_kem_vector_portable_vector_type_PortableVector a, 1026 uint8_t ret[2U]) 1027 { 1028 libcrux_ml_kem_vector_portable_serialize_1(a, ret); 1029 } 1030 1031 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 1032 libcrux_ml_kem_vector_portable_serialize_deserialize_1(Eurydice_slice v) 1033 { 1034 int16_t result0 = libcrux_secrets_int_as_i16_59( 1035 (uint32_t)Eurydice_slice_index(v, (size_t)0U, uint8_t, uint8_t *) & 1U); 1036 int16_t result1 = libcrux_secrets_int_as_i16_59( 1037 (uint32_t)Eurydice_slice_index(v, (size_t)0U, uint8_t, uint8_t *) >> 1U & 1038 1U); 1039 int16_t result2 = libcrux_secrets_int_as_i16_59( 1040 (uint32_t)Eurydice_slice_index(v, (size_t)0U, uint8_t, uint8_t *) >> 2U & 1041 1U); 1042 int16_t result3 = libcrux_secrets_int_as_i16_59( 1043 (uint32_t)Eurydice_slice_index(v, (size_t)0U, uint8_t, uint8_t *) >> 3U & 1044 1U); 1045 int16_t result4 = libcrux_secrets_int_as_i16_59( 1046 (uint32_t)Eurydice_slice_index(v, (size_t)0U, uint8_t, uint8_t *) >> 4U & 1047 1U); 1048 int16_t result5 = libcrux_secrets_int_as_i16_59( 1049 (uint32_t)Eurydice_slice_index(v, (size_t)0U, uint8_t, uint8_t *) >> 5U & 1050 1U); 1051 int16_t result6 = libcrux_secrets_int_as_i16_59( 1052 (uint32_t)Eurydice_slice_index(v, (size_t)0U, uint8_t, uint8_t *) >> 6U & 1053 1U); 1054 int16_t result7 = libcrux_secrets_int_as_i16_59( 1055 (uint32_t)Eurydice_slice_index(v, (size_t)0U, uint8_t, uint8_t *) >> 7U & 1056 1U); 1057 int16_t result8 = libcrux_secrets_int_as_i16_59( 1058 (uint32_t)Eurydice_slice_index(v, (size_t)1U, uint8_t, uint8_t *) & 1U); 1059 int16_t result9 = libcrux_secrets_int_as_i16_59( 1060 (uint32_t)Eurydice_slice_index(v, (size_t)1U, uint8_t, uint8_t *) >> 1U & 1061 1U); 1062 int16_t result10 = libcrux_secrets_int_as_i16_59( 1063 (uint32_t)Eurydice_slice_index(v, (size_t)1U, uint8_t, uint8_t *) >> 2U & 1064 1U); 1065 int16_t result11 = libcrux_secrets_int_as_i16_59( 1066 (uint32_t)Eurydice_slice_index(v, (size_t)1U, uint8_t, uint8_t *) >> 3U & 1067 1U); 1068 int16_t result12 = libcrux_secrets_int_as_i16_59( 1069 (uint32_t)Eurydice_slice_index(v, (size_t)1U, uint8_t, uint8_t *) >> 4U & 1070 1U); 1071 int16_t result13 = libcrux_secrets_int_as_i16_59( 1072 (uint32_t)Eurydice_slice_index(v, (size_t)1U, uint8_t, uint8_t *) >> 5U & 1073 1U); 1074 int16_t result14 = libcrux_secrets_int_as_i16_59( 1075 (uint32_t)Eurydice_slice_index(v, (size_t)1U, uint8_t, uint8_t *) >> 6U & 1076 1U); 1077 int16_t result15 = libcrux_secrets_int_as_i16_59( 1078 (uint32_t)Eurydice_slice_index(v, (size_t)1U, uint8_t, uint8_t *) >> 7U & 1079 1U); 1080 return ( 1081 KRML_CLITERAL(libcrux_ml_kem_vector_portable_vector_type_PortableVector){ 1082 .elements = { result0, result1, result2, result3, result4, result5, 1083 result6, result7, result8, result9, result10, result11, 1084 result12, result13, result14, result15 } }); 1085 } 1086 1087 libcrux_ml_kem_vector_portable_vector_type_PortableVector 1088 libcrux_ml_kem_vector_portable_deserialize_1(Eurydice_slice a) 1089 { 1090 return libcrux_ml_kem_vector_portable_serialize_deserialize_1( 1091 libcrux_secrets_int_classify_public_classify_ref_9b_90(a)); 1092 } 1093 1094 /** 1095 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 1096 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 1097 */ 1098 libcrux_ml_kem_vector_portable_vector_type_PortableVector 1099 libcrux_ml_kem_vector_portable_deserialize_1_b8(Eurydice_slice a) 1100 { 1101 return libcrux_ml_kem_vector_portable_deserialize_1(a); 1102 } 1103 1104 KRML_MUSTINLINE uint8_t_x4 1105 libcrux_ml_kem_vector_portable_serialize_serialize_4_int(Eurydice_slice v) 1106 { 1107 uint8_t result0 = (uint32_t)libcrux_secrets_int_as_u8_f5( 1108 Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *)) 1109 << 4U | 1110 (uint32_t)libcrux_secrets_int_as_u8_f5(Eurydice_slice_index( 1111 v, (size_t)0U, int16_t, int16_t *)); 1112 uint8_t result1 = (uint32_t)libcrux_secrets_int_as_u8_f5( 1113 Eurydice_slice_index(v, (size_t)3U, int16_t, int16_t *)) 1114 << 4U | 1115 (uint32_t)libcrux_secrets_int_as_u8_f5(Eurydice_slice_index( 1116 v, (size_t)2U, int16_t, int16_t *)); 1117 uint8_t result2 = (uint32_t)libcrux_secrets_int_as_u8_f5( 1118 Eurydice_slice_index(v, (size_t)5U, int16_t, int16_t *)) 1119 << 4U | 1120 (uint32_t)libcrux_secrets_int_as_u8_f5(Eurydice_slice_index( 1121 v, (size_t)4U, int16_t, int16_t *)); 1122 uint8_t result3 = (uint32_t)libcrux_secrets_int_as_u8_f5( 1123 Eurydice_slice_index(v, (size_t)7U, int16_t, int16_t *)) 1124 << 4U | 1125 (uint32_t)libcrux_secrets_int_as_u8_f5(Eurydice_slice_index( 1126 v, (size_t)6U, int16_t, int16_t *)); 1127 return (KRML_CLITERAL(uint8_t_x4){ 1128 .fst = result0, .snd = result1, .thd = result2, .f3 = result3 }); 1129 } 1130 1131 KRML_MUSTINLINE void 1132 libcrux_ml_kem_vector_portable_serialize_serialize_4( 1133 libcrux_ml_kem_vector_portable_vector_type_PortableVector v, 1134 uint8_t ret[8U]) 1135 { 1136 uint8_t_x4 result0_3 = 1137 libcrux_ml_kem_vector_portable_serialize_serialize_4_int( 1138 Eurydice_array_to_subslice3(v.elements, (size_t)0U, (size_t)8U, 1139 int16_t *)); 1140 uint8_t_x4 result4_7 = 1141 libcrux_ml_kem_vector_portable_serialize_serialize_4_int( 1142 Eurydice_array_to_subslice3(v.elements, (size_t)8U, (size_t)16U, 1143 int16_t *)); 1144 ret[0U] = result0_3.fst; 1145 ret[1U] = result0_3.snd; 1146 ret[2U] = result0_3.thd; 1147 ret[3U] = result0_3.f3; 1148 ret[4U] = result4_7.fst; 1149 ret[5U] = result4_7.snd; 1150 ret[6U] = result4_7.thd; 1151 ret[7U] = result4_7.f3; 1152 } 1153 1154 void 1155 libcrux_ml_kem_vector_portable_serialize_4( 1156 libcrux_ml_kem_vector_portable_vector_type_PortableVector a, 1157 uint8_t ret[8U]) 1158 { 1159 uint8_t ret0[8U]; 1160 libcrux_ml_kem_vector_portable_serialize_serialize_4(a, ret0); 1161 libcrux_secrets_int_public_integers_declassify_d8_76(ret0, ret); 1162 } 1163 1164 /** 1165 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 1166 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 1167 */ 1168 void 1169 libcrux_ml_kem_vector_portable_serialize_4_b8( 1170 libcrux_ml_kem_vector_portable_vector_type_PortableVector a, 1171 uint8_t ret[8U]) 1172 { 1173 libcrux_ml_kem_vector_portable_serialize_4(a, ret); 1174 } 1175 1176 KRML_MUSTINLINE int16_t_x8 1177 libcrux_ml_kem_vector_portable_serialize_deserialize_4_int( 1178 Eurydice_slice bytes) 1179 { 1180 int16_t v0 = libcrux_secrets_int_as_i16_59( 1181 (uint32_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *) & 1182 15U); 1183 int16_t v1 = libcrux_secrets_int_as_i16_59( 1184 (uint32_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *) >> 1185 4U & 1186 15U); 1187 int16_t v2 = libcrux_secrets_int_as_i16_59( 1188 (uint32_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *) & 1189 15U); 1190 int16_t v3 = libcrux_secrets_int_as_i16_59( 1191 (uint32_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *) >> 1192 4U & 1193 15U); 1194 int16_t v4 = libcrux_secrets_int_as_i16_59( 1195 (uint32_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *) & 1196 15U); 1197 int16_t v5 = libcrux_secrets_int_as_i16_59( 1198 (uint32_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *) >> 1199 4U & 1200 15U); 1201 int16_t v6 = libcrux_secrets_int_as_i16_59( 1202 (uint32_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *) & 1203 15U); 1204 int16_t v7 = libcrux_secrets_int_as_i16_59( 1205 (uint32_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *) >> 1206 4U & 1207 15U); 1208 return (KRML_CLITERAL(int16_t_x8){ .fst = v0, 1209 .snd = v1, 1210 .thd = v2, 1211 .f3 = v3, 1212 .f4 = v4, 1213 .f5 = v5, 1214 .f6 = v6, 1215 .f7 = v7 }); 1216 } 1217 1218 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 1219 libcrux_ml_kem_vector_portable_serialize_deserialize_4(Eurydice_slice bytes) 1220 { 1221 int16_t_x8 v0_7 = libcrux_ml_kem_vector_portable_serialize_deserialize_4_int( 1222 Eurydice_slice_subslice3(bytes, (size_t)0U, (size_t)4U, uint8_t *)); 1223 int16_t_x8 v8_15 = libcrux_ml_kem_vector_portable_serialize_deserialize_4_int( 1224 Eurydice_slice_subslice3(bytes, (size_t)4U, (size_t)8U, uint8_t *)); 1225 return ( 1226 KRML_CLITERAL(libcrux_ml_kem_vector_portable_vector_type_PortableVector){ 1227 .elements = { v0_7.fst, v0_7.snd, v0_7.thd, v0_7.f3, v0_7.f4, v0_7.f5, 1228 v0_7.f6, v0_7.f7, v8_15.fst, v8_15.snd, v8_15.thd, 1229 v8_15.f3, v8_15.f4, v8_15.f5, v8_15.f6, v8_15.f7 } }); 1230 } 1231 1232 libcrux_ml_kem_vector_portable_vector_type_PortableVector 1233 libcrux_ml_kem_vector_portable_deserialize_4(Eurydice_slice a) 1234 { 1235 return libcrux_ml_kem_vector_portable_serialize_deserialize_4( 1236 libcrux_secrets_int_classify_public_classify_ref_9b_90(a)); 1237 } 1238 1239 /** 1240 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 1241 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 1242 */ 1243 libcrux_ml_kem_vector_portable_vector_type_PortableVector 1244 libcrux_ml_kem_vector_portable_deserialize_4_b8(Eurydice_slice a) 1245 { 1246 return libcrux_ml_kem_vector_portable_deserialize_4(a); 1247 } 1248 1249 KRML_MUSTINLINE uint8_t_x5 1250 libcrux_ml_kem_vector_portable_serialize_serialize_5_int(Eurydice_slice v) 1251 { 1252 uint8_t r0 = libcrux_secrets_int_as_u8_f5( 1253 Eurydice_slice_index(v, (size_t)0U, int16_t, int16_t *) | 1254 Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *) << 5U); 1255 uint8_t r1 = libcrux_secrets_int_as_u8_f5( 1256 (Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *) >> 3U | 1257 Eurydice_slice_index(v, (size_t)2U, int16_t, int16_t *) << 2U) | 1258 Eurydice_slice_index(v, (size_t)3U, int16_t, int16_t *) << 7U); 1259 uint8_t r2 = libcrux_secrets_int_as_u8_f5( 1260 Eurydice_slice_index(v, (size_t)3U, int16_t, int16_t *) >> 1U | 1261 Eurydice_slice_index(v, (size_t)4U, int16_t, int16_t *) << 4U); 1262 uint8_t r3 = libcrux_secrets_int_as_u8_f5( 1263 (Eurydice_slice_index(v, (size_t)4U, int16_t, int16_t *) >> 4U | 1264 Eurydice_slice_index(v, (size_t)5U, int16_t, int16_t *) << 1U) | 1265 Eurydice_slice_index(v, (size_t)6U, int16_t, int16_t *) << 6U); 1266 uint8_t r4 = libcrux_secrets_int_as_u8_f5( 1267 Eurydice_slice_index(v, (size_t)6U, int16_t, int16_t *) >> 2U | 1268 Eurydice_slice_index(v, (size_t)7U, int16_t, int16_t *) << 3U); 1269 return (KRML_CLITERAL(uint8_t_x5){ 1270 .fst = r0, .snd = r1, .thd = r2, .f3 = r3, .f4 = r4 }); 1271 } 1272 1273 KRML_MUSTINLINE void 1274 libcrux_ml_kem_vector_portable_serialize_serialize_5( 1275 libcrux_ml_kem_vector_portable_vector_type_PortableVector v, 1276 uint8_t ret[10U]) 1277 { 1278 uint8_t_x5 r0_4 = libcrux_ml_kem_vector_portable_serialize_serialize_5_int( 1279 Eurydice_array_to_subslice3(v.elements, (size_t)0U, (size_t)8U, 1280 int16_t *)); 1281 uint8_t_x5 r5_9 = libcrux_ml_kem_vector_portable_serialize_serialize_5_int( 1282 Eurydice_array_to_subslice3(v.elements, (size_t)8U, (size_t)16U, 1283 int16_t *)); 1284 ret[0U] = r0_4.fst; 1285 ret[1U] = r0_4.snd; 1286 ret[2U] = r0_4.thd; 1287 ret[3U] = r0_4.f3; 1288 ret[4U] = r0_4.f4; 1289 ret[5U] = r5_9.fst; 1290 ret[6U] = r5_9.snd; 1291 ret[7U] = r5_9.thd; 1292 ret[8U] = r5_9.f3; 1293 ret[9U] = r5_9.f4; 1294 } 1295 1296 void 1297 libcrux_ml_kem_vector_portable_serialize_5( 1298 libcrux_ml_kem_vector_portable_vector_type_PortableVector a, 1299 uint8_t ret[10U]) 1300 { 1301 uint8_t ret0[10U]; 1302 libcrux_ml_kem_vector_portable_serialize_serialize_5(a, ret0); 1303 libcrux_secrets_int_public_integers_declassify_d8_cc(ret0, ret); 1304 } 1305 1306 /** 1307 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 1308 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 1309 */ 1310 void 1311 libcrux_ml_kem_vector_portable_serialize_5_b8( 1312 libcrux_ml_kem_vector_portable_vector_type_PortableVector a, 1313 uint8_t ret[10U]) 1314 { 1315 libcrux_ml_kem_vector_portable_serialize_5(a, ret); 1316 } 1317 1318 KRML_MUSTINLINE int16_t_x8 1319 libcrux_ml_kem_vector_portable_serialize_deserialize_5_int( 1320 Eurydice_slice bytes) 1321 { 1322 int16_t v0 = libcrux_secrets_int_as_i16_59( 1323 (uint32_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *) & 1324 31U); 1325 int16_t v1 = libcrux_secrets_int_as_i16_59( 1326 ((uint32_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *) & 1327 3U) << 3U | 1328 (uint32_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *) >> 1329 5U); 1330 int16_t v2 = libcrux_secrets_int_as_i16_59( 1331 (uint32_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *) >> 1332 2U & 1333 31U); 1334 int16_t v3 = libcrux_secrets_int_as_i16_59( 1335 ((uint32_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *) & 1336 15U) 1337 << 1U | 1338 (uint32_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *) >> 1339 7U); 1340 int16_t v4 = libcrux_secrets_int_as_i16_59( 1341 ((uint32_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *) & 1342 1U) << 4U | 1343 (uint32_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *) >> 1344 4U); 1345 int16_t v5 = libcrux_secrets_int_as_i16_59( 1346 (uint32_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *) >> 1347 1U & 1348 31U); 1349 int16_t v6 = libcrux_secrets_int_as_i16_59( 1350 ((uint32_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *) & 1351 7U) << 2U | 1352 (uint32_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *) >> 1353 6U); 1354 int16_t v7 = libcrux_secrets_int_as_i16_59( 1355 (uint32_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *) >> 1356 3U); 1357 return (KRML_CLITERAL(int16_t_x8){ .fst = v0, 1358 .snd = v1, 1359 .thd = v2, 1360 .f3 = v3, 1361 .f4 = v4, 1362 .f5 = v5, 1363 .f6 = v6, 1364 .f7 = v7 }); 1365 } 1366 1367 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 1368 libcrux_ml_kem_vector_portable_serialize_deserialize_5(Eurydice_slice bytes) 1369 { 1370 int16_t_x8 v0_7 = libcrux_ml_kem_vector_portable_serialize_deserialize_5_int( 1371 Eurydice_slice_subslice3(bytes, (size_t)0U, (size_t)5U, uint8_t *)); 1372 int16_t_x8 v8_15 = libcrux_ml_kem_vector_portable_serialize_deserialize_5_int( 1373 Eurydice_slice_subslice3(bytes, (size_t)5U, (size_t)10U, uint8_t *)); 1374 return ( 1375 KRML_CLITERAL(libcrux_ml_kem_vector_portable_vector_type_PortableVector){ 1376 .elements = { v0_7.fst, v0_7.snd, v0_7.thd, v0_7.f3, v0_7.f4, v0_7.f5, 1377 v0_7.f6, v0_7.f7, v8_15.fst, v8_15.snd, v8_15.thd, 1378 v8_15.f3, v8_15.f4, v8_15.f5, v8_15.f6, v8_15.f7 } }); 1379 } 1380 1381 libcrux_ml_kem_vector_portable_vector_type_PortableVector 1382 libcrux_ml_kem_vector_portable_deserialize_5(Eurydice_slice a) 1383 { 1384 return libcrux_ml_kem_vector_portable_serialize_deserialize_5( 1385 libcrux_secrets_int_classify_public_classify_ref_9b_90(a)); 1386 } 1387 1388 /** 1389 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 1390 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 1391 */ 1392 libcrux_ml_kem_vector_portable_vector_type_PortableVector 1393 libcrux_ml_kem_vector_portable_deserialize_5_b8(Eurydice_slice a) 1394 { 1395 return libcrux_ml_kem_vector_portable_deserialize_5(a); 1396 } 1397 1398 KRML_MUSTINLINE uint8_t_x5 1399 libcrux_ml_kem_vector_portable_serialize_serialize_10_int(Eurydice_slice v) 1400 { 1401 uint8_t r0 = libcrux_secrets_int_as_u8_f5( 1402 Eurydice_slice_index(v, (size_t)0U, int16_t, int16_t *) & (int16_t)255); 1403 uint8_t r1 = 1404 (uint32_t)libcrux_secrets_int_as_u8_f5( 1405 Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *) & (int16_t)63) 1406 << 2U | 1407 (uint32_t)libcrux_secrets_int_as_u8_f5( 1408 Eurydice_slice_index(v, (size_t)0U, int16_t, int16_t *) >> 8U & 1409 (int16_t)3); 1410 uint8_t r2 = 1411 (uint32_t)libcrux_secrets_int_as_u8_f5( 1412 Eurydice_slice_index(v, (size_t)2U, int16_t, int16_t *) & (int16_t)15) 1413 << 4U | 1414 (uint32_t)libcrux_secrets_int_as_u8_f5( 1415 Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *) >> 6U & 1416 (int16_t)15); 1417 uint8_t r3 = 1418 (uint32_t)libcrux_secrets_int_as_u8_f5( 1419 Eurydice_slice_index(v, (size_t)3U, int16_t, int16_t *) & (int16_t)3) 1420 << 6U | 1421 (uint32_t)libcrux_secrets_int_as_u8_f5( 1422 Eurydice_slice_index(v, (size_t)2U, int16_t, int16_t *) >> 4U & 1423 (int16_t)63); 1424 uint8_t r4 = libcrux_secrets_int_as_u8_f5( 1425 Eurydice_slice_index(v, (size_t)3U, int16_t, int16_t *) >> 2U & 1426 (int16_t)255); 1427 return (KRML_CLITERAL(uint8_t_x5){ 1428 .fst = r0, .snd = r1, .thd = r2, .f3 = r3, .f4 = r4 }); 1429 } 1430 1431 KRML_MUSTINLINE void 1432 libcrux_ml_kem_vector_portable_serialize_serialize_10( 1433 libcrux_ml_kem_vector_portable_vector_type_PortableVector v, 1434 uint8_t ret[20U]) 1435 { 1436 uint8_t_x5 r0_4 = libcrux_ml_kem_vector_portable_serialize_serialize_10_int( 1437 Eurydice_array_to_subslice3(v.elements, (size_t)0U, (size_t)4U, 1438 int16_t *)); 1439 uint8_t_x5 r5_9 = libcrux_ml_kem_vector_portable_serialize_serialize_10_int( 1440 Eurydice_array_to_subslice3(v.elements, (size_t)4U, (size_t)8U, 1441 int16_t *)); 1442 uint8_t_x5 r10_14 = libcrux_ml_kem_vector_portable_serialize_serialize_10_int( 1443 Eurydice_array_to_subslice3(v.elements, (size_t)8U, (size_t)12U, 1444 int16_t *)); 1445 uint8_t_x5 r15_19 = libcrux_ml_kem_vector_portable_serialize_serialize_10_int( 1446 Eurydice_array_to_subslice3(v.elements, (size_t)12U, (size_t)16U, 1447 int16_t *)); 1448 ret[0U] = r0_4.fst; 1449 ret[1U] = r0_4.snd; 1450 ret[2U] = r0_4.thd; 1451 ret[3U] = r0_4.f3; 1452 ret[4U] = r0_4.f4; 1453 ret[5U] = r5_9.fst; 1454 ret[6U] = r5_9.snd; 1455 ret[7U] = r5_9.thd; 1456 ret[8U] = r5_9.f3; 1457 ret[9U] = r5_9.f4; 1458 ret[10U] = r10_14.fst; 1459 ret[11U] = r10_14.snd; 1460 ret[12U] = r10_14.thd; 1461 ret[13U] = r10_14.f3; 1462 ret[14U] = r10_14.f4; 1463 ret[15U] = r15_19.fst; 1464 ret[16U] = r15_19.snd; 1465 ret[17U] = r15_19.thd; 1466 ret[18U] = r15_19.f3; 1467 ret[19U] = r15_19.f4; 1468 } 1469 1470 void 1471 libcrux_ml_kem_vector_portable_serialize_10( 1472 libcrux_ml_kem_vector_portable_vector_type_PortableVector a, 1473 uint8_t ret[20U]) 1474 { 1475 uint8_t ret0[20U]; 1476 libcrux_ml_kem_vector_portable_serialize_serialize_10(a, ret0); 1477 libcrux_secrets_int_public_integers_declassify_d8_57(ret0, ret); 1478 } 1479 1480 /** 1481 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 1482 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 1483 */ 1484 void 1485 libcrux_ml_kem_vector_portable_serialize_10_b8( 1486 libcrux_ml_kem_vector_portable_vector_type_PortableVector a, 1487 uint8_t ret[20U]) 1488 { 1489 libcrux_ml_kem_vector_portable_serialize_10(a, ret); 1490 } 1491 1492 KRML_MUSTINLINE int16_t_x8 1493 libcrux_ml_kem_vector_portable_serialize_deserialize_10_int( 1494 Eurydice_slice bytes) 1495 { 1496 int16_t r0 = libcrux_secrets_int_as_i16_f5( 1497 (libcrux_secrets_int_as_i16_59( 1498 Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *)) & 1499 (int16_t)3) 1500 << 8U | 1501 (libcrux_secrets_int_as_i16_59( 1502 Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *)) & 1503 (int16_t)255)); 1504 int16_t r1 = libcrux_secrets_int_as_i16_f5( 1505 (libcrux_secrets_int_as_i16_59( 1506 Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *)) & 1507 (int16_t)15) 1508 << 6U | 1509 libcrux_secrets_int_as_i16_59( 1510 Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *)) >> 1511 2U); 1512 int16_t r2 = libcrux_secrets_int_as_i16_f5( 1513 (libcrux_secrets_int_as_i16_59( 1514 Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *)) & 1515 (int16_t)63) 1516 << 4U | 1517 libcrux_secrets_int_as_i16_59( 1518 Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *)) >> 1519 4U); 1520 int16_t r3 = libcrux_secrets_int_as_i16_f5( 1521 libcrux_secrets_int_as_i16_59( 1522 Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *)) 1523 << 2U | 1524 libcrux_secrets_int_as_i16_59( 1525 Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *)) >> 1526 6U); 1527 int16_t r4 = libcrux_secrets_int_as_i16_f5( 1528 (libcrux_secrets_int_as_i16_59( 1529 Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *)) & 1530 (int16_t)3) 1531 << 8U | 1532 (libcrux_secrets_int_as_i16_59( 1533 Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *)) & 1534 (int16_t)255)); 1535 int16_t r5 = libcrux_secrets_int_as_i16_f5( 1536 (libcrux_secrets_int_as_i16_59( 1537 Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *)) & 1538 (int16_t)15) 1539 << 6U | 1540 libcrux_secrets_int_as_i16_59( 1541 Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *)) >> 1542 2U); 1543 int16_t r6 = libcrux_secrets_int_as_i16_f5( 1544 (libcrux_secrets_int_as_i16_59( 1545 Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *)) & 1546 (int16_t)63) 1547 << 4U | 1548 libcrux_secrets_int_as_i16_59( 1549 Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *)) >> 1550 4U); 1551 int16_t r7 = libcrux_secrets_int_as_i16_f5( 1552 libcrux_secrets_int_as_i16_59( 1553 Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *)) 1554 << 2U | 1555 libcrux_secrets_int_as_i16_59( 1556 Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *)) >> 1557 6U); 1558 return (KRML_CLITERAL(int16_t_x8){ .fst = r0, 1559 .snd = r1, 1560 .thd = r2, 1561 .f3 = r3, 1562 .f4 = r4, 1563 .f5 = r5, 1564 .f6 = r6, 1565 .f7 = r7 }); 1566 } 1567 1568 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 1569 libcrux_ml_kem_vector_portable_serialize_deserialize_10(Eurydice_slice bytes) 1570 { 1571 int16_t_x8 v0_7 = libcrux_ml_kem_vector_portable_serialize_deserialize_10_int( 1572 Eurydice_slice_subslice3(bytes, (size_t)0U, (size_t)10U, uint8_t *)); 1573 int16_t_x8 v8_15 = 1574 libcrux_ml_kem_vector_portable_serialize_deserialize_10_int( 1575 Eurydice_slice_subslice3(bytes, (size_t)10U, (size_t)20U, uint8_t *)); 1576 return ( 1577 KRML_CLITERAL(libcrux_ml_kem_vector_portable_vector_type_PortableVector){ 1578 .elements = { v0_7.fst, v0_7.snd, v0_7.thd, v0_7.f3, v0_7.f4, v0_7.f5, 1579 v0_7.f6, v0_7.f7, v8_15.fst, v8_15.snd, v8_15.thd, 1580 v8_15.f3, v8_15.f4, v8_15.f5, v8_15.f6, v8_15.f7 } }); 1581 } 1582 1583 libcrux_ml_kem_vector_portable_vector_type_PortableVector 1584 libcrux_ml_kem_vector_portable_deserialize_10(Eurydice_slice a) 1585 { 1586 return libcrux_ml_kem_vector_portable_serialize_deserialize_10( 1587 libcrux_secrets_int_classify_public_classify_ref_9b_90(a)); 1588 } 1589 1590 /** 1591 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 1592 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 1593 */ 1594 libcrux_ml_kem_vector_portable_vector_type_PortableVector 1595 libcrux_ml_kem_vector_portable_deserialize_10_b8(Eurydice_slice a) 1596 { 1597 return libcrux_ml_kem_vector_portable_deserialize_10(a); 1598 } 1599 1600 KRML_MUSTINLINE uint8_t_x11 1601 libcrux_ml_kem_vector_portable_serialize_serialize_11_int(Eurydice_slice v) 1602 { 1603 uint8_t r0 = libcrux_secrets_int_as_u8_f5( 1604 Eurydice_slice_index(v, (size_t)0U, int16_t, int16_t *)); 1605 uint8_t r1 = 1606 (uint32_t)libcrux_secrets_int_as_u8_f5( 1607 Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *) & (int16_t)31) 1608 << 3U | 1609 (uint32_t)libcrux_secrets_int_as_u8_f5( 1610 Eurydice_slice_index(v, (size_t)0U, int16_t, int16_t *) >> 8U); 1611 uint8_t r2 = 1612 (uint32_t)libcrux_secrets_int_as_u8_f5( 1613 Eurydice_slice_index(v, (size_t)2U, int16_t, int16_t *) & (int16_t)3) 1614 << 6U | 1615 (uint32_t)libcrux_secrets_int_as_u8_f5( 1616 Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *) >> 5U); 1617 uint8_t r3 = libcrux_secrets_int_as_u8_f5( 1618 Eurydice_slice_index(v, (size_t)2U, int16_t, int16_t *) >> 2U & 1619 (int16_t)255); 1620 uint8_t r4 = 1621 (uint32_t)libcrux_secrets_int_as_u8_f5( 1622 Eurydice_slice_index(v, (size_t)3U, int16_t, int16_t *) & 1623 (int16_t)127) 1624 << 1U | 1625 (uint32_t)libcrux_secrets_int_as_u8_f5( 1626 Eurydice_slice_index(v, (size_t)2U, int16_t, int16_t *) >> 10U); 1627 uint8_t r5 = 1628 (uint32_t)libcrux_secrets_int_as_u8_f5( 1629 Eurydice_slice_index(v, (size_t)4U, int16_t, int16_t *) & (int16_t)15) 1630 << 4U | 1631 (uint32_t)libcrux_secrets_int_as_u8_f5( 1632 Eurydice_slice_index(v, (size_t)3U, int16_t, int16_t *) >> 7U); 1633 uint8_t r6 = 1634 (uint32_t)libcrux_secrets_int_as_u8_f5( 1635 Eurydice_slice_index(v, (size_t)5U, int16_t, int16_t *) & (int16_t)1) 1636 << 7U | 1637 (uint32_t)libcrux_secrets_int_as_u8_f5( 1638 Eurydice_slice_index(v, (size_t)4U, int16_t, int16_t *) >> 4U); 1639 uint8_t r7 = libcrux_secrets_int_as_u8_f5( 1640 Eurydice_slice_index(v, (size_t)5U, int16_t, int16_t *) >> 1U & 1641 (int16_t)255); 1642 uint8_t r8 = 1643 (uint32_t)libcrux_secrets_int_as_u8_f5( 1644 Eurydice_slice_index(v, (size_t)6U, int16_t, int16_t *) & (int16_t)63) 1645 << 2U | 1646 (uint32_t)libcrux_secrets_int_as_u8_f5( 1647 Eurydice_slice_index(v, (size_t)5U, int16_t, int16_t *) >> 9U); 1648 uint8_t r9 = 1649 (uint32_t)libcrux_secrets_int_as_u8_f5( 1650 Eurydice_slice_index(v, (size_t)7U, int16_t, int16_t *) & (int16_t)7) 1651 << 5U | 1652 (uint32_t)libcrux_secrets_int_as_u8_f5( 1653 Eurydice_slice_index(v, (size_t)6U, int16_t, int16_t *) >> 6U); 1654 uint8_t r10 = libcrux_secrets_int_as_u8_f5( 1655 Eurydice_slice_index(v, (size_t)7U, int16_t, int16_t *) >> 3U); 1656 return (KRML_CLITERAL(uint8_t_x11){ .fst = r0, 1657 .snd = r1, 1658 .thd = r2, 1659 .f3 = r3, 1660 .f4 = r4, 1661 .f5 = r5, 1662 .f6 = r6, 1663 .f7 = r7, 1664 .f8 = r8, 1665 .f9 = r9, 1666 .f10 = r10 }); 1667 } 1668 1669 KRML_MUSTINLINE void 1670 libcrux_ml_kem_vector_portable_serialize_serialize_11( 1671 libcrux_ml_kem_vector_portable_vector_type_PortableVector v, 1672 uint8_t ret[22U]) 1673 { 1674 uint8_t_x11 r0_10 = libcrux_ml_kem_vector_portable_serialize_serialize_11_int( 1675 Eurydice_array_to_subslice3(v.elements, (size_t)0U, (size_t)8U, 1676 int16_t *)); 1677 uint8_t_x11 r11_21 = 1678 libcrux_ml_kem_vector_portable_serialize_serialize_11_int( 1679 Eurydice_array_to_subslice3(v.elements, (size_t)8U, (size_t)16U, 1680 int16_t *)); 1681 ret[0U] = r0_10.fst; 1682 ret[1U] = r0_10.snd; 1683 ret[2U] = r0_10.thd; 1684 ret[3U] = r0_10.f3; 1685 ret[4U] = r0_10.f4; 1686 ret[5U] = r0_10.f5; 1687 ret[6U] = r0_10.f6; 1688 ret[7U] = r0_10.f7; 1689 ret[8U] = r0_10.f8; 1690 ret[9U] = r0_10.f9; 1691 ret[10U] = r0_10.f10; 1692 ret[11U] = r11_21.fst; 1693 ret[12U] = r11_21.snd; 1694 ret[13U] = r11_21.thd; 1695 ret[14U] = r11_21.f3; 1696 ret[15U] = r11_21.f4; 1697 ret[16U] = r11_21.f5; 1698 ret[17U] = r11_21.f6; 1699 ret[18U] = r11_21.f7; 1700 ret[19U] = r11_21.f8; 1701 ret[20U] = r11_21.f9; 1702 ret[21U] = r11_21.f10; 1703 } 1704 1705 void 1706 libcrux_ml_kem_vector_portable_serialize_11( 1707 libcrux_ml_kem_vector_portable_vector_type_PortableVector a, 1708 uint8_t ret[22U]) 1709 { 1710 uint8_t ret0[22U]; 1711 libcrux_ml_kem_vector_portable_serialize_serialize_11(a, ret0); 1712 libcrux_secrets_int_public_integers_declassify_d8_fa(ret0, ret); 1713 } 1714 1715 /** 1716 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 1717 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 1718 */ 1719 void 1720 libcrux_ml_kem_vector_portable_serialize_11_b8( 1721 libcrux_ml_kem_vector_portable_vector_type_PortableVector a, 1722 uint8_t ret[22U]) 1723 { 1724 libcrux_ml_kem_vector_portable_serialize_11(a, ret); 1725 } 1726 1727 KRML_MUSTINLINE int16_t_x8 1728 libcrux_ml_kem_vector_portable_serialize_deserialize_11_int( 1729 Eurydice_slice bytes) 1730 { 1731 int16_t r0 = (libcrux_secrets_int_as_i16_59(Eurydice_slice_index( 1732 bytes, (size_t)1U, uint8_t, uint8_t *)) & 1733 (int16_t)7) 1734 << 8U | 1735 libcrux_secrets_int_as_i16_59( 1736 Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *)); 1737 int16_t r1 = (libcrux_secrets_int_as_i16_59(Eurydice_slice_index( 1738 bytes, (size_t)2U, uint8_t, uint8_t *)) & 1739 (int16_t)63) 1740 << 5U | 1741 libcrux_secrets_int_as_i16_59(Eurydice_slice_index( 1742 bytes, (size_t)1U, uint8_t, uint8_t *)) >> 1743 3U; 1744 int16_t r2 = ((libcrux_secrets_int_as_i16_59(Eurydice_slice_index( 1745 bytes, (size_t)4U, uint8_t, uint8_t *)) & 1746 (int16_t)1) 1747 << 10U | 1748 libcrux_secrets_int_as_i16_59( 1749 Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *)) 1750 << 2U) | 1751 libcrux_secrets_int_as_i16_59(Eurydice_slice_index( 1752 bytes, (size_t)2U, uint8_t, uint8_t *)) >> 1753 6U; 1754 int16_t r3 = (libcrux_secrets_int_as_i16_59(Eurydice_slice_index( 1755 bytes, (size_t)5U, uint8_t, uint8_t *)) & 1756 (int16_t)15) 1757 << 7U | 1758 libcrux_secrets_int_as_i16_59(Eurydice_slice_index( 1759 bytes, (size_t)4U, uint8_t, uint8_t *)) >> 1760 1U; 1761 int16_t r4 = (libcrux_secrets_int_as_i16_59(Eurydice_slice_index( 1762 bytes, (size_t)6U, uint8_t, uint8_t *)) & 1763 (int16_t)127) 1764 << 4U | 1765 libcrux_secrets_int_as_i16_59(Eurydice_slice_index( 1766 bytes, (size_t)5U, uint8_t, uint8_t *)) >> 1767 4U; 1768 int16_t r5 = ((libcrux_secrets_int_as_i16_59(Eurydice_slice_index( 1769 bytes, (size_t)8U, uint8_t, uint8_t *)) & 1770 (int16_t)3) 1771 << 9U | 1772 libcrux_secrets_int_as_i16_59( 1773 Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *)) 1774 << 1U) | 1775 libcrux_secrets_int_as_i16_59(Eurydice_slice_index( 1776 bytes, (size_t)6U, uint8_t, uint8_t *)) >> 1777 7U; 1778 int16_t r6 = (libcrux_secrets_int_as_i16_59(Eurydice_slice_index( 1779 bytes, (size_t)9U, uint8_t, uint8_t *)) & 1780 (int16_t)31) 1781 << 6U | 1782 libcrux_secrets_int_as_i16_59(Eurydice_slice_index( 1783 bytes, (size_t)8U, uint8_t, uint8_t *)) >> 1784 2U; 1785 int16_t r7 = libcrux_secrets_int_as_i16_59( 1786 Eurydice_slice_index(bytes, (size_t)10U, uint8_t, uint8_t *)) 1787 << 3U | 1788 libcrux_secrets_int_as_i16_59(Eurydice_slice_index( 1789 bytes, (size_t)9U, uint8_t, uint8_t *)) >> 1790 5U; 1791 return (KRML_CLITERAL(int16_t_x8){ .fst = r0, 1792 .snd = r1, 1793 .thd = r2, 1794 .f3 = r3, 1795 .f4 = r4, 1796 .f5 = r5, 1797 .f6 = r6, 1798 .f7 = r7 }); 1799 } 1800 1801 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 1802 libcrux_ml_kem_vector_portable_serialize_deserialize_11(Eurydice_slice bytes) 1803 { 1804 int16_t_x8 v0_7 = libcrux_ml_kem_vector_portable_serialize_deserialize_11_int( 1805 Eurydice_slice_subslice3(bytes, (size_t)0U, (size_t)11U, uint8_t *)); 1806 int16_t_x8 v8_15 = 1807 libcrux_ml_kem_vector_portable_serialize_deserialize_11_int( 1808 Eurydice_slice_subslice3(bytes, (size_t)11U, (size_t)22U, uint8_t *)); 1809 return ( 1810 KRML_CLITERAL(libcrux_ml_kem_vector_portable_vector_type_PortableVector){ 1811 .elements = { v0_7.fst, v0_7.snd, v0_7.thd, v0_7.f3, v0_7.f4, v0_7.f5, 1812 v0_7.f6, v0_7.f7, v8_15.fst, v8_15.snd, v8_15.thd, 1813 v8_15.f3, v8_15.f4, v8_15.f5, v8_15.f6, v8_15.f7 } }); 1814 } 1815 1816 libcrux_ml_kem_vector_portable_vector_type_PortableVector 1817 libcrux_ml_kem_vector_portable_deserialize_11(Eurydice_slice a) 1818 { 1819 return libcrux_ml_kem_vector_portable_serialize_deserialize_11( 1820 libcrux_secrets_int_classify_public_classify_ref_9b_90(a)); 1821 } 1822 1823 /** 1824 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 1825 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 1826 */ 1827 libcrux_ml_kem_vector_portable_vector_type_PortableVector 1828 libcrux_ml_kem_vector_portable_deserialize_11_b8(Eurydice_slice a) 1829 { 1830 return libcrux_ml_kem_vector_portable_deserialize_11(a); 1831 } 1832 1833 KRML_MUSTINLINE uint8_t_x3 1834 libcrux_ml_kem_vector_portable_serialize_serialize_12_int(Eurydice_slice v) 1835 { 1836 uint8_t r0 = libcrux_secrets_int_as_u8_f5( 1837 Eurydice_slice_index(v, (size_t)0U, int16_t, int16_t *) & (int16_t)255); 1838 uint8_t r1 = libcrux_secrets_int_as_u8_f5( 1839 Eurydice_slice_index(v, (size_t)0U, int16_t, int16_t *) >> 8U | 1840 (Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *) & (int16_t)15) 1841 << 4U); 1842 uint8_t r2 = libcrux_secrets_int_as_u8_f5( 1843 Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *) >> 4U & 1844 (int16_t)255); 1845 return (KRML_CLITERAL(uint8_t_x3){ .fst = r0, .snd = r1, .thd = r2 }); 1846 } 1847 1848 KRML_MUSTINLINE void 1849 libcrux_ml_kem_vector_portable_serialize_serialize_12( 1850 libcrux_ml_kem_vector_portable_vector_type_PortableVector v, 1851 uint8_t ret[24U]) 1852 { 1853 uint8_t_x3 r0_2 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int( 1854 Eurydice_array_to_subslice3(v.elements, (size_t)0U, (size_t)2U, 1855 int16_t *)); 1856 uint8_t_x3 r3_5 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int( 1857 Eurydice_array_to_subslice3(v.elements, (size_t)2U, (size_t)4U, 1858 int16_t *)); 1859 uint8_t_x3 r6_8 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int( 1860 Eurydice_array_to_subslice3(v.elements, (size_t)4U, (size_t)6U, 1861 int16_t *)); 1862 uint8_t_x3 r9_11 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int( 1863 Eurydice_array_to_subslice3(v.elements, (size_t)6U, (size_t)8U, 1864 int16_t *)); 1865 uint8_t_x3 r12_14 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int( 1866 Eurydice_array_to_subslice3(v.elements, (size_t)8U, (size_t)10U, 1867 int16_t *)); 1868 uint8_t_x3 r15_17 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int( 1869 Eurydice_array_to_subslice3(v.elements, (size_t)10U, (size_t)12U, 1870 int16_t *)); 1871 uint8_t_x3 r18_20 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int( 1872 Eurydice_array_to_subslice3(v.elements, (size_t)12U, (size_t)14U, 1873 int16_t *)); 1874 uint8_t_x3 r21_23 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int( 1875 Eurydice_array_to_subslice3(v.elements, (size_t)14U, (size_t)16U, 1876 int16_t *)); 1877 ret[0U] = r0_2.fst; 1878 ret[1U] = r0_2.snd; 1879 ret[2U] = r0_2.thd; 1880 ret[3U] = r3_5.fst; 1881 ret[4U] = r3_5.snd; 1882 ret[5U] = r3_5.thd; 1883 ret[6U] = r6_8.fst; 1884 ret[7U] = r6_8.snd; 1885 ret[8U] = r6_8.thd; 1886 ret[9U] = r9_11.fst; 1887 ret[10U] = r9_11.snd; 1888 ret[11U] = r9_11.thd; 1889 ret[12U] = r12_14.fst; 1890 ret[13U] = r12_14.snd; 1891 ret[14U] = r12_14.thd; 1892 ret[15U] = r15_17.fst; 1893 ret[16U] = r15_17.snd; 1894 ret[17U] = r15_17.thd; 1895 ret[18U] = r18_20.fst; 1896 ret[19U] = r18_20.snd; 1897 ret[20U] = r18_20.thd; 1898 ret[21U] = r21_23.fst; 1899 ret[22U] = r21_23.snd; 1900 ret[23U] = r21_23.thd; 1901 } 1902 1903 void 1904 libcrux_ml_kem_vector_portable_serialize_12( 1905 libcrux_ml_kem_vector_portable_vector_type_PortableVector a, 1906 uint8_t ret[24U]) 1907 { 1908 uint8_t ret0[24U]; 1909 libcrux_ml_kem_vector_portable_serialize_serialize_12(a, ret0); 1910 libcrux_secrets_int_public_integers_declassify_d8_d2(ret0, ret); 1911 } 1912 1913 /** 1914 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 1915 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 1916 */ 1917 void 1918 libcrux_ml_kem_vector_portable_serialize_12_b8( 1919 libcrux_ml_kem_vector_portable_vector_type_PortableVector a, 1920 uint8_t ret[24U]) 1921 { 1922 libcrux_ml_kem_vector_portable_serialize_12(a, ret); 1923 } 1924 1925 KRML_MUSTINLINE int16_t_x2 1926 libcrux_ml_kem_vector_portable_serialize_deserialize_12_int( 1927 Eurydice_slice bytes) 1928 { 1929 int16_t byte0 = libcrux_secrets_int_as_i16_59( 1930 Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *)); 1931 int16_t byte1 = libcrux_secrets_int_as_i16_59( 1932 Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *)); 1933 int16_t byte2 = libcrux_secrets_int_as_i16_59( 1934 Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *)); 1935 int16_t r0 = (byte1 & (int16_t)15) << 8U | (byte0 & (int16_t)255); 1936 int16_t r1 = byte2 << 4U | (byte1 >> 4U & (int16_t)15); 1937 return (KRML_CLITERAL(int16_t_x2){ .fst = r0, .snd = r1 }); 1938 } 1939 1940 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 1941 libcrux_ml_kem_vector_portable_serialize_deserialize_12(Eurydice_slice bytes) 1942 { 1943 int16_t_x2 v0_1 = libcrux_ml_kem_vector_portable_serialize_deserialize_12_int( 1944 Eurydice_slice_subslice3(bytes, (size_t)0U, (size_t)3U, uint8_t *)); 1945 int16_t_x2 v2_3 = libcrux_ml_kem_vector_portable_serialize_deserialize_12_int( 1946 Eurydice_slice_subslice3(bytes, (size_t)3U, (size_t)6U, uint8_t *)); 1947 int16_t_x2 v4_5 = libcrux_ml_kem_vector_portable_serialize_deserialize_12_int( 1948 Eurydice_slice_subslice3(bytes, (size_t)6U, (size_t)9U, uint8_t *)); 1949 int16_t_x2 v6_7 = libcrux_ml_kem_vector_portable_serialize_deserialize_12_int( 1950 Eurydice_slice_subslice3(bytes, (size_t)9U, (size_t)12U, uint8_t *)); 1951 int16_t_x2 v8_9 = libcrux_ml_kem_vector_portable_serialize_deserialize_12_int( 1952 Eurydice_slice_subslice3(bytes, (size_t)12U, (size_t)15U, uint8_t *)); 1953 int16_t_x2 v10_11 = 1954 libcrux_ml_kem_vector_portable_serialize_deserialize_12_int( 1955 Eurydice_slice_subslice3(bytes, (size_t)15U, (size_t)18U, uint8_t *)); 1956 int16_t_x2 v12_13 = 1957 libcrux_ml_kem_vector_portable_serialize_deserialize_12_int( 1958 Eurydice_slice_subslice3(bytes, (size_t)18U, (size_t)21U, uint8_t *)); 1959 int16_t_x2 v14_15 = 1960 libcrux_ml_kem_vector_portable_serialize_deserialize_12_int( 1961 Eurydice_slice_subslice3(bytes, (size_t)21U, (size_t)24U, uint8_t *)); 1962 return ( 1963 KRML_CLITERAL(libcrux_ml_kem_vector_portable_vector_type_PortableVector){ 1964 .elements = { v0_1.fst, v0_1.snd, v2_3.fst, v2_3.snd, v4_5.fst, 1965 v4_5.snd, v6_7.fst, v6_7.snd, v8_9.fst, v8_9.snd, 1966 v10_11.fst, v10_11.snd, v12_13.fst, v12_13.snd, 1967 v14_15.fst, v14_15.snd } }); 1968 } 1969 1970 libcrux_ml_kem_vector_portable_vector_type_PortableVector 1971 libcrux_ml_kem_vector_portable_deserialize_12(Eurydice_slice a) 1972 { 1973 return libcrux_ml_kem_vector_portable_serialize_deserialize_12( 1974 libcrux_secrets_int_classify_public_classify_ref_9b_90(a)); 1975 } 1976 1977 /** 1978 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 1979 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 1980 */ 1981 libcrux_ml_kem_vector_portable_vector_type_PortableVector 1982 libcrux_ml_kem_vector_portable_deserialize_12_b8(Eurydice_slice a) 1983 { 1984 return libcrux_ml_kem_vector_portable_deserialize_12(a); 1985 } 1986 1987 KRML_MUSTINLINE size_t 1988 libcrux_ml_kem_vector_portable_sampling_rej_sample( 1989 Eurydice_slice a, Eurydice_slice result) 1990 { 1991 size_t sampled = (size_t)0U; 1992 for (size_t i = (size_t)0U; i < Eurydice_slice_len(a, uint8_t) / (size_t)3U; 1993 i++) { 1994 size_t i0 = i; 1995 int16_t b1 = (int16_t)Eurydice_slice_index(a, i0 * (size_t)3U + (size_t)0U, 1996 uint8_t, uint8_t *); 1997 int16_t b2 = (int16_t)Eurydice_slice_index(a, i0 * (size_t)3U + (size_t)1U, 1998 uint8_t, uint8_t *); 1999 int16_t b3 = (int16_t)Eurydice_slice_index(a, i0 * (size_t)3U + (size_t)2U, 2000 uint8_t, uint8_t *); 2001 int16_t d1 = (b2 & (int16_t)15) << 8U | b1; 2002 int16_t d2 = b3 << 4U | b2 >> 4U; 2003 if (d1 < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS) { 2004 if (sampled < (size_t)16U) { 2005 Eurydice_slice_index(result, sampled, int16_t, int16_t *) = d1; 2006 sampled++; 2007 } 2008 } 2009 if (d2 < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS) { 2010 if (sampled < (size_t)16U) { 2011 Eurydice_slice_index(result, sampled, int16_t, int16_t *) = d2; 2012 sampled++; 2013 } 2014 } 2015 } 2016 return sampled; 2017 } 2018 2019 /** 2020 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 2021 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 2022 */ 2023 size_t 2024 libcrux_ml_kem_vector_portable_rej_sample_b8(Eurydice_slice a, 2025 Eurydice_slice out) 2026 { 2027 return libcrux_ml_kem_vector_portable_sampling_rej_sample(a, out); 2028 } 2029 2030 /** 2031 This function found in impl {core::clone::Clone for 2032 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 2033 */ 2034 inline libcrux_ml_kem_vector_portable_vector_type_PortableVector 2035 libcrux_ml_kem_vector_portable_vector_type_clone_9c( 2036 libcrux_ml_kem_vector_portable_vector_type_PortableVector *self) 2037 { 2038 return self[0U]; 2039 } 2040 2041 /** 2042 This function found in impl 2043 {libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0, 2044 TraitClause@1]} 2045 */ 2046 /** 2047 A monomorphic instance of libcrux_ml_kem.polynomial.ZERO_d6 2048 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 2049 with const generics 2050 2051 */ 2052 static libcrux_ml_kem_polynomial_PolynomialRingElement_1d 2053 ZERO_d6_ea(void) 2054 { 2055 libcrux_ml_kem_polynomial_PolynomialRingElement_1d lit; 2056 libcrux_ml_kem_vector_portable_vector_type_PortableVector 2057 repeat_expression[16U]; 2058 KRML_MAYBE_FOR16( 2059 i, (size_t)0U, (size_t)16U, (size_t)1U, 2060 repeat_expression[i] = libcrux_ml_kem_vector_portable_ZERO_b8();); 2061 memcpy(lit.coefficients, repeat_expression, 2062 (size_t)16U * 2063 sizeof(libcrux_ml_kem_vector_portable_vector_type_PortableVector)); 2064 return lit; 2065 } 2066 2067 /** 2068 This function found in impl {core::ops::function::FnMut<(usize), 2069 libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0, 2070 TraitClause@1]> for 2071 libcrux_ml_kem::serialize::deserialize_ring_elements_reduced_out::closure<Vector, 2072 K>[TraitClause@0, TraitClause@1]} 2073 */ 2074 /** 2075 A monomorphic instance of 2076 libcrux_ml_kem.serialize.deserialize_ring_elements_reduced_out.call_mut_0b with 2077 types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const 2078 generics 2079 - K= 4 2080 */ 2081 static libcrux_ml_kem_polynomial_PolynomialRingElement_1d 2082 call_mut_0b_d0( 2083 void **_) 2084 { 2085 return ZERO_d6_ea(); 2086 } 2087 2088 /** 2089 Only use with public values. 2090 2091 This MUST NOT be used with secret inputs, like its caller 2092 `deserialize_ring_elements_reduced`. 2093 */ 2094 /** 2095 A monomorphic instance of 2096 libcrux_ml_kem.serialize.deserialize_to_reduced_ring_element with types 2097 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 2098 2099 */ 2100 static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d 2101 deserialize_to_reduced_ring_element_ea(Eurydice_slice serialized) 2102 { 2103 libcrux_ml_kem_polynomial_PolynomialRingElement_1d re = ZERO_d6_ea(); 2104 for (size_t i = (size_t)0U; 2105 i < Eurydice_slice_len(serialized, uint8_t) / (size_t)24U; i++) { 2106 size_t i0 = i; 2107 Eurydice_slice bytes = 2108 Eurydice_slice_subslice3(serialized, i0 * (size_t)24U, 2109 i0 * (size_t)24U + (size_t)24U, uint8_t *); 2110 libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = 2111 libcrux_ml_kem_vector_portable_deserialize_12_b8(bytes); 2112 libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = 2113 libcrux_ml_kem_vector_portable_cond_subtract_3329_b8(coefficient); 2114 re.coefficients[i0] = uu____0; 2115 } 2116 return re; 2117 } 2118 2119 /** 2120 See [deserialize_ring_elements_reduced_out]. 2121 */ 2122 /** 2123 A monomorphic instance of 2124 libcrux_ml_kem.serialize.deserialize_ring_elements_reduced with types 2125 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 2126 - K= 4 2127 */ 2128 static KRML_MUSTINLINE void 2129 deserialize_ring_elements_reduced_d0( 2130 Eurydice_slice public_key, 2131 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *deserialized_pk) 2132 { 2133 for (size_t i = (size_t)0U; 2134 i < Eurydice_slice_len(public_key, uint8_t) / 2135 LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; 2136 i++) { 2137 size_t i0 = i; 2138 Eurydice_slice ring_element = Eurydice_slice_subslice3( 2139 public_key, i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, 2140 i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + 2141 LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, 2142 uint8_t *); 2143 libcrux_ml_kem_polynomial_PolynomialRingElement_1d uu____0 = 2144 deserialize_to_reduced_ring_element_ea(ring_element); 2145 deserialized_pk[i0] = uu____0; 2146 } 2147 } 2148 2149 /** 2150 This function deserializes ring elements and reduces the result by the field 2151 modulus. 2152 2153 This function MUST NOT be used on secret inputs. 2154 */ 2155 /** 2156 A monomorphic instance of 2157 libcrux_ml_kem.serialize.deserialize_ring_elements_reduced_out with types 2158 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 2159 - K= 4 2160 */ 2161 static KRML_MUSTINLINE void 2162 deserialize_ring_elements_reduced_out_d0( 2163 Eurydice_slice public_key, 2164 libcrux_ml_kem_polynomial_PolynomialRingElement_1d ret[4U]) 2165 { 2166 libcrux_ml_kem_polynomial_PolynomialRingElement_1d deserialized_pk[4U]; 2167 KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, 2168 /* original Rust expression is not an lvalue in C */ 2169 void *lvalue = (void *)0U; 2170 deserialized_pk[i] = call_mut_0b_d0(&lvalue);); 2171 deserialize_ring_elements_reduced_d0(public_key, deserialized_pk); 2172 memcpy( 2173 ret, deserialized_pk, 2174 (size_t)4U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); 2175 } 2176 2177 /** 2178 A monomorphic instance of libcrux_ml_kem.serialize.to_unsigned_field_modulus 2179 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 2180 with const generics 2181 2182 */ 2183 static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 2184 to_unsigned_field_modulus_ea( 2185 libcrux_ml_kem_vector_portable_vector_type_PortableVector a) 2186 { 2187 return libcrux_ml_kem_vector_portable_to_unsigned_representative_b8(a); 2188 } 2189 2190 /** 2191 A monomorphic instance of 2192 libcrux_ml_kem.serialize.serialize_uncompressed_ring_element with types 2193 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 2194 2195 */ 2196 static KRML_MUSTINLINE void 2197 serialize_uncompressed_ring_element_ea( 2198 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re, uint8_t ret[384U]) 2199 { 2200 uint8_t serialized[384U] = { 0U }; 2201 for (size_t i = (size_t)0U; i < VECTORS_IN_RING_ELEMENT; i++) { 2202 size_t i0 = i; 2203 libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = 2204 to_unsigned_field_modulus_ea(re->coefficients[i0]); 2205 uint8_t bytes[24U]; 2206 libcrux_ml_kem_vector_portable_serialize_12_b8(coefficient, bytes); 2207 Eurydice_slice_copy( 2208 Eurydice_array_to_subslice3(serialized, (size_t)24U * i0, 2209 (size_t)24U * i0 + (size_t)24U, uint8_t *), 2210 Eurydice_array_to_slice((size_t)24U, bytes, uint8_t), uint8_t); 2211 } 2212 memcpy(ret, serialized, (size_t)384U * sizeof(uint8_t)); 2213 } 2214 2215 /** 2216 Call [`serialize_uncompressed_ring_element`] for each ring element. 2217 */ 2218 /** 2219 A monomorphic instance of libcrux_ml_kem.ind_cpa.serialize_vector 2220 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 2221 with const generics 2222 - K= 4 2223 */ 2224 static KRML_MUSTINLINE void 2225 serialize_vector_d0( 2226 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *key, 2227 Eurydice_slice out) 2228 { 2229 for (size_t i = (size_t)0U; 2230 i < Eurydice_slice_len( 2231 Eurydice_array_to_slice( 2232 (size_t)4U, key, 2233 libcrux_ml_kem_polynomial_PolynomialRingElement_1d), 2234 libcrux_ml_kem_polynomial_PolynomialRingElement_1d); 2235 i++) { 2236 size_t i0 = i; 2237 libcrux_ml_kem_polynomial_PolynomialRingElement_1d re = key[i0]; 2238 Eurydice_slice uu____0 = Eurydice_slice_subslice3( 2239 out, i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, 2240 (i0 + (size_t)1U) * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, 2241 uint8_t *); 2242 uint8_t ret[384U]; 2243 serialize_uncompressed_ring_element_ea(&re, ret); 2244 Eurydice_slice_copy( 2245 uu____0, Eurydice_array_to_slice((size_t)384U, ret, uint8_t), uint8_t); 2246 } 2247 } 2248 2249 /** 2250 Concatenate `t` and `ρ` into the public key. 2251 */ 2252 /** 2253 A monomorphic instance of libcrux_ml_kem.ind_cpa.serialize_public_key_mut 2254 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 2255 with const generics 2256 - K= 4 2257 - PUBLIC_KEY_SIZE= 1568 2258 */ 2259 static KRML_MUSTINLINE void 2260 serialize_public_key_mut_ff( 2261 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *t_as_ntt, 2262 Eurydice_slice seed_for_a, uint8_t *serialized) 2263 { 2264 serialize_vector_d0( 2265 t_as_ntt, 2266 Eurydice_array_to_subslice3( 2267 serialized, (size_t)0U, 2268 libcrux_ml_kem_constants_ranked_bytes_per_ring_element((size_t)4U), 2269 uint8_t *)); 2270 Eurydice_slice_copy( 2271 Eurydice_array_to_subslice_from( 2272 (size_t)1568U, serialized, 2273 libcrux_ml_kem_constants_ranked_bytes_per_ring_element((size_t)4U), 2274 uint8_t, size_t, uint8_t[]), 2275 seed_for_a, uint8_t); 2276 } 2277 2278 /** 2279 Concatenate `t` and `ρ` into the public key. 2280 */ 2281 /** 2282 A monomorphic instance of libcrux_ml_kem.ind_cpa.serialize_public_key 2283 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 2284 with const generics 2285 - K= 4 2286 - PUBLIC_KEY_SIZE= 1568 2287 */ 2288 static KRML_MUSTINLINE void 2289 serialize_public_key_ff( 2290 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *t_as_ntt, 2291 Eurydice_slice seed_for_a, uint8_t ret[1568U]) 2292 { 2293 uint8_t public_key_serialized[1568U] = { 0U }; 2294 serialize_public_key_mut_ff(t_as_ntt, seed_for_a, public_key_serialized); 2295 memcpy(ret, public_key_serialized, (size_t)1568U * sizeof(uint8_t)); 2296 } 2297 2298 /** 2299 Validate an ML-KEM public key. 2300 2301 This implements the Modulus check in 7.2 2. 2302 Note that the size check in 7.2 1 is covered by the `PUBLIC_KEY_SIZE` in the 2303 `public_key` type. 2304 */ 2305 /** 2306 A monomorphic instance of libcrux_ml_kem.ind_cca.validate_public_key 2307 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 2308 with const generics 2309 - K= 4 2310 - PUBLIC_KEY_SIZE= 1568 2311 */ 2312 bool 2313 libcrux_ml_kem_ind_cca_validate_public_key_ff(uint8_t *public_key) 2314 { 2315 libcrux_ml_kem_polynomial_PolynomialRingElement_1d deserialized_pk[4U]; 2316 deserialize_ring_elements_reduced_out_d0( 2317 Eurydice_array_to_subslice_to( 2318 (size_t)1568U, public_key, 2319 libcrux_ml_kem_constants_ranked_bytes_per_ring_element((size_t)4U), 2320 uint8_t, size_t, uint8_t[]), 2321 deserialized_pk); 2322 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *uu____0 = deserialized_pk; 2323 uint8_t public_key_serialized[1568U]; 2324 serialize_public_key_ff( 2325 uu____0, 2326 Eurydice_array_to_subslice_from( 2327 (size_t)1568U, public_key, 2328 libcrux_ml_kem_constants_ranked_bytes_per_ring_element((size_t)4U), 2329 uint8_t, size_t, uint8_t[]), 2330 public_key_serialized); 2331 return Eurydice_array_eq((size_t)1568U, public_key, public_key_serialized, 2332 uint8_t); 2333 } 2334 2335 /** 2336 This function found in impl {libcrux_ml_kem::hash_functions::Hash<K> for 2337 libcrux_ml_kem::hash_functions::portable::PortableHash<K>} 2338 */ 2339 /** 2340 A monomorphic instance of libcrux_ml_kem.hash_functions.portable.H_4a 2341 with const generics 2342 - K= 4 2343 */ 2344 static inline void 2345 H_4a_ac(Eurydice_slice input, uint8_t ret[32U]) 2346 { 2347 libcrux_ml_kem_hash_functions_portable_H(input, ret); 2348 } 2349 2350 /** 2351 Validate an ML-KEM private key. 2352 2353 This implements the Hash check in 7.3 3. 2354 */ 2355 /** 2356 A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key_only 2357 with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] 2358 with const generics 2359 - K= 4 2360 - SECRET_KEY_SIZE= 3168 2361 */ 2362 bool 2363 libcrux_ml_kem_ind_cca_validate_private_key_only_60( 2364 libcrux_ml_kem_types_MlKemPrivateKey_83 *private_key) 2365 { 2366 uint8_t t[32U]; 2367 H_4a_ac(Eurydice_array_to_subslice3( 2368 private_key->value, (size_t)384U * (size_t)4U, 2369 (size_t)768U * (size_t)4U + (size_t)32U, uint8_t *), 2370 t); 2371 Eurydice_slice expected = Eurydice_array_to_subslice3( 2372 private_key->value, (size_t)768U * (size_t)4U + (size_t)32U, 2373 (size_t)768U * (size_t)4U + (size_t)64U, uint8_t *); 2374 return Eurydice_array_eq_slice((size_t)32U, t, &expected, uint8_t, bool); 2375 } 2376 2377 /** 2378 Validate an ML-KEM private key. 2379 2380 This implements the Hash check in 7.3 3. 2381 Note that the size checks in 7.2 1 and 2 are covered by the `SECRET_KEY_SIZE` 2382 and `CIPHERTEXT_SIZE` in the `private_key` and `ciphertext` types. 2383 */ 2384 /** 2385 A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key 2386 with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] 2387 with const generics 2388 - K= 4 2389 - SECRET_KEY_SIZE= 3168 2390 - CIPHERTEXT_SIZE= 1568 2391 */ 2392 bool 2393 libcrux_ml_kem_ind_cca_validate_private_key_b5( 2394 libcrux_ml_kem_types_MlKemPrivateKey_83 *private_key, 2395 libcrux_ml_kem_types_MlKemCiphertext_64 *_ciphertext) 2396 { 2397 return libcrux_ml_kem_ind_cca_validate_private_key_only_60(private_key); 2398 } 2399 2400 /** 2401 A monomorphic instance of 2402 libcrux_ml_kem.ind_cpa.unpacked.IndCpaPrivateKeyUnpacked with types 2403 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 2404 - $4size_t 2405 */ 2406 typedef struct IndCpaPrivateKeyUnpacked_af_s { 2407 libcrux_ml_kem_polynomial_PolynomialRingElement_1d secret_as_ntt[4U]; 2408 } IndCpaPrivateKeyUnpacked_af; 2409 2410 /** 2411 This function found in impl {core::default::Default for 2412 libcrux_ml_kem::ind_cpa::unpacked::IndCpaPrivateKeyUnpacked<Vector, 2413 K>[TraitClause@0, TraitClause@1]} 2414 */ 2415 /** 2416 A monomorphic instance of libcrux_ml_kem.ind_cpa.unpacked.default_70 2417 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 2418 with const generics 2419 - K= 4 2420 */ 2421 static IndCpaPrivateKeyUnpacked_af 2422 default_70_d0(void) 2423 { 2424 IndCpaPrivateKeyUnpacked_af lit; 2425 libcrux_ml_kem_polynomial_PolynomialRingElement_1d repeat_expression[4U]; 2426 KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, 2427 repeat_expression[i] = ZERO_d6_ea();); 2428 memcpy( 2429 lit.secret_as_ntt, repeat_expression, 2430 (size_t)4U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); 2431 return lit; 2432 } 2433 2434 /** 2435 A monomorphic instance of 2436 libcrux_ml_kem.ind_cpa.unpacked.IndCpaPublicKeyUnpacked with types 2437 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 2438 - $4size_t 2439 */ 2440 typedef struct IndCpaPublicKeyUnpacked_af_s { 2441 libcrux_ml_kem_polynomial_PolynomialRingElement_1d t_as_ntt[4U]; 2442 uint8_t seed_for_A[32U]; 2443 libcrux_ml_kem_polynomial_PolynomialRingElement_1d A[4U][4U]; 2444 } IndCpaPublicKeyUnpacked_af; 2445 2446 /** 2447 This function found in impl {core::default::Default for 2448 libcrux_ml_kem::ind_cpa::unpacked::IndCpaPublicKeyUnpacked<Vector, 2449 K>[TraitClause@0, TraitClause@1]} 2450 */ 2451 /** 2452 A monomorphic instance of libcrux_ml_kem.ind_cpa.unpacked.default_8b 2453 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 2454 with const generics 2455 - K= 4 2456 */ 2457 static IndCpaPublicKeyUnpacked_af 2458 default_8b_d0(void) 2459 { 2460 libcrux_ml_kem_polynomial_PolynomialRingElement_1d uu____0[4U]; 2461 KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, 2462 uu____0[i] = ZERO_d6_ea();); 2463 uint8_t uu____1[32U] = { 0U }; 2464 IndCpaPublicKeyUnpacked_af lit; 2465 memcpy( 2466 lit.t_as_ntt, uu____0, 2467 (size_t)4U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); 2468 memcpy(lit.seed_for_A, uu____1, (size_t)32U * sizeof(uint8_t)); 2469 libcrux_ml_kem_polynomial_PolynomialRingElement_1d repeat_expression0[4U][4U]; 2470 KRML_MAYBE_FOR4( 2471 i0, (size_t)0U, (size_t)4U, (size_t)1U, 2472 libcrux_ml_kem_polynomial_PolynomialRingElement_1d repeat_expression[4U]; 2473 KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, 2474 repeat_expression[i] = ZERO_d6_ea();); 2475 memcpy(repeat_expression0[i0], repeat_expression, 2476 (size_t)4U * 2477 sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d));); 2478 memcpy(lit.A, repeat_expression0, 2479 (size_t)4U * 2480 sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d[4U])); 2481 return lit; 2482 } 2483 2484 /** 2485 This function found in impl {libcrux_ml_kem::hash_functions::Hash<K> for 2486 libcrux_ml_kem::hash_functions::portable::PortableHash<K>} 2487 */ 2488 /** 2489 A monomorphic instance of libcrux_ml_kem.hash_functions.portable.G_4a 2490 with const generics 2491 - K= 4 2492 */ 2493 static inline void 2494 G_4a_ac(Eurydice_slice input, uint8_t ret[64U]) 2495 { 2496 libcrux_ml_kem_hash_functions_portable_G(input, ret); 2497 } 2498 2499 /** 2500 This function found in impl {libcrux_ml_kem::variant::Variant for 2501 libcrux_ml_kem::variant::MlKem} 2502 */ 2503 /** 2504 A monomorphic instance of libcrux_ml_kem.variant.cpa_keygen_seed_39 2505 with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] 2506 with const generics 2507 - K= 4 2508 */ 2509 static KRML_MUSTINLINE void 2510 cpa_keygen_seed_39_03( 2511 Eurydice_slice key_generation_seed, uint8_t ret[64U]) 2512 { 2513 uint8_t seed[33U] = { 0U }; 2514 Eurydice_slice_copy( 2515 Eurydice_array_to_subslice3( 2516 seed, (size_t)0U, 2517 LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t *), 2518 key_generation_seed, uint8_t); 2519 seed[LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE] = 2520 (uint8_t)(size_t)4U; 2521 uint8_t ret0[64U]; 2522 G_4a_ac(Eurydice_array_to_slice((size_t)33U, seed, uint8_t), ret0); 2523 memcpy(ret, ret0, (size_t)64U * sizeof(uint8_t)); 2524 } 2525 2526 /** 2527 A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PortableHash 2528 with const generics 2529 - $4size_t 2530 */ 2531 typedef struct PortableHash_44_s { 2532 libcrux_sha3_generic_keccak_KeccakState_17 shake128_state[4U]; 2533 } PortableHash_44; 2534 2535 /** 2536 A monomorphic instance of 2537 libcrux_ml_kem.hash_functions.portable.shake128_init_absorb_final with const 2538 generics 2539 - K= 4 2540 */ 2541 static inline PortableHash_44 2542 shake128_init_absorb_final_ac( 2543 uint8_t (*input)[34U]) 2544 { 2545 PortableHash_44 shake128_state; 2546 libcrux_sha3_generic_keccak_KeccakState_17 repeat_expression[4U]; 2547 KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, 2548 repeat_expression[i] = 2549 libcrux_sha3_portable_incremental_shake128_init();); 2550 memcpy(shake128_state.shake128_state, repeat_expression, 2551 (size_t)4U * sizeof(libcrux_sha3_generic_keccak_KeccakState_17)); 2552 KRML_MAYBE_FOR4( 2553 i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; 2554 libcrux_sha3_portable_incremental_shake128_absorb_final( 2555 &shake128_state.shake128_state[i0], 2556 Eurydice_array_to_slice((size_t)34U, input[i0], uint8_t));); 2557 return shake128_state; 2558 } 2559 2560 /** 2561 This function found in impl {libcrux_ml_kem::hash_functions::Hash<K> for 2562 libcrux_ml_kem::hash_functions::portable::PortableHash<K>} 2563 */ 2564 /** 2565 A monomorphic instance of 2566 libcrux_ml_kem.hash_functions.portable.shake128_init_absorb_final_4a with const 2567 generics 2568 - K= 4 2569 */ 2570 static inline PortableHash_44 2571 shake128_init_absorb_final_4a_ac( 2572 uint8_t (*input)[34U]) 2573 { 2574 return shake128_init_absorb_final_ac(input); 2575 } 2576 2577 /** 2578 A monomorphic instance of 2579 libcrux_ml_kem.hash_functions.portable.shake128_squeeze_first_three_blocks with 2580 const generics 2581 - K= 4 2582 */ 2583 static inline void 2584 shake128_squeeze_first_three_blocks_ac( 2585 PortableHash_44 *st, uint8_t ret[4U][504U]) 2586 { 2587 uint8_t out[4U][504U] = { { 0U } }; 2588 KRML_MAYBE_FOR4( 2589 i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; 2590 libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks( 2591 &st->shake128_state[i0], 2592 Eurydice_array_to_slice((size_t)504U, out[i0], uint8_t));); 2593 memcpy(ret, out, (size_t)4U * sizeof(uint8_t[504U])); 2594 } 2595 2596 /** 2597 This function found in impl {libcrux_ml_kem::hash_functions::Hash<K> for 2598 libcrux_ml_kem::hash_functions::portable::PortableHash<K>} 2599 */ 2600 /** 2601 A monomorphic instance of 2602 libcrux_ml_kem.hash_functions.portable.shake128_squeeze_first_three_blocks_4a 2603 with const generics 2604 - K= 4 2605 */ 2606 static inline void 2607 shake128_squeeze_first_three_blocks_4a_ac( 2608 PortableHash_44 *self, uint8_t ret[4U][504U]) 2609 { 2610 shake128_squeeze_first_three_blocks_ac(self, ret); 2611 } 2612 2613 /** 2614 If `bytes` contains a set of uniformly random bytes, this function 2615 uniformly samples a ring element `â` that is treated as being the NTT 2616 representation of the corresponding polynomial `a`. 2617 2618 Since rejection sampling is used, it is possible the supplied bytes are 2619 not enough to sample the element, in which case an `Err` is returned and the 2620 caller must try again with a fresh set of bytes. 2621 2622 This function <strong>partially</strong> implements <strong>Algorithm 2623 6</strong> of the NIST FIPS 203 standard, We say "partially" because this 2624 implementation only accepts a finite set of bytes as input and returns an error 2625 if the set is not enough; Algorithm 6 of the FIPS 203 standard on the other 2626 hand samples from an infinite stream of bytes until the ring element is filled. 2627 Algorithm 6 is reproduced below: 2628 2629 ```plaintext 2630 Input: byte stream B ∈ 𝔹*. 2631 Output: array â ∈ ℤ₂₅₆. 2632 2633 i ← 0 2634 j ← 0 2635 while j < 256 do 2636 d₁ ← B[i] + 256·(B[i+1] mod 16) 2637 d₂ ← ⌊B[i+1]/16⌋ + 16·B[i+2] 2638 if d₁ < q then 2639 â[j] ← d₁ 2640 j ← j + 1 2641 end if 2642 if d₂ < q and j < 256 then 2643 â[j] ← d₂ 2644 j ← j + 1 2645 end if 2646 i ← i + 3 2647 end while 2648 return â 2649 ``` 2650 2651 The NIST FIPS 203 standard can be found at 2652 <https://csrc.nist.gov/pubs/fips/203/ipd>. 2653 */ 2654 /** 2655 A monomorphic instance of 2656 libcrux_ml_kem.sampling.sample_from_uniform_distribution_next with types 2657 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 2658 - K= 4 2659 - N= 504 2660 */ 2661 static KRML_MUSTINLINE bool 2662 sample_from_uniform_distribution_next_ff( 2663 uint8_t (*randomness)[504U], size_t *sampled_coefficients, 2664 int16_t (*out)[272U]) 2665 { 2666 KRML_MAYBE_FOR4( 2667 i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; 2668 for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { 2669 size_t r = i; 2670 if (sampled_coefficients[i1] < 2671 LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { 2672 size_t sampled = libcrux_ml_kem_vector_portable_rej_sample_b8( 2673 Eurydice_array_to_subslice3(randomness[i1], r * (size_t)24U, 2674 r * (size_t)24U + (size_t)24U, 2675 uint8_t *), 2676 Eurydice_array_to_subslice3( 2677 out[i1], sampled_coefficients[i1], 2678 sampled_coefficients[i1] + (size_t)16U, int16_t *)); 2679 size_t uu____0 = i1; 2680 sampled_coefficients[uu____0] = 2681 sampled_coefficients[uu____0] + sampled; 2682 } 2683 }); 2684 bool done = true; 2685 KRML_MAYBE_FOR4( 2686 i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; 2687 if (sampled_coefficients[i0] >= 2688 LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { 2689 sampled_coefficients[i0] = 2690 LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; 2691 } else { done = false; }); 2692 return done; 2693 } 2694 2695 /** 2696 A monomorphic instance of 2697 libcrux_ml_kem.hash_functions.portable.shake128_squeeze_next_block with const 2698 generics 2699 - K= 4 2700 */ 2701 static inline void 2702 shake128_squeeze_next_block_ac(PortableHash_44 *st, 2703 uint8_t ret[4U][168U]) 2704 { 2705 uint8_t out[4U][168U] = { { 0U } }; 2706 KRML_MAYBE_FOR4( 2707 i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; 2708 libcrux_sha3_portable_incremental_shake128_squeeze_next_block( 2709 &st->shake128_state[i0], 2710 Eurydice_array_to_slice((size_t)168U, out[i0], uint8_t));); 2711 memcpy(ret, out, (size_t)4U * sizeof(uint8_t[168U])); 2712 } 2713 2714 /** 2715 This function found in impl {libcrux_ml_kem::hash_functions::Hash<K> for 2716 libcrux_ml_kem::hash_functions::portable::PortableHash<K>} 2717 */ 2718 /** 2719 A monomorphic instance of 2720 libcrux_ml_kem.hash_functions.portable.shake128_squeeze_next_block_4a with const 2721 generics 2722 - K= 4 2723 */ 2724 static inline void 2725 shake128_squeeze_next_block_4a_ac(PortableHash_44 *self, 2726 uint8_t ret[4U][168U]) 2727 { 2728 shake128_squeeze_next_block_ac(self, ret); 2729 } 2730 2731 /** 2732 If `bytes` contains a set of uniformly random bytes, this function 2733 uniformly samples a ring element `â` that is treated as being the NTT 2734 representation of the corresponding polynomial `a`. 2735 2736 Since rejection sampling is used, it is possible the supplied bytes are 2737 not enough to sample the element, in which case an `Err` is returned and the 2738 caller must try again with a fresh set of bytes. 2739 2740 This function <strong>partially</strong> implements <strong>Algorithm 2741 6</strong> of the NIST FIPS 203 standard, We say "partially" because this 2742 implementation only accepts a finite set of bytes as input and returns an error 2743 if the set is not enough; Algorithm 6 of the FIPS 203 standard on the other 2744 hand samples from an infinite stream of bytes until the ring element is filled. 2745 Algorithm 6 is reproduced below: 2746 2747 ```plaintext 2748 Input: byte stream B ∈ 𝔹*. 2749 Output: array â ∈ ℤ₂₅₆. 2750 2751 i ← 0 2752 j ← 0 2753 while j < 256 do 2754 d₁ ← B[i] + 256·(B[i+1] mod 16) 2755 d₂ ← ⌊B[i+1]/16⌋ + 16·B[i+2] 2756 if d₁ < q then 2757 â[j] ← d₁ 2758 j ← j + 1 2759 end if 2760 if d₂ < q and j < 256 then 2761 â[j] ← d₂ 2762 j ← j + 1 2763 end if 2764 i ← i + 3 2765 end while 2766 return â 2767 ``` 2768 2769 The NIST FIPS 203 standard can be found at 2770 <https://csrc.nist.gov/pubs/fips/203/ipd>. 2771 */ 2772 /** 2773 A monomorphic instance of 2774 libcrux_ml_kem.sampling.sample_from_uniform_distribution_next with types 2775 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 2776 - K= 4 2777 - N= 168 2778 */ 2779 static KRML_MUSTINLINE bool 2780 sample_from_uniform_distribution_next_ff0( 2781 uint8_t (*randomness)[168U], size_t *sampled_coefficients, 2782 int16_t (*out)[272U]) 2783 { 2784 KRML_MAYBE_FOR4( 2785 i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; 2786 for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { 2787 size_t r = i; 2788 if (sampled_coefficients[i1] < 2789 LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { 2790 size_t sampled = libcrux_ml_kem_vector_portable_rej_sample_b8( 2791 Eurydice_array_to_subslice3(randomness[i1], r * (size_t)24U, 2792 r * (size_t)24U + (size_t)24U, 2793 uint8_t *), 2794 Eurydice_array_to_subslice3( 2795 out[i1], sampled_coefficients[i1], 2796 sampled_coefficients[i1] + (size_t)16U, int16_t *)); 2797 size_t uu____0 = i1; 2798 sampled_coefficients[uu____0] = 2799 sampled_coefficients[uu____0] + sampled; 2800 } 2801 }); 2802 bool done = true; 2803 KRML_MAYBE_FOR4( 2804 i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; 2805 if (sampled_coefficients[i0] >= 2806 LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { 2807 sampled_coefficients[i0] = 2808 LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; 2809 } else { done = false; }); 2810 return done; 2811 } 2812 2813 /** 2814 A monomorphic instance of libcrux_ml_kem.polynomial.ZERO 2815 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 2816 with const generics 2817 2818 */ 2819 static libcrux_ml_kem_polynomial_PolynomialRingElement_1d 2820 ZERO_ea(void) 2821 { 2822 libcrux_ml_kem_polynomial_PolynomialRingElement_1d lit; 2823 libcrux_ml_kem_vector_portable_vector_type_PortableVector 2824 repeat_expression[16U]; 2825 KRML_MAYBE_FOR16( 2826 i, (size_t)0U, (size_t)16U, (size_t)1U, 2827 repeat_expression[i] = libcrux_ml_kem_vector_portable_ZERO_b8();); 2828 memcpy(lit.coefficients, repeat_expression, 2829 (size_t)16U * 2830 sizeof(libcrux_ml_kem_vector_portable_vector_type_PortableVector)); 2831 return lit; 2832 } 2833 2834 /** 2835 A monomorphic instance of libcrux_ml_kem.polynomial.from_i16_array 2836 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 2837 with const generics 2838 2839 */ 2840 static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d 2841 from_i16_array_ea(Eurydice_slice a) 2842 { 2843 libcrux_ml_kem_polynomial_PolynomialRingElement_1d result = ZERO_ea(); 2844 for (size_t i = (size_t)0U; i < VECTORS_IN_RING_ELEMENT; i++) { 2845 size_t i0 = i; 2846 libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = 2847 libcrux_ml_kem_vector_portable_from_i16_array_b8( 2848 Eurydice_slice_subslice3(a, i0 * (size_t)16U, 2849 (i0 + (size_t)1U) * (size_t)16U, 2850 int16_t *)); 2851 result.coefficients[i0] = uu____0; 2852 } 2853 return result; 2854 } 2855 2856 /** 2857 This function found in impl 2858 {libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0, 2859 TraitClause@1]} 2860 */ 2861 /** 2862 A monomorphic instance of libcrux_ml_kem.polynomial.from_i16_array_d6 2863 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 2864 with const generics 2865 2866 */ 2867 static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d 2868 from_i16_array_d6_ea(Eurydice_slice a) 2869 { 2870 return from_i16_array_ea(a); 2871 } 2872 2873 /** 2874 This function found in impl {core::ops::function::FnMut<(@Array<i16, 272usize>), 2875 libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0, 2876 TraitClause@2]> for libcrux_ml_kem::sampling::sample_from_xof::closure<Vector, 2877 Hasher, K>[TraitClause@0, TraitClause@1, TraitClause@2, TraitClause@3]} 2878 */ 2879 /** 2880 A monomorphic instance of libcrux_ml_kem.sampling.sample_from_xof.call_mut_e7 2881 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 2882 libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] with const 2883 generics 2884 - K= 4 2885 */ 2886 static libcrux_ml_kem_polynomial_PolynomialRingElement_1d 2887 call_mut_e7_2b( 2888 int16_t tupled_args[272U]) 2889 { 2890 int16_t s[272U]; 2891 memcpy(s, tupled_args, (size_t)272U * sizeof(int16_t)); 2892 return from_i16_array_d6_ea( 2893 Eurydice_array_to_subslice3(s, (size_t)0U, (size_t)256U, int16_t *)); 2894 } 2895 2896 /** 2897 A monomorphic instance of libcrux_ml_kem.sampling.sample_from_xof 2898 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 2899 libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] with const 2900 generics 2901 - K= 4 2902 */ 2903 static KRML_MUSTINLINE void 2904 sample_from_xof_2b( 2905 uint8_t (*seeds)[34U], 2906 libcrux_ml_kem_polynomial_PolynomialRingElement_1d ret[4U]) 2907 { 2908 size_t sampled_coefficients[4U] = { 0U }; 2909 int16_t out[4U][272U] = { { 0U } }; 2910 PortableHash_44 xof_state = shake128_init_absorb_final_4a_ac(seeds); 2911 uint8_t randomness0[4U][504U]; 2912 shake128_squeeze_first_three_blocks_4a_ac(&xof_state, randomness0); 2913 bool done = sample_from_uniform_distribution_next_ff( 2914 randomness0, sampled_coefficients, out); 2915 while (true) { 2916 if (done) { 2917 break; 2918 } else { 2919 uint8_t randomness[4U][168U]; 2920 shake128_squeeze_next_block_4a_ac(&xof_state, randomness); 2921 done = sample_from_uniform_distribution_next_ff0( 2922 randomness, sampled_coefficients, out); 2923 } 2924 } 2925 /* Passing arrays by value in Rust generates a copy in C */ 2926 int16_t copy_of_out[4U][272U]; 2927 memcpy(copy_of_out, out, (size_t)4U * sizeof(int16_t[272U])); 2928 libcrux_ml_kem_polynomial_PolynomialRingElement_1d ret0[4U]; 2929 KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, 2930 ret0[i] = call_mut_e7_2b(copy_of_out[i]);); 2931 memcpy( 2932 ret, ret0, 2933 (size_t)4U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); 2934 } 2935 2936 /** 2937 A monomorphic instance of libcrux_ml_kem.matrix.sample_matrix_A 2938 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 2939 libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] with const 2940 generics 2941 - K= 4 2942 */ 2943 static KRML_MUSTINLINE void 2944 sample_matrix_A_2b( 2945 libcrux_ml_kem_polynomial_PolynomialRingElement_1d (*A_transpose)[4U], 2946 uint8_t *seed, bool transpose) 2947 { 2948 KRML_MAYBE_FOR4( 2949 i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0; 2950 uint8_t seeds[4U][34U]; 2951 KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, 2952 core_array__core__clone__Clone_for__Array_T__N___clone( 2953 (size_t)34U, seed, seeds[i], uint8_t, void *);); 2954 KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t j = i; 2955 seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); 2956 libcrux_ml_kem_polynomial_PolynomialRingElement_1d sampled[4U]; 2957 sample_from_xof_2b(seeds, sampled); 2958 for (size_t i = (size_t)0U; 2959 i < Eurydice_slice_len( 2960 Eurydice_array_to_slice( 2961 (size_t)4U, sampled, 2962 libcrux_ml_kem_polynomial_PolynomialRingElement_1d), 2963 libcrux_ml_kem_polynomial_PolynomialRingElement_1d); 2964 i++) { 2965 size_t j = i; 2966 libcrux_ml_kem_polynomial_PolynomialRingElement_1d sample = sampled[j]; 2967 if (transpose) { 2968 A_transpose[j][i1] = sample; 2969 } else { 2970 A_transpose[i1][j] = sample; 2971 } 2972 }); 2973 } 2974 2975 /** 2976 A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRFxN 2977 with const generics 2978 - K= 4 2979 - LEN= 128 2980 */ 2981 static inline void 2982 PRFxN_44(uint8_t (*input)[33U], uint8_t ret[4U][128U]) 2983 { 2984 uint8_t out[4U][128U] = { { 0U } }; 2985 KRML_MAYBE_FOR4( 2986 i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; 2987 libcrux_sha3_portable_shake256( 2988 Eurydice_array_to_slice((size_t)128U, out[i0], uint8_t), 2989 Eurydice_array_to_slice((size_t)33U, input[i0], uint8_t));); 2990 memcpy(ret, out, (size_t)4U * sizeof(uint8_t[128U])); 2991 } 2992 2993 /** 2994 This function found in impl {libcrux_ml_kem::hash_functions::Hash<K> for 2995 libcrux_ml_kem::hash_functions::portable::PortableHash<K>} 2996 */ 2997 /** 2998 A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRFxN_4a 2999 with const generics 3000 - K= 4 3001 - LEN= 128 3002 */ 3003 static inline void 3004 PRFxN_4a_44(uint8_t (*input)[33U], uint8_t ret[4U][128U]) 3005 { 3006 PRFxN_44(input, ret); 3007 } 3008 3009 /** 3010 Given a series of uniformly random bytes in `randomness`, for some number 3011 `eta`, the `sample_from_binomial_distribution_{eta}` functions sample a ring 3012 element from a binomial distribution centered at 0 that uses two sets of `eta` 3013 coin flips. If, for example, `eta = ETA`, each ring coefficient is a value `v` 3014 such such that `v ∈ {-ETA, -ETA + 1, ..., 0, ..., ETA + 1, ETA}` and: 3015 3016 ```plaintext 3017 - If v < 0, Pr[v] = Pr[-v] 3018 - If v >= 0, Pr[v] = BINOMIAL_COEFFICIENT(2 * ETA; ETA - v) / 2 ^ (2 * ETA) 3019 ``` 3020 3021 The values `v < 0` are mapped to the appropriate `KyberFieldElement`. 3022 3023 The expected value is: 3024 3025 ```plaintext 3026 E[X] = (-ETA)Pr[-ETA] + (-(ETA - 1))Pr[-(ETA - 1)] + ... + (ETA - 1)Pr[ETA - 1] 3027 + (ETA)Pr[ETA] = 0 since Pr[-v] = Pr[v] when v < 0. 3028 ``` 3029 3030 And the variance is: 3031 3032 ```plaintext 3033 Var(X) = E[(X - E[X])^2] 3034 = E[X^2] 3035 = sum_(v=-ETA to ETA)v^2 * (BINOMIAL_COEFFICIENT(2 * ETA; ETA - v) / 3036 2^(2 * ETA)) = ETA / 2 3037 ``` 3038 3039 This function implements <strong>Algorithm 7</strong> of the NIST FIPS 203 3040 standard, which is reproduced below: 3041 3042 ```plaintext 3043 Input: byte array B ∈ 𝔹^{64η}. 3044 Output: array f ∈ ℤ₂₅₆. 3045 3046 b ← BytesToBits(B) 3047 for (i ← 0; i < 256; i++) 3048 x ← ∑(j=0 to η - 1) b[2iη + j] 3049 y ← ∑(j=0 to η - 1) b[2iη + η + j] 3050 f[i] ← x−y mod q 3051 end for 3052 return f 3053 ``` 3054 3055 The NIST FIPS 203 standard can be found at 3056 <https://csrc.nist.gov/pubs/fips/203/ipd>. 3057 */ 3058 /** 3059 A monomorphic instance of 3060 libcrux_ml_kem.sampling.sample_from_binomial_distribution_2 with types 3061 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 3062 3063 */ 3064 static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d 3065 sample_from_binomial_distribution_2_ea(Eurydice_slice randomness) 3066 { 3067 int16_t sampled_i16s[256U] = { 0U }; 3068 for (size_t i0 = (size_t)0U; 3069 i0 < Eurydice_slice_len(randomness, uint8_t) / (size_t)4U; i0++) { 3070 size_t chunk_number = i0; 3071 Eurydice_slice byte_chunk = Eurydice_slice_subslice3( 3072 randomness, chunk_number * (size_t)4U, 3073 chunk_number * (size_t)4U + (size_t)4U, uint8_t *); 3074 uint32_t random_bits_as_u32 = 3075 (((uint32_t)Eurydice_slice_index(byte_chunk, (size_t)0U, uint8_t, 3076 uint8_t *) | 3077 (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, uint8_t, 3078 uint8_t *) 3079 << 8U) | 3080 (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, uint8_t, 3081 uint8_t *) 3082 << 16U) | 3083 (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)3U, uint8_t, 3084 uint8_t *) 3085 << 24U; 3086 uint32_t even_bits = random_bits_as_u32 & 1431655765U; 3087 uint32_t odd_bits = random_bits_as_u32 >> 1U & 1431655765U; 3088 uint32_t coin_toss_outcomes = even_bits + odd_bits; 3089 for (uint32_t i = 0U; i < 32U / 4U; i++) { 3090 uint32_t outcome_set = i; 3091 uint32_t outcome_set0 = outcome_set * 4U; 3092 int16_t outcome_1 = 3093 (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 3U); 3094 int16_t outcome_2 = 3095 (int16_t)(coin_toss_outcomes >> (uint32_t)(outcome_set0 + 2U) & 3U); 3096 size_t offset = (size_t)(outcome_set0 >> 2U); 3097 sampled_i16s[(size_t)8U * chunk_number + offset] = outcome_1 - outcome_2; 3098 } 3099 } 3100 return from_i16_array_d6_ea( 3101 Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t)); 3102 } 3103 3104 /** 3105 A monomorphic instance of 3106 libcrux_ml_kem.sampling.sample_from_binomial_distribution with types 3107 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 3108 - ETA= 2 3109 */ 3110 static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d 3111 sample_from_binomial_distribution_a0(Eurydice_slice randomness) 3112 { 3113 return sample_from_binomial_distribution_2_ea(randomness); 3114 } 3115 3116 /** 3117 A monomorphic instance of libcrux_ml_kem.ntt.ntt_at_layer_7 3118 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 3119 with const generics 3120 3121 */ 3122 static KRML_MUSTINLINE void 3123 ntt_at_layer_7_ea( 3124 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re) 3125 { 3126 size_t step = VECTORS_IN_RING_ELEMENT / (size_t)2U; 3127 for (size_t i = (size_t)0U; i < step; i++) { 3128 size_t j = i; 3129 libcrux_ml_kem_vector_portable_vector_type_PortableVector t = 3130 libcrux_ml_kem_vector_portable_multiply_by_constant_b8( 3131 re->coefficients[j + step], (int16_t)-1600); 3132 re->coefficients[j + step] = 3133 libcrux_ml_kem_vector_portable_sub_b8(re->coefficients[j], &t); 3134 libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____1 = 3135 libcrux_ml_kem_vector_portable_add_b8(re->coefficients[j], &t); 3136 re->coefficients[j] = uu____1; 3137 } 3138 } 3139 3140 typedef struct libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2_s { 3141 libcrux_ml_kem_vector_portable_vector_type_PortableVector fst; 3142 libcrux_ml_kem_vector_portable_vector_type_PortableVector snd; 3143 } libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2; 3144 3145 /** 3146 A monomorphic instance of libcrux_ml_kem.ntt.ntt_layer_int_vec_step 3147 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 3148 with const generics 3149 3150 */ 3151 static KRML_MUSTINLINE 3152 libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2 3153 ntt_layer_int_vec_step_ea( 3154 libcrux_ml_kem_vector_portable_vector_type_PortableVector a, 3155 libcrux_ml_kem_vector_portable_vector_type_PortableVector b, 3156 int16_t zeta_r) 3157 { 3158 libcrux_ml_kem_vector_portable_vector_type_PortableVector t = 3159 libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_b8(b, 3160 zeta_r); 3161 b = libcrux_ml_kem_vector_portable_sub_b8(a, &t); 3162 a = libcrux_ml_kem_vector_portable_add_b8(a, &t); 3163 return (KRML_CLITERAL( 3164 libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2){ .fst = a, 3165 .snd = b }); 3166 } 3167 3168 /** 3169 A monomorphic instance of libcrux_ml_kem.ntt.ntt_at_layer_4_plus 3170 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 3171 with const generics 3172 3173 */ 3174 static KRML_MUSTINLINE void 3175 ntt_at_layer_4_plus_ea( 3176 size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re, 3177 size_t layer) 3178 { 3179 size_t step = (size_t)1U << (uint32_t)layer; 3180 for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { 3181 size_t round = i0; 3182 zeta_i[0U] = zeta_i[0U] + (size_t)1U; 3183 size_t offset = round * step * (size_t)2U; 3184 size_t offset_vec = offset / (size_t)16U; 3185 size_t step_vec = step / (size_t)16U; 3186 for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { 3187 size_t j = i; 3188 libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2 uu____0 = 3189 ntt_layer_int_vec_step_ea(re->coefficients[j], 3190 re->coefficients[j + step_vec], 3191 zeta(zeta_i[0U])); 3192 libcrux_ml_kem_vector_portable_vector_type_PortableVector x = uu____0.fst; 3193 libcrux_ml_kem_vector_portable_vector_type_PortableVector y = uu____0.snd; 3194 re->coefficients[j] = x; 3195 re->coefficients[j + step_vec] = y; 3196 } 3197 } 3198 } 3199 3200 /** 3201 A monomorphic instance of libcrux_ml_kem.ntt.ntt_at_layer_3 3202 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 3203 with const generics 3204 3205 */ 3206 static KRML_MUSTINLINE void 3207 ntt_at_layer_3_ea( 3208 size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re) 3209 { 3210 KRML_MAYBE_FOR16( 3211 i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; 3212 zeta_i[0U] = zeta_i[0U] + (size_t)1U; 3213 libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = 3214 libcrux_ml_kem_vector_portable_ntt_layer_3_step_b8( 3215 re->coefficients[round], zeta(zeta_i[0U])); 3216 re->coefficients[round] = uu____0;); 3217 } 3218 3219 /** 3220 A monomorphic instance of libcrux_ml_kem.ntt.ntt_at_layer_2 3221 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 3222 with const generics 3223 3224 */ 3225 static KRML_MUSTINLINE void 3226 ntt_at_layer_2_ea( 3227 size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re) 3228 { 3229 KRML_MAYBE_FOR16(i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; 3230 zeta_i[0U] = zeta_i[0U] + (size_t)1U; 3231 re->coefficients[round] = 3232 libcrux_ml_kem_vector_portable_ntt_layer_2_step_b8( 3233 re->coefficients[round], zeta(zeta_i[0U]), 3234 zeta(zeta_i[0U] + (size_t)1U)); 3235 zeta_i[0U] = zeta_i[0U] + (size_t)1U;); 3236 } 3237 3238 /** 3239 A monomorphic instance of libcrux_ml_kem.ntt.ntt_at_layer_1 3240 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 3241 with const generics 3242 3243 */ 3244 static KRML_MUSTINLINE void 3245 ntt_at_layer_1_ea( 3246 size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re) 3247 { 3248 KRML_MAYBE_FOR16( 3249 i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; 3250 zeta_i[0U] = zeta_i[0U] + (size_t)1U; 3251 re->coefficients[round] = 3252 libcrux_ml_kem_vector_portable_ntt_layer_1_step_b8( 3253 re->coefficients[round], zeta(zeta_i[0U]), 3254 zeta(zeta_i[0U] + (size_t)1U), zeta(zeta_i[0U] + (size_t)2U), 3255 zeta(zeta_i[0U] + (size_t)3U)); 3256 zeta_i[0U] = zeta_i[0U] + (size_t)3U;); 3257 } 3258 3259 /** 3260 A monomorphic instance of libcrux_ml_kem.polynomial.poly_barrett_reduce 3261 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 3262 with const generics 3263 3264 */ 3265 static KRML_MUSTINLINE void 3266 poly_barrett_reduce_ea( 3267 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *myself) 3268 { 3269 for (size_t i = (size_t)0U; i < VECTORS_IN_RING_ELEMENT; i++) { 3270 size_t i0 = i; 3271 libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = 3272 libcrux_ml_kem_vector_portable_barrett_reduce_b8( 3273 myself->coefficients[i0]); 3274 myself->coefficients[i0] = uu____0; 3275 } 3276 } 3277 3278 /** 3279 This function found in impl 3280 {libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0, 3281 TraitClause@1]} 3282 */ 3283 /** 3284 A monomorphic instance of libcrux_ml_kem.polynomial.poly_barrett_reduce_d6 3285 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 3286 with const generics 3287 3288 */ 3289 static KRML_MUSTINLINE void 3290 poly_barrett_reduce_d6_ea( 3291 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *self) 3292 { 3293 poly_barrett_reduce_ea(self); 3294 } 3295 3296 /** 3297 A monomorphic instance of libcrux_ml_kem.ntt.ntt_binomially_sampled_ring_element 3298 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 3299 with const generics 3300 3301 */ 3302 static KRML_MUSTINLINE void 3303 ntt_binomially_sampled_ring_element_ea( 3304 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re) 3305 { 3306 ntt_at_layer_7_ea(re); 3307 size_t zeta_i = (size_t)1U; 3308 ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)6U); 3309 ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)5U); 3310 ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)4U); 3311 ntt_at_layer_3_ea(&zeta_i, re); 3312 ntt_at_layer_2_ea(&zeta_i, re); 3313 ntt_at_layer_1_ea(&zeta_i, re); 3314 poly_barrett_reduce_d6_ea(re); 3315 } 3316 3317 /** 3318 Sample a vector of ring elements from a centered binomial distribution and 3319 convert them into their NTT representations. 3320 */ 3321 /** 3322 A monomorphic instance of libcrux_ml_kem.ind_cpa.sample_vector_cbd_then_ntt 3323 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 3324 libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] with const 3325 generics 3326 - K= 4 3327 - ETA= 2 3328 - ETA_RANDOMNESS_SIZE= 128 3329 */ 3330 static KRML_MUSTINLINE uint8_t 3331 sample_vector_cbd_then_ntt_3b( 3332 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re_as_ntt, 3333 uint8_t *prf_input, uint8_t domain_separator) 3334 { 3335 uint8_t prf_inputs[4U][33U]; 3336 KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, 3337 core_array__core__clone__Clone_for__Array_T__N___clone( 3338 (size_t)33U, prf_input, prf_inputs[i], uint8_t, void *);); 3339 domain_separator = 3340 libcrux_ml_kem_utils_prf_input_inc_ac(prf_inputs, domain_separator); 3341 uint8_t prf_outputs[4U][128U]; 3342 PRFxN_4a_44(prf_inputs, prf_outputs); 3343 KRML_MAYBE_FOR4( 3344 i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; 3345 re_as_ntt[i0] = sample_from_binomial_distribution_a0( 3346 Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], uint8_t)); 3347 ntt_binomially_sampled_ring_element_ea(&re_as_ntt[i0]);); 3348 return domain_separator; 3349 } 3350 3351 /** 3352 This function found in impl {core::ops::function::FnMut<(usize), 3353 libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0, 3354 TraitClause@3]> for 3355 libcrux_ml_kem::ind_cpa::generate_keypair_unpacked::closure<Vector, Hasher, 3356 Scheme, K, ETA1, ETA1_RANDOMNESS_SIZE>[TraitClause@0, TraitClause@1, 3357 TraitClause@2, TraitClause@3, TraitClause@4, TraitClause@5]} 3358 */ 3359 /** 3360 A monomorphic instance of 3361 libcrux_ml_kem.ind_cpa.generate_keypair_unpacked.call_mut_73 with types 3362 libcrux_ml_kem_vector_portable_vector_type_PortableVector, 3363 libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]], 3364 libcrux_ml_kem_variant_MlKem with const generics 3365 - K= 4 3366 - ETA1= 2 3367 - ETA1_RANDOMNESS_SIZE= 128 3368 */ 3369 static libcrux_ml_kem_polynomial_PolynomialRingElement_1d 3370 call_mut_73_1c( 3371 void **_) 3372 { 3373 return ZERO_d6_ea(); 3374 } 3375 3376 /** 3377 Given two `KyberPolynomialRingElement`s in their NTT representations, 3378 compute their product. Given two polynomials in the NTT domain `f^` and `ĵ`, 3379 the `iᵗʰ` coefficient of the product `k̂` is determined by the calculation: 3380 3381 ```plaintext 3382 ĥ[2·i] + ĥ[2·i + 1]X = (f^[2·i] + f^[2·i + 1]X)·(ĝ[2·i] + ĝ[2·i + 1]X) mod (X² 3383 - ζ^(2·BitRev₇(i) + 1)) 3384 ``` 3385 3386 This function almost implements <strong>Algorithm 10</strong> of the 3387 NIST FIPS 203 standard, which is reproduced below: 3388 3389 ```plaintext 3390 Input: Two arrays fˆ ∈ ℤ₂₅₆ and ĝ ∈ ℤ₂₅₆. 3391 Output: An array ĥ ∈ ℤq. 3392 3393 for(i ← 0; i < 128; i++) 3394 (ĥ[2i], ĥ[2i+1]) ← BaseCaseMultiply(fˆ[2i], fˆ[2i+1], ĝ[2i], ĝ[2i+1], 3395 ζ^(2·BitRev₇(i) + 1)) end for return ĥ 3396 ``` 3397 We say "almost" because the coefficients of the ring element output by 3398 this function are in the Montgomery domain. 3399 3400 The NIST FIPS 203 standard can be found at 3401 <https://csrc.nist.gov/pubs/fips/203/ipd>. 3402 */ 3403 /** 3404 A monomorphic instance of libcrux_ml_kem.polynomial.ntt_multiply 3405 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 3406 with const generics 3407 3408 */ 3409 static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d 3410 ntt_multiply_ea(libcrux_ml_kem_polynomial_PolynomialRingElement_1d *myself, 3411 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *rhs) 3412 { 3413 libcrux_ml_kem_polynomial_PolynomialRingElement_1d out = ZERO_ea(); 3414 for (size_t i = (size_t)0U; i < VECTORS_IN_RING_ELEMENT; i++) { 3415 size_t i0 = i; 3416 libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = 3417 libcrux_ml_kem_vector_portable_ntt_multiply_b8( 3418 &myself->coefficients[i0], &rhs->coefficients[i0], 3419 zeta((size_t)64U + (size_t)4U * i0), 3420 zeta((size_t)64U + (size_t)4U * i0 + (size_t)1U), 3421 zeta((size_t)64U + (size_t)4U * i0 + (size_t)2U), 3422 zeta((size_t)64U + (size_t)4U * i0 + (size_t)3U)); 3423 out.coefficients[i0] = uu____0; 3424 } 3425 return out; 3426 } 3427 3428 /** 3429 This function found in impl 3430 {libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0, 3431 TraitClause@1]} 3432 */ 3433 /** 3434 A monomorphic instance of libcrux_ml_kem.polynomial.ntt_multiply_d6 3435 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 3436 with const generics 3437 3438 */ 3439 static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d 3440 ntt_multiply_d6_ea(libcrux_ml_kem_polynomial_PolynomialRingElement_1d *self, 3441 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *rhs) 3442 { 3443 return ntt_multiply_ea(self, rhs); 3444 } 3445 3446 /** 3447 Given two polynomial ring elements `lhs` and `rhs`, compute the pointwise 3448 sum of their constituent coefficients. 3449 */ 3450 /** 3451 A monomorphic instance of libcrux_ml_kem.polynomial.add_to_ring_element 3452 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 3453 with const generics 3454 - K= 4 3455 */ 3456 static KRML_MUSTINLINE void 3457 add_to_ring_element_d0( 3458 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *myself, 3459 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *rhs) 3460 { 3461 for (size_t i = (size_t)0U; 3462 i < Eurydice_slice_len( 3463 Eurydice_array_to_slice( 3464 (size_t)16U, myself->coefficients, 3465 libcrux_ml_kem_vector_portable_vector_type_PortableVector), 3466 libcrux_ml_kem_vector_portable_vector_type_PortableVector); 3467 i++) { 3468 size_t i0 = i; 3469 libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = 3470 libcrux_ml_kem_vector_portable_add_b8(myself->coefficients[i0], 3471 &rhs->coefficients[i0]); 3472 myself->coefficients[i0] = uu____0; 3473 } 3474 } 3475 3476 /** 3477 This function found in impl 3478 {libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0, 3479 TraitClause@1]} 3480 */ 3481 /** 3482 A monomorphic instance of libcrux_ml_kem.polynomial.add_to_ring_element_d6 3483 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 3484 with const generics 3485 - K= 4 3486 */ 3487 static KRML_MUSTINLINE void 3488 add_to_ring_element_d6_d0( 3489 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *self, 3490 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *rhs) 3491 { 3492 add_to_ring_element_d0(self, rhs); 3493 } 3494 3495 /** 3496 A monomorphic instance of libcrux_ml_kem.polynomial.to_standard_domain 3497 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 3498 with const generics 3499 3500 */ 3501 static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 3502 to_standard_domain_ea( 3503 libcrux_ml_kem_vector_portable_vector_type_PortableVector vector) 3504 { 3505 return libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_b8( 3506 vector, 3507 LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS); 3508 } 3509 3510 /** 3511 A monomorphic instance of libcrux_ml_kem.polynomial.add_standard_error_reduce 3512 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 3513 with const generics 3514 3515 */ 3516 static KRML_MUSTINLINE void 3517 add_standard_error_reduce_ea( 3518 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *myself, 3519 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *error) 3520 { 3521 for (size_t i = (size_t)0U; i < VECTORS_IN_RING_ELEMENT; i++) { 3522 size_t j = i; 3523 libcrux_ml_kem_vector_portable_vector_type_PortableVector 3524 coefficient_normal_form = 3525 to_standard_domain_ea(myself->coefficients[j]); 3526 libcrux_ml_kem_vector_portable_vector_type_PortableVector sum = 3527 libcrux_ml_kem_vector_portable_add_b8(coefficient_normal_form, 3528 &error->coefficients[j]); 3529 libcrux_ml_kem_vector_portable_vector_type_PortableVector red = 3530 libcrux_ml_kem_vector_portable_barrett_reduce_b8(sum); 3531 myself->coefficients[j] = red; 3532 } 3533 } 3534 3535 /** 3536 This function found in impl 3537 {libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0, 3538 TraitClause@1]} 3539 */ 3540 /** 3541 A monomorphic instance of libcrux_ml_kem.polynomial.add_standard_error_reduce_d6 3542 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 3543 with const generics 3544 3545 */ 3546 static KRML_MUSTINLINE void 3547 add_standard_error_reduce_d6_ea( 3548 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *self, 3549 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *error) 3550 { 3551 add_standard_error_reduce_ea(self, error); 3552 } 3553 3554 /** 3555 Compute  ◦ ŝ + ê 3556 */ 3557 /** 3558 A monomorphic instance of libcrux_ml_kem.matrix.compute_As_plus_e 3559 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 3560 with const generics 3561 - K= 4 3562 */ 3563 static KRML_MUSTINLINE void 3564 compute_As_plus_e_d0( 3565 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *t_as_ntt, 3566 libcrux_ml_kem_polynomial_PolynomialRingElement_1d (*matrix_A)[4U], 3567 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *s_as_ntt, 3568 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *error_as_ntt) 3569 { 3570 for (size_t i = (size_t)0U; 3571 i < Eurydice_slice_len( 3572 Eurydice_array_to_slice( 3573 (size_t)4U, matrix_A, 3574 libcrux_ml_kem_polynomial_PolynomialRingElement_1d[4U]), 3575 libcrux_ml_kem_polynomial_PolynomialRingElement_1d[4U]); 3576 i++) { 3577 size_t i0 = i; 3578 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *row = matrix_A[i0]; 3579 libcrux_ml_kem_polynomial_PolynomialRingElement_1d uu____0 = ZERO_d6_ea(); 3580 t_as_ntt[i0] = uu____0; 3581 for (size_t i1 = (size_t)0U; 3582 i1 < Eurydice_slice_len( 3583 Eurydice_array_to_slice( 3584 (size_t)4U, row, 3585 libcrux_ml_kem_polynomial_PolynomialRingElement_1d), 3586 libcrux_ml_kem_polynomial_PolynomialRingElement_1d); 3587 i1++) { 3588 size_t j = i1; 3589 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *matrix_element = 3590 &row[j]; 3591 libcrux_ml_kem_polynomial_PolynomialRingElement_1d product = 3592 ntt_multiply_d6_ea(matrix_element, &s_as_ntt[j]); 3593 add_to_ring_element_d6_d0(&t_as_ntt[i0], &product); 3594 } 3595 add_standard_error_reduce_d6_ea(&t_as_ntt[i0], &error_as_ntt[i0]); 3596 } 3597 } 3598 3599 /** 3600 This function implements most of <strong>Algorithm 12</strong> of the 3601 NIST FIPS 203 specification; this is the Kyber CPA-PKE key generation 3602 algorithm. 3603 3604 We say "most of" since Algorithm 12 samples the required randomness within 3605 the function itself, whereas this implementation expects it to be provided 3606 through the `key_generation_seed` parameter. 3607 3608 Algorithm 12 is reproduced below: 3609 3610 ```plaintext 3611 Output: encryption key ekₚₖₑ ∈ 𝔹^{384k+32}. 3612 Output: decryption key dkₚₖₑ ∈ 𝔹^{384k}. 3613 3614 d ←$ B 3615 (ρ,σ) ← G(d) 3616 N ← 0 3617 for (i ← 0; i < k; i++) 3618 for(j ← 0; j < k; j++) 3619 Â[i,j] ← SampleNTT(XOF(ρ, i, j)) 3620 end for 3621 end for 3622 for(i ← 0; i < k; i++) 3623 s[i] ← SamplePolyCBD_{η₁}(PRF_{η₁}(σ,N)) 3624 N ← N + 1 3625 end for 3626 for(i ← 0; i < k; i++) 3627 e[i] ← SamplePolyCBD_{η₂}(PRF_{η₂}(σ,N)) 3628 N ← N + 1 3629 end for 3630 ŝ ← NTT(s) 3631 ê ← NTT(e) 3632 t̂ ← Â◦ŝ + ê 3633 ekₚₖₑ ← ByteEncode₁₂(t̂) ‖ ρ 3634 dkₚₖₑ ← ByteEncode₁₂(ŝ) 3635 ``` 3636 3637 The NIST FIPS 203 standard can be found at 3638 <https://csrc.nist.gov/pubs/fips/203/ipd>. 3639 */ 3640 /** 3641 A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair_unpacked 3642 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 3643 libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]], 3644 libcrux_ml_kem_variant_MlKem with const generics 3645 - K= 4 3646 - ETA1= 2 3647 - ETA1_RANDOMNESS_SIZE= 128 3648 */ 3649 static KRML_MUSTINLINE void 3650 generate_keypair_unpacked_1c( 3651 Eurydice_slice key_generation_seed, 3652 IndCpaPrivateKeyUnpacked_af *private_key, 3653 IndCpaPublicKeyUnpacked_af *public_key) 3654 { 3655 uint8_t hashed[64U]; 3656 cpa_keygen_seed_39_03(key_generation_seed, hashed); 3657 Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at( 3658 Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), (size_t)32U, 3659 uint8_t, Eurydice_slice_uint8_t_x2); 3660 Eurydice_slice seed_for_A = uu____0.fst; 3661 Eurydice_slice seed_for_secret_and_error = uu____0.snd; 3662 libcrux_ml_kem_polynomial_PolynomialRingElement_1d(*uu____1)[4U] = 3663 public_key->A; 3664 uint8_t ret[34U]; 3665 libcrux_ml_kem_utils_into_padded_array_b6(seed_for_A, ret); 3666 sample_matrix_A_2b(uu____1, ret, true); 3667 uint8_t prf_input[33U]; 3668 libcrux_ml_kem_utils_into_padded_array_c8(seed_for_secret_and_error, 3669 prf_input); 3670 uint8_t domain_separator = 3671 sample_vector_cbd_then_ntt_3b(private_key->secret_as_ntt, prf_input, 0U); 3672 libcrux_ml_kem_polynomial_PolynomialRingElement_1d error_as_ntt[4U]; 3673 KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, 3674 /* original Rust expression is not an lvalue in C */ 3675 void *lvalue = (void *)0U; 3676 error_as_ntt[i] = call_mut_73_1c(&lvalue);); 3677 sample_vector_cbd_then_ntt_3b(error_as_ntt, prf_input, domain_separator); 3678 compute_As_plus_e_d0(public_key->t_as_ntt, public_key->A, 3679 private_key->secret_as_ntt, error_as_ntt); 3680 uint8_t uu____2[32U]; 3681 core_result_Result_fb dst; 3682 Eurydice_slice_to_array2(&dst, seed_for_A, Eurydice_slice, uint8_t[32U], 3683 core_array_TryFromSliceError); 3684 core_result_unwrap_26_b3(dst, uu____2); 3685 memcpy(public_key->seed_for_A, uu____2, (size_t)32U * sizeof(uint8_t)); 3686 } 3687 3688 /** 3689 Serialize the secret key from the unpacked key pair generation. 3690 */ 3691 /** 3692 A monomorphic instance of libcrux_ml_kem.ind_cpa.serialize_unpacked_secret_key 3693 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 3694 with const generics 3695 - K= 4 3696 - PRIVATE_KEY_SIZE= 1536 3697 - PUBLIC_KEY_SIZE= 1568 3698 */ 3699 static libcrux_ml_kem_utils_extraction_helper_Keypair1024 3700 serialize_unpacked_secret_key_00(IndCpaPublicKeyUnpacked_af *public_key, 3701 IndCpaPrivateKeyUnpacked_af *private_key) 3702 { 3703 uint8_t public_key_serialized[1568U]; 3704 serialize_public_key_ff( 3705 public_key->t_as_ntt, 3706 Eurydice_array_to_slice((size_t)32U, public_key->seed_for_A, uint8_t), 3707 public_key_serialized); 3708 uint8_t secret_key_serialized[1536U] = { 0U }; 3709 serialize_vector_d0( 3710 private_key->secret_as_ntt, 3711 Eurydice_array_to_slice((size_t)1536U, secret_key_serialized, uint8_t)); 3712 /* Passing arrays by value in Rust generates a copy in C */ 3713 uint8_t copy_of_secret_key_serialized[1536U]; 3714 memcpy(copy_of_secret_key_serialized, secret_key_serialized, 3715 (size_t)1536U * sizeof(uint8_t)); 3716 /* Passing arrays by value in Rust generates a copy in C */ 3717 uint8_t copy_of_public_key_serialized[1568U]; 3718 memcpy(copy_of_public_key_serialized, public_key_serialized, 3719 (size_t)1568U * sizeof(uint8_t)); 3720 libcrux_ml_kem_utils_extraction_helper_Keypair1024 lit; 3721 memcpy(lit.fst, copy_of_secret_key_serialized, 3722 (size_t)1536U * sizeof(uint8_t)); 3723 memcpy(lit.snd, copy_of_public_key_serialized, 3724 (size_t)1568U * sizeof(uint8_t)); 3725 return lit; 3726 } 3727 3728 /** 3729 A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair 3730 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 3731 libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]], 3732 libcrux_ml_kem_variant_MlKem with const generics 3733 - K= 4 3734 - PRIVATE_KEY_SIZE= 1536 3735 - PUBLIC_KEY_SIZE= 1568 3736 - ETA1= 2 3737 - ETA1_RANDOMNESS_SIZE= 128 3738 */ 3739 static KRML_MUSTINLINE libcrux_ml_kem_utils_extraction_helper_Keypair1024 3740 generate_keypair_ea0(Eurydice_slice key_generation_seed) 3741 { 3742 IndCpaPrivateKeyUnpacked_af private_key = default_70_d0(); 3743 IndCpaPublicKeyUnpacked_af public_key = default_8b_d0(); 3744 generate_keypair_unpacked_1c(key_generation_seed, &private_key, &public_key); 3745 return serialize_unpacked_secret_key_00(&public_key, &private_key); 3746 } 3747 3748 /** 3749 Serialize the secret key. 3750 */ 3751 /** 3752 A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key_mut 3753 with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] 3754 with const generics 3755 - K= 4 3756 - SERIALIZED_KEY_LEN= 3168 3757 */ 3758 static KRML_MUSTINLINE void 3759 serialize_kem_secret_key_mut_60( 3760 Eurydice_slice private_key, Eurydice_slice public_key, 3761 Eurydice_slice implicit_rejection_value, uint8_t *serialized) 3762 { 3763 size_t pointer = (size_t)0U; 3764 uint8_t *uu____0 = serialized; 3765 size_t uu____1 = pointer; 3766 size_t uu____2 = pointer; 3767 Eurydice_slice_copy( 3768 Eurydice_array_to_subslice3( 3769 uu____0, uu____1, uu____2 + Eurydice_slice_len(private_key, uint8_t), 3770 uint8_t *), 3771 private_key, uint8_t); 3772 pointer = pointer + Eurydice_slice_len(private_key, uint8_t); 3773 uint8_t *uu____3 = serialized; 3774 size_t uu____4 = pointer; 3775 size_t uu____5 = pointer; 3776 Eurydice_slice_copy( 3777 Eurydice_array_to_subslice3( 3778 uu____3, uu____4, uu____5 + Eurydice_slice_len(public_key, uint8_t), 3779 uint8_t *), 3780 public_key, uint8_t); 3781 pointer = pointer + Eurydice_slice_len(public_key, uint8_t); 3782 Eurydice_slice uu____6 = Eurydice_array_to_subslice3( 3783 serialized, pointer, pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, 3784 uint8_t *); 3785 uint8_t ret[32U]; 3786 H_4a_ac(public_key, ret); 3787 Eurydice_slice_copy( 3788 uu____6, Eurydice_array_to_slice((size_t)32U, ret, uint8_t), uint8_t); 3789 pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; 3790 uint8_t *uu____7 = serialized; 3791 size_t uu____8 = pointer; 3792 size_t uu____9 = pointer; 3793 Eurydice_slice_copy( 3794 Eurydice_array_to_subslice3( 3795 uu____7, uu____8, 3796 uu____9 + Eurydice_slice_len(implicit_rejection_value, uint8_t), 3797 uint8_t *), 3798 implicit_rejection_value, uint8_t); 3799 } 3800 3801 /** 3802 A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key 3803 with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] 3804 with const generics 3805 - K= 4 3806 - SERIALIZED_KEY_LEN= 3168 3807 */ 3808 static KRML_MUSTINLINE void 3809 serialize_kem_secret_key_60( 3810 Eurydice_slice private_key, Eurydice_slice public_key, 3811 Eurydice_slice implicit_rejection_value, uint8_t ret[3168U]) 3812 { 3813 uint8_t out[3168U] = { 0U }; 3814 serialize_kem_secret_key_mut_60(private_key, public_key, 3815 implicit_rejection_value, out); 3816 memcpy(ret, out, (size_t)3168U * sizeof(uint8_t)); 3817 } 3818 3819 /** 3820 Packed API 3821 3822 Generate a key pair. 3823 3824 Depending on the `Vector` and `Hasher` used, this requires different hardware 3825 features 3826 */ 3827 /** 3828 A monomorphic instance of libcrux_ml_kem.ind_cca.generate_keypair 3829 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 3830 libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]], 3831 libcrux_ml_kem_variant_MlKem with const generics 3832 - K= 4 3833 - CPA_PRIVATE_KEY_SIZE= 1536 3834 - PRIVATE_KEY_SIZE= 3168 3835 - PUBLIC_KEY_SIZE= 1568 3836 - ETA1= 2 3837 - ETA1_RANDOMNESS_SIZE= 128 3838 */ 3839 libcrux_ml_kem_mlkem1024_MlKem1024KeyPair 3840 libcrux_ml_kem_ind_cca_generate_keypair_150(uint8_t *randomness) 3841 { 3842 Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice3( 3843 randomness, (size_t)0U, 3844 LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t *); 3845 Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( 3846 (size_t)64U, randomness, 3847 LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, 3848 size_t, uint8_t[]); 3849 libcrux_ml_kem_utils_extraction_helper_Keypair1024 uu____0 = 3850 generate_keypair_ea0(ind_cpa_keypair_randomness); 3851 uint8_t ind_cpa_private_key[1536U]; 3852 memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1536U * sizeof(uint8_t)); 3853 uint8_t public_key[1568U]; 3854 memcpy(public_key, uu____0.snd, (size_t)1568U * sizeof(uint8_t)); 3855 uint8_t secret_key_serialized[3168U]; 3856 serialize_kem_secret_key_60( 3857 Eurydice_array_to_slice((size_t)1536U, ind_cpa_private_key, uint8_t), 3858 Eurydice_array_to_slice((size_t)1568U, public_key, uint8_t), 3859 implicit_rejection_value, secret_key_serialized); 3860 /* Passing arrays by value in Rust generates a copy in C */ 3861 uint8_t copy_of_secret_key_serialized[3168U]; 3862 memcpy(copy_of_secret_key_serialized, secret_key_serialized, 3863 (size_t)3168U * sizeof(uint8_t)); 3864 libcrux_ml_kem_types_MlKemPrivateKey_83 private_key = 3865 libcrux_ml_kem_types_from_77_39(copy_of_secret_key_serialized); 3866 libcrux_ml_kem_types_MlKemPrivateKey_83 uu____2 = private_key; 3867 /* Passing arrays by value in Rust generates a copy in C */ 3868 uint8_t copy_of_public_key[1568U]; 3869 memcpy(copy_of_public_key, public_key, (size_t)1568U * sizeof(uint8_t)); 3870 return libcrux_ml_kem_types_from_17_94( 3871 uu____2, libcrux_ml_kem_types_from_fd_af(copy_of_public_key)); 3872 } 3873 3874 /** 3875 This function found in impl {libcrux_ml_kem::variant::Variant for 3876 libcrux_ml_kem::variant::MlKem} 3877 */ 3878 /** 3879 A monomorphic instance of libcrux_ml_kem.variant.entropy_preprocess_39 3880 with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] 3881 with const generics 3882 - K= 4 3883 */ 3884 static KRML_MUSTINLINE void 3885 entropy_preprocess_39_03(Eurydice_slice randomness, 3886 uint8_t ret[32U]) 3887 { 3888 uint8_t out[32U] = { 0U }; 3889 Eurydice_slice_copy(Eurydice_array_to_slice((size_t)32U, out, uint8_t), 3890 randomness, uint8_t); 3891 memcpy(ret, out, (size_t)32U * sizeof(uint8_t)); 3892 } 3893 3894 /** 3895 A monomorphic instance of libcrux_ml_kem.ind_cpa.build_unpacked_public_key_mut 3896 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 3897 libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] with const 3898 generics 3899 - K= 4 3900 - T_AS_NTT_ENCODED_SIZE= 1536 3901 */ 3902 static KRML_MUSTINLINE void 3903 build_unpacked_public_key_mut_3f( 3904 Eurydice_slice public_key, 3905 IndCpaPublicKeyUnpacked_af *unpacked_public_key) 3906 { 3907 Eurydice_slice uu____0 = Eurydice_slice_subslice_to( 3908 public_key, (size_t)1536U, uint8_t, size_t, uint8_t[]); 3909 deserialize_ring_elements_reduced_d0(uu____0, unpacked_public_key->t_as_ntt); 3910 Eurydice_slice seed = Eurydice_slice_subslice_from( 3911 public_key, (size_t)1536U, uint8_t, size_t, uint8_t[]); 3912 libcrux_ml_kem_polynomial_PolynomialRingElement_1d(*uu____1)[4U] = 3913 unpacked_public_key->A; 3914 uint8_t ret[34U]; 3915 libcrux_ml_kem_utils_into_padded_array_b6(seed, ret); 3916 sample_matrix_A_2b(uu____1, ret, false); 3917 } 3918 3919 /** 3920 A monomorphic instance of libcrux_ml_kem.ind_cpa.build_unpacked_public_key 3921 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 3922 libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] with const 3923 generics 3924 - K= 4 3925 - T_AS_NTT_ENCODED_SIZE= 1536 3926 */ 3927 static KRML_MUSTINLINE IndCpaPublicKeyUnpacked_af 3928 build_unpacked_public_key_3f0(Eurydice_slice public_key) 3929 { 3930 IndCpaPublicKeyUnpacked_af unpacked_public_key = default_8b_d0(); 3931 build_unpacked_public_key_mut_3f(public_key, &unpacked_public_key); 3932 return unpacked_public_key; 3933 } 3934 3935 /** 3936 A monomorphic instance of K. 3937 with types libcrux_ml_kem_polynomial_PolynomialRingElement 3938 libcrux_ml_kem_vector_portable_vector_type_PortableVector[4size_t], 3939 libcrux_ml_kem_polynomial_PolynomialRingElement 3940 libcrux_ml_kem_vector_portable_vector_type_PortableVector 3941 3942 */ 3943 typedef struct tuple_08_s { 3944 libcrux_ml_kem_polynomial_PolynomialRingElement_1d fst[4U]; 3945 libcrux_ml_kem_polynomial_PolynomialRingElement_1d snd; 3946 } tuple_08; 3947 3948 /** 3949 This function found in impl {core::ops::function::FnMut<(usize), 3950 libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0, 3951 TraitClause@2]> for libcrux_ml_kem::ind_cpa::encrypt_c1::closure<Vector, Hasher, 3952 K, C1_LEN, U_COMPRESSION_FACTOR, BLOCK_LEN, ETA1, ETA1_RANDOMNESS_SIZE, ETA2, 3953 ETA2_RANDOMNESS_SIZE>[TraitClause@0, TraitClause@1, TraitClause@2, 3954 TraitClause@3]} 3955 */ 3956 /** 3957 A monomorphic instance of libcrux_ml_kem.ind_cpa.encrypt_c1.call_mut_f1 3958 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 3959 libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] with const 3960 generics 3961 - K= 4 3962 - C1_LEN= 1408 3963 - U_COMPRESSION_FACTOR= 11 3964 - BLOCK_LEN= 352 3965 - ETA1= 2 3966 - ETA1_RANDOMNESS_SIZE= 128 3967 - ETA2= 2 3968 - ETA2_RANDOMNESS_SIZE= 128 3969 */ 3970 static libcrux_ml_kem_polynomial_PolynomialRingElement_1d 3971 call_mut_f1_85( 3972 void **_) 3973 { 3974 return ZERO_d6_ea(); 3975 } 3976 3977 /** 3978 This function found in impl {core::ops::function::FnMut<(usize), 3979 libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0, 3980 TraitClause@2]> for libcrux_ml_kem::ind_cpa::encrypt_c1::closure#1<Vector, 3981 Hasher, K, C1_LEN, U_COMPRESSION_FACTOR, BLOCK_LEN, ETA1, ETA1_RANDOMNESS_SIZE, 3982 ETA2, ETA2_RANDOMNESS_SIZE>[TraitClause@0, TraitClause@1, TraitClause@2, 3983 TraitClause@3]} 3984 */ 3985 /** 3986 A monomorphic instance of libcrux_ml_kem.ind_cpa.encrypt_c1.call_mut_dd 3987 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 3988 libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] with const 3989 generics 3990 - K= 4 3991 - C1_LEN= 1408 3992 - U_COMPRESSION_FACTOR= 11 3993 - BLOCK_LEN= 352 3994 - ETA1= 2 3995 - ETA1_RANDOMNESS_SIZE= 128 3996 - ETA2= 2 3997 - ETA2_RANDOMNESS_SIZE= 128 3998 */ 3999 static libcrux_ml_kem_polynomial_PolynomialRingElement_1d 4000 call_mut_dd_85( 4001 void **_) 4002 { 4003 return ZERO_d6_ea(); 4004 } 4005 4006 /** 4007 Sample a vector of ring elements from a centered binomial distribution. 4008 */ 4009 /** 4010 A monomorphic instance of libcrux_ml_kem.ind_cpa.sample_ring_element_cbd 4011 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 4012 libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] with const 4013 generics 4014 - K= 4 4015 - ETA2_RANDOMNESS_SIZE= 128 4016 - ETA2= 2 4017 */ 4018 static KRML_MUSTINLINE uint8_t 4019 sample_ring_element_cbd_3b( 4020 uint8_t *prf_input, uint8_t domain_separator, 4021 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *error_1) 4022 { 4023 uint8_t prf_inputs[4U][33U]; 4024 KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, 4025 core_array__core__clone__Clone_for__Array_T__N___clone( 4026 (size_t)33U, prf_input, prf_inputs[i], uint8_t, void *);); 4027 domain_separator = 4028 libcrux_ml_kem_utils_prf_input_inc_ac(prf_inputs, domain_separator); 4029 uint8_t prf_outputs[4U][128U]; 4030 PRFxN_4a_44(prf_inputs, prf_outputs); 4031 KRML_MAYBE_FOR4( 4032 i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; 4033 libcrux_ml_kem_polynomial_PolynomialRingElement_1d uu____0 = 4034 sample_from_binomial_distribution_a0( 4035 Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], uint8_t)); 4036 error_1[i0] = uu____0;); 4037 return domain_separator; 4038 } 4039 4040 /** 4041 A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRF 4042 with const generics 4043 - LEN= 128 4044 */ 4045 static inline void 4046 PRF_a6(Eurydice_slice input, uint8_t ret[128U]) 4047 { 4048 uint8_t digest[128U] = { 0U }; 4049 libcrux_sha3_portable_shake256( 4050 Eurydice_array_to_slice((size_t)128U, digest, uint8_t), input); 4051 memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); 4052 } 4053 4054 /** 4055 This function found in impl {libcrux_ml_kem::hash_functions::Hash<K> for 4056 libcrux_ml_kem::hash_functions::portable::PortableHash<K>} 4057 */ 4058 /** 4059 A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRF_4a 4060 with const generics 4061 - K= 4 4062 - LEN= 128 4063 */ 4064 static inline void 4065 PRF_4a_440(Eurydice_slice input, uint8_t ret[128U]) 4066 { 4067 PRF_a6(input, ret); 4068 } 4069 4070 /** 4071 This function found in impl {core::ops::function::FnMut<(usize), 4072 libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0, 4073 TraitClause@1]> for libcrux_ml_kem::matrix::compute_vector_u::closure<Vector, 4074 K>[TraitClause@0, TraitClause@1]} 4075 */ 4076 /** 4077 A monomorphic instance of libcrux_ml_kem.matrix.compute_vector_u.call_mut_a8 4078 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 4079 with const generics 4080 - K= 4 4081 */ 4082 static libcrux_ml_kem_polynomial_PolynomialRingElement_1d 4083 call_mut_a8_d0( 4084 void **_) 4085 { 4086 return ZERO_d6_ea(); 4087 } 4088 4089 /** 4090 A monomorphic instance of libcrux_ml_kem.invert_ntt.invert_ntt_at_layer_1 4091 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 4092 with const generics 4093 4094 */ 4095 static KRML_MUSTINLINE void 4096 invert_ntt_at_layer_1_ea( 4097 size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re) 4098 { 4099 KRML_MAYBE_FOR16( 4100 i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; 4101 zeta_i[0U] = zeta_i[0U] - (size_t)1U; 4102 re->coefficients[round] = 4103 libcrux_ml_kem_vector_portable_inv_ntt_layer_1_step_b8( 4104 re->coefficients[round], zeta(zeta_i[0U]), 4105 zeta(zeta_i[0U] - (size_t)1U), zeta(zeta_i[0U] - (size_t)2U), 4106 zeta(zeta_i[0U] - (size_t)3U)); 4107 zeta_i[0U] = zeta_i[0U] - (size_t)3U;); 4108 } 4109 4110 /** 4111 A monomorphic instance of libcrux_ml_kem.invert_ntt.invert_ntt_at_layer_2 4112 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 4113 with const generics 4114 4115 */ 4116 static KRML_MUSTINLINE void 4117 invert_ntt_at_layer_2_ea( 4118 size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re) 4119 { 4120 KRML_MAYBE_FOR16(i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; 4121 zeta_i[0U] = zeta_i[0U] - (size_t)1U; 4122 re->coefficients[round] = 4123 libcrux_ml_kem_vector_portable_inv_ntt_layer_2_step_b8( 4124 re->coefficients[round], zeta(zeta_i[0U]), 4125 zeta(zeta_i[0U] - (size_t)1U)); 4126 zeta_i[0U] = zeta_i[0U] - (size_t)1U;); 4127 } 4128 4129 /** 4130 A monomorphic instance of libcrux_ml_kem.invert_ntt.invert_ntt_at_layer_3 4131 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 4132 with const generics 4133 4134 */ 4135 static KRML_MUSTINLINE void 4136 invert_ntt_at_layer_3_ea( 4137 size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re) 4138 { 4139 KRML_MAYBE_FOR16( 4140 i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; 4141 zeta_i[0U] = zeta_i[0U] - (size_t)1U; 4142 libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = 4143 libcrux_ml_kem_vector_portable_inv_ntt_layer_3_step_b8( 4144 re->coefficients[round], zeta(zeta_i[0U])); 4145 re->coefficients[round] = uu____0;); 4146 } 4147 4148 /** 4149 A monomorphic instance of 4150 libcrux_ml_kem.invert_ntt.inv_ntt_layer_int_vec_step_reduce with types 4151 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 4152 4153 */ 4154 static KRML_MUSTINLINE 4155 libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2 4156 inv_ntt_layer_int_vec_step_reduce_ea( 4157 libcrux_ml_kem_vector_portable_vector_type_PortableVector a, 4158 libcrux_ml_kem_vector_portable_vector_type_PortableVector b, 4159 int16_t zeta_r) 4160 { 4161 libcrux_ml_kem_vector_portable_vector_type_PortableVector a_minus_b = 4162 libcrux_ml_kem_vector_portable_sub_b8(b, &a); 4163 a = libcrux_ml_kem_vector_portable_barrett_reduce_b8( 4164 libcrux_ml_kem_vector_portable_add_b8(a, &b)); 4165 b = libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_b8( 4166 a_minus_b, zeta_r); 4167 return (KRML_CLITERAL( 4168 libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2){ .fst = a, 4169 .snd = b }); 4170 } 4171 4172 /** 4173 A monomorphic instance of libcrux_ml_kem.invert_ntt.invert_ntt_at_layer_4_plus 4174 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 4175 with const generics 4176 4177 */ 4178 static KRML_MUSTINLINE void 4179 invert_ntt_at_layer_4_plus_ea( 4180 size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re, 4181 size_t layer) 4182 { 4183 size_t step = (size_t)1U << (uint32_t)layer; 4184 for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { 4185 size_t round = i0; 4186 zeta_i[0U] = zeta_i[0U] - (size_t)1U; 4187 size_t offset = round * step * (size_t)2U; 4188 size_t offset_vec = 4189 offset / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; 4190 size_t step_vec = 4191 step / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; 4192 for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { 4193 size_t j = i; 4194 libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2 uu____0 = 4195 inv_ntt_layer_int_vec_step_reduce_ea(re->coefficients[j], 4196 re->coefficients[j + step_vec], 4197 zeta(zeta_i[0U])); 4198 libcrux_ml_kem_vector_portable_vector_type_PortableVector x = uu____0.fst; 4199 libcrux_ml_kem_vector_portable_vector_type_PortableVector y = uu____0.snd; 4200 re->coefficients[j] = x; 4201 re->coefficients[j + step_vec] = y; 4202 } 4203 } 4204 } 4205 4206 /** 4207 A monomorphic instance of libcrux_ml_kem.invert_ntt.invert_ntt_montgomery 4208 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 4209 with const generics 4210 - K= 4 4211 */ 4212 static KRML_MUSTINLINE void 4213 invert_ntt_montgomery_d0( 4214 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re) 4215 { 4216 size_t zeta_i = 4217 LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; 4218 invert_ntt_at_layer_1_ea(&zeta_i, re); 4219 invert_ntt_at_layer_2_ea(&zeta_i, re); 4220 invert_ntt_at_layer_3_ea(&zeta_i, re); 4221 invert_ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)4U); 4222 invert_ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)5U); 4223 invert_ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)6U); 4224 invert_ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)7U); 4225 poly_barrett_reduce_d6_ea(re); 4226 } 4227 4228 /** 4229 A monomorphic instance of libcrux_ml_kem.polynomial.add_error_reduce 4230 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 4231 with const generics 4232 4233 */ 4234 static KRML_MUSTINLINE void 4235 add_error_reduce_ea( 4236 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *myself, 4237 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *error) 4238 { 4239 for (size_t i = (size_t)0U; i < VECTORS_IN_RING_ELEMENT; i++) { 4240 size_t j = i; 4241 libcrux_ml_kem_vector_portable_vector_type_PortableVector 4242 coefficient_normal_form = 4243 libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_b8( 4244 myself->coefficients[j], (int16_t)1441); 4245 libcrux_ml_kem_vector_portable_vector_type_PortableVector sum = 4246 libcrux_ml_kem_vector_portable_add_b8(coefficient_normal_form, 4247 &error->coefficients[j]); 4248 libcrux_ml_kem_vector_portable_vector_type_PortableVector red = 4249 libcrux_ml_kem_vector_portable_barrett_reduce_b8(sum); 4250 myself->coefficients[j] = red; 4251 } 4252 } 4253 4254 /** 4255 This function found in impl 4256 {libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0, 4257 TraitClause@1]} 4258 */ 4259 /** 4260 A monomorphic instance of libcrux_ml_kem.polynomial.add_error_reduce_d6 4261 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 4262 with const generics 4263 4264 */ 4265 static KRML_MUSTINLINE void 4266 add_error_reduce_d6_ea( 4267 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *self, 4268 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *error) 4269 { 4270 add_error_reduce_ea(self, error); 4271 } 4272 4273 /** 4274 Compute u := InvertNTT(Aᵀ ◦ r̂) + e₁ 4275 */ 4276 /** 4277 A monomorphic instance of libcrux_ml_kem.matrix.compute_vector_u 4278 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 4279 with const generics 4280 - K= 4 4281 */ 4282 static KRML_MUSTINLINE void 4283 compute_vector_u_d0( 4284 libcrux_ml_kem_polynomial_PolynomialRingElement_1d (*a_as_ntt)[4U], 4285 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *r_as_ntt, 4286 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *error_1, 4287 libcrux_ml_kem_polynomial_PolynomialRingElement_1d ret[4U]) 4288 { 4289 libcrux_ml_kem_polynomial_PolynomialRingElement_1d result[4U]; 4290 KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, 4291 /* original Rust expression is not an lvalue in C */ 4292 void *lvalue = (void *)0U; 4293 result[i] = call_mut_a8_d0(&lvalue);); 4294 for (size_t i0 = (size_t)0U; 4295 i0 < Eurydice_slice_len( 4296 Eurydice_array_to_slice( 4297 (size_t)4U, a_as_ntt, 4298 libcrux_ml_kem_polynomial_PolynomialRingElement_1d[4U]), 4299 libcrux_ml_kem_polynomial_PolynomialRingElement_1d[4U]); 4300 i0++) { 4301 size_t i1 = i0; 4302 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *row = a_as_ntt[i1]; 4303 for (size_t i = (size_t)0U; 4304 i < Eurydice_slice_len( 4305 Eurydice_array_to_slice( 4306 (size_t)4U, row, 4307 libcrux_ml_kem_polynomial_PolynomialRingElement_1d), 4308 libcrux_ml_kem_polynomial_PolynomialRingElement_1d); 4309 i++) { 4310 size_t j = i; 4311 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *a_element = &row[j]; 4312 libcrux_ml_kem_polynomial_PolynomialRingElement_1d product = 4313 ntt_multiply_d6_ea(a_element, &r_as_ntt[j]); 4314 add_to_ring_element_d6_d0(&result[i1], &product); 4315 } 4316 invert_ntt_montgomery_d0(&result[i1]); 4317 add_error_reduce_d6_ea(&result[i1], &error_1[i1]); 4318 } 4319 memcpy( 4320 ret, result, 4321 (size_t)4U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); 4322 } 4323 4324 /** 4325 A monomorphic instance of libcrux_ml_kem.vector.portable.compress.compress 4326 with const generics 4327 - COEFFICIENT_BITS= 10 4328 */ 4329 static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 4330 compress_ef(libcrux_ml_kem_vector_portable_vector_type_PortableVector a) 4331 { 4332 for (size_t i = (size_t)0U; 4333 i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { 4334 size_t i0 = i; 4335 int16_t uu____0 = libcrux_secrets_int_as_i16_f5( 4336 libcrux_ml_kem_vector_portable_compress_compress_ciphertext_coefficient( 4337 (uint8_t)(int32_t)10, 4338 libcrux_secrets_int_as_u16_f5(a.elements[i0]))); 4339 a.elements[i0] = uu____0; 4340 } 4341 return a; 4342 } 4343 4344 /** 4345 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 4346 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 4347 */ 4348 /** 4349 A monomorphic instance of libcrux_ml_kem.vector.portable.compress_b8 4350 with const generics 4351 - COEFFICIENT_BITS= 10 4352 */ 4353 static libcrux_ml_kem_vector_portable_vector_type_PortableVector 4354 compress_b8_ef( 4355 libcrux_ml_kem_vector_portable_vector_type_PortableVector a) 4356 { 4357 return compress_ef(a); 4358 } 4359 4360 /** 4361 A monomorphic instance of libcrux_ml_kem.vector.portable.compress.compress 4362 with const generics 4363 - COEFFICIENT_BITS= 11 4364 */ 4365 static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 4366 compress_c4(libcrux_ml_kem_vector_portable_vector_type_PortableVector a) 4367 { 4368 for (size_t i = (size_t)0U; 4369 i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { 4370 size_t i0 = i; 4371 int16_t uu____0 = libcrux_secrets_int_as_i16_f5( 4372 libcrux_ml_kem_vector_portable_compress_compress_ciphertext_coefficient( 4373 (uint8_t)(int32_t)11, 4374 libcrux_secrets_int_as_u16_f5(a.elements[i0]))); 4375 a.elements[i0] = uu____0; 4376 } 4377 return a; 4378 } 4379 4380 /** 4381 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 4382 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 4383 */ 4384 /** 4385 A monomorphic instance of libcrux_ml_kem.vector.portable.compress_b8 4386 with const generics 4387 - COEFFICIENT_BITS= 11 4388 */ 4389 static libcrux_ml_kem_vector_portable_vector_type_PortableVector 4390 compress_b8_c4( 4391 libcrux_ml_kem_vector_portable_vector_type_PortableVector a) 4392 { 4393 return compress_c4(a); 4394 } 4395 4396 /** 4397 A monomorphic instance of libcrux_ml_kem.serialize.compress_then_serialize_11 4398 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 4399 with const generics 4400 - OUT_LEN= 352 4401 */ 4402 static KRML_MUSTINLINE void 4403 compress_then_serialize_11_54( 4404 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re, uint8_t ret[352U]) 4405 { 4406 uint8_t serialized[352U] = { 0U }; 4407 for (size_t i = (size_t)0U; i < VECTORS_IN_RING_ELEMENT; i++) { 4408 size_t i0 = i; 4409 libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = 4410 compress_b8_c4( 4411 libcrux_ml_kem_vector_portable_to_unsigned_representative_b8( 4412 re->coefficients[i0])); 4413 uint8_t bytes[22U]; 4414 libcrux_ml_kem_vector_portable_serialize_11_b8(coefficient, bytes); 4415 Eurydice_slice_copy( 4416 Eurydice_array_to_subslice3(serialized, (size_t)22U * i0, 4417 (size_t)22U * i0 + (size_t)22U, uint8_t *), 4418 Eurydice_array_to_slice((size_t)22U, bytes, uint8_t), uint8_t); 4419 } 4420 memcpy(ret, serialized, (size_t)352U * sizeof(uint8_t)); 4421 } 4422 4423 /** 4424 A monomorphic instance of 4425 libcrux_ml_kem.serialize.compress_then_serialize_ring_element_u with types 4426 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 4427 - COMPRESSION_FACTOR= 11 4428 - OUT_LEN= 352 4429 */ 4430 static KRML_MUSTINLINE void 4431 compress_then_serialize_ring_element_u_82( 4432 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re, uint8_t ret[352U]) 4433 { 4434 uint8_t uu____0[352U]; 4435 compress_then_serialize_11_54(re, uu____0); 4436 memcpy(ret, uu____0, (size_t)352U * sizeof(uint8_t)); 4437 } 4438 4439 /** 4440 Call [`compress_then_serialize_ring_element_u`] on each ring element. 4441 */ 4442 /** 4443 A monomorphic instance of libcrux_ml_kem.ind_cpa.compress_then_serialize_u 4444 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 4445 with const generics 4446 - K= 4 4447 - OUT_LEN= 1408 4448 - COMPRESSION_FACTOR= 11 4449 - BLOCK_LEN= 352 4450 */ 4451 static KRML_MUSTINLINE void 4452 compress_then_serialize_u_2f( 4453 libcrux_ml_kem_polynomial_PolynomialRingElement_1d input[4U], 4454 Eurydice_slice out) 4455 { 4456 for (size_t i = (size_t)0U; 4457 i < Eurydice_slice_len( 4458 Eurydice_array_to_slice( 4459 (size_t)4U, input, 4460 libcrux_ml_kem_polynomial_PolynomialRingElement_1d), 4461 libcrux_ml_kem_polynomial_PolynomialRingElement_1d); 4462 i++) { 4463 size_t i0 = i; 4464 libcrux_ml_kem_polynomial_PolynomialRingElement_1d re = input[i0]; 4465 Eurydice_slice uu____0 = Eurydice_slice_subslice3( 4466 out, i0 * ((size_t)1408U / (size_t)4U), 4467 (i0 + (size_t)1U) * ((size_t)1408U / (size_t)4U), uint8_t *); 4468 uint8_t ret[352U]; 4469 compress_then_serialize_ring_element_u_82(&re, ret); 4470 Eurydice_slice_copy( 4471 uu____0, Eurydice_array_to_slice((size_t)352U, ret, uint8_t), uint8_t); 4472 } 4473 } 4474 4475 /** 4476 A monomorphic instance of libcrux_ml_kem.ind_cpa.encrypt_c1 4477 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 4478 libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] with const 4479 generics 4480 - K= 4 4481 - C1_LEN= 1408 4482 - U_COMPRESSION_FACTOR= 11 4483 - BLOCK_LEN= 352 4484 - ETA1= 2 4485 - ETA1_RANDOMNESS_SIZE= 128 4486 - ETA2= 2 4487 - ETA2_RANDOMNESS_SIZE= 128 4488 */ 4489 static KRML_MUSTINLINE tuple_08 4490 encrypt_c1_85(Eurydice_slice randomness, 4491 libcrux_ml_kem_polynomial_PolynomialRingElement_1d (*matrix)[4U], 4492 Eurydice_slice ciphertext) 4493 { 4494 uint8_t prf_input[33U]; 4495 libcrux_ml_kem_utils_into_padded_array_c8(randomness, prf_input); 4496 libcrux_ml_kem_polynomial_PolynomialRingElement_1d r_as_ntt[4U]; 4497 KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, 4498 /* original Rust expression is not an lvalue in C */ 4499 void *lvalue = (void *)0U; 4500 r_as_ntt[i] = call_mut_f1_85(&lvalue);); 4501 uint8_t domain_separator0 = 4502 sample_vector_cbd_then_ntt_3b(r_as_ntt, prf_input, 0U); 4503 libcrux_ml_kem_polynomial_PolynomialRingElement_1d error_1[4U]; 4504 KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, 4505 /* original Rust expression is not an lvalue in C */ 4506 void *lvalue = (void *)0U; 4507 error_1[i] = call_mut_dd_85(&lvalue);); 4508 uint8_t domain_separator = 4509 sample_ring_element_cbd_3b(prf_input, domain_separator0, error_1); 4510 prf_input[32U] = domain_separator; 4511 uint8_t prf_output[128U]; 4512 PRF_4a_440(Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t), 4513 prf_output); 4514 libcrux_ml_kem_polynomial_PolynomialRingElement_1d error_2 = 4515 sample_from_binomial_distribution_a0( 4516 Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t)); 4517 libcrux_ml_kem_polynomial_PolynomialRingElement_1d u[4U]; 4518 compute_vector_u_d0(matrix, r_as_ntt, error_1, u); 4519 libcrux_ml_kem_polynomial_PolynomialRingElement_1d uu____0[4U]; 4520 memcpy( 4521 uu____0, u, 4522 (size_t)4U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); 4523 compress_then_serialize_u_2f(uu____0, ciphertext); 4524 /* Passing arrays by value in Rust generates a copy in C */ 4525 libcrux_ml_kem_polynomial_PolynomialRingElement_1d copy_of_r_as_ntt[4U]; 4526 memcpy( 4527 copy_of_r_as_ntt, r_as_ntt, 4528 (size_t)4U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); 4529 tuple_08 lit; 4530 memcpy( 4531 lit.fst, copy_of_r_as_ntt, 4532 (size_t)4U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); 4533 lit.snd = error_2; 4534 return lit; 4535 } 4536 4537 /** 4538 A monomorphic instance of 4539 libcrux_ml_kem.serialize.deserialize_then_decompress_message with types 4540 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 4541 4542 */ 4543 static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d 4544 deserialize_then_decompress_message_ea(uint8_t *serialized) 4545 { 4546 libcrux_ml_kem_polynomial_PolynomialRingElement_1d re = ZERO_d6_ea(); 4547 KRML_MAYBE_FOR16( 4548 i, (size_t)0U, (size_t)16U, (size_t)1U, size_t i0 = i; 4549 libcrux_ml_kem_vector_portable_vector_type_PortableVector 4550 coefficient_compressed = 4551 libcrux_ml_kem_vector_portable_deserialize_1_b8( 4552 Eurydice_array_to_subslice3(serialized, (size_t)2U * i0, 4553 (size_t)2U * i0 + (size_t)2U, 4554 uint8_t *)); 4555 libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = 4556 libcrux_ml_kem_vector_portable_decompress_1_b8( 4557 coefficient_compressed); 4558 re.coefficients[i0] = uu____0;); 4559 return re; 4560 } 4561 4562 /** 4563 A monomorphic instance of libcrux_ml_kem.polynomial.add_message_error_reduce 4564 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 4565 with const generics 4566 4567 */ 4568 static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d 4569 add_message_error_reduce_ea( 4570 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *myself, 4571 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *message, 4572 libcrux_ml_kem_polynomial_PolynomialRingElement_1d result) 4573 { 4574 for (size_t i = (size_t)0U; i < VECTORS_IN_RING_ELEMENT; i++) { 4575 size_t i0 = i; 4576 libcrux_ml_kem_vector_portable_vector_type_PortableVector 4577 coefficient_normal_form = 4578 libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_b8( 4579 result.coefficients[i0], (int16_t)1441); 4580 libcrux_ml_kem_vector_portable_vector_type_PortableVector sum1 = 4581 libcrux_ml_kem_vector_portable_add_b8(myself->coefficients[i0], 4582 &message->coefficients[i0]); 4583 libcrux_ml_kem_vector_portable_vector_type_PortableVector sum2 = 4584 libcrux_ml_kem_vector_portable_add_b8(coefficient_normal_form, &sum1); 4585 libcrux_ml_kem_vector_portable_vector_type_PortableVector red = 4586 libcrux_ml_kem_vector_portable_barrett_reduce_b8(sum2); 4587 result.coefficients[i0] = red; 4588 } 4589 return result; 4590 } 4591 4592 /** 4593 This function found in impl 4594 {libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0, 4595 TraitClause@1]} 4596 */ 4597 /** 4598 A monomorphic instance of libcrux_ml_kem.polynomial.add_message_error_reduce_d6 4599 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 4600 with const generics 4601 4602 */ 4603 static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d 4604 add_message_error_reduce_d6_ea( 4605 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *self, 4606 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *message, 4607 libcrux_ml_kem_polynomial_PolynomialRingElement_1d result) 4608 { 4609 return add_message_error_reduce_ea(self, message, result); 4610 } 4611 4612 /** 4613 Compute InverseNTT(tᵀ ◦ r̂) + e₂ + message 4614 */ 4615 /** 4616 A monomorphic instance of libcrux_ml_kem.matrix.compute_ring_element_v 4617 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 4618 with const generics 4619 - K= 4 4620 */ 4621 static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d 4622 compute_ring_element_v_d0( 4623 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *t_as_ntt, 4624 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *r_as_ntt, 4625 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *error_2, 4626 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *message) 4627 { 4628 libcrux_ml_kem_polynomial_PolynomialRingElement_1d result = ZERO_d6_ea(); 4629 KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; 4630 libcrux_ml_kem_polynomial_PolynomialRingElement_1d product = 4631 ntt_multiply_d6_ea(&t_as_ntt[i0], &r_as_ntt[i0]); 4632 add_to_ring_element_d6_d0(&result, &product);); 4633 invert_ntt_montgomery_d0(&result); 4634 return add_message_error_reduce_d6_ea(error_2, message, result); 4635 } 4636 4637 /** 4638 A monomorphic instance of libcrux_ml_kem.vector.portable.compress.compress 4639 with const generics 4640 - COEFFICIENT_BITS= 4 4641 */ 4642 static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 4643 compress_d1(libcrux_ml_kem_vector_portable_vector_type_PortableVector a) 4644 { 4645 for (size_t i = (size_t)0U; 4646 i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { 4647 size_t i0 = i; 4648 int16_t uu____0 = libcrux_secrets_int_as_i16_f5( 4649 libcrux_ml_kem_vector_portable_compress_compress_ciphertext_coefficient( 4650 (uint8_t)(int32_t)4, 4651 libcrux_secrets_int_as_u16_f5(a.elements[i0]))); 4652 a.elements[i0] = uu____0; 4653 } 4654 return a; 4655 } 4656 4657 /** 4658 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 4659 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 4660 */ 4661 /** 4662 A monomorphic instance of libcrux_ml_kem.vector.portable.compress_b8 4663 with const generics 4664 - COEFFICIENT_BITS= 4 4665 */ 4666 static libcrux_ml_kem_vector_portable_vector_type_PortableVector 4667 compress_b8_d1( 4668 libcrux_ml_kem_vector_portable_vector_type_PortableVector a) 4669 { 4670 return compress_d1(a); 4671 } 4672 4673 /** 4674 A monomorphic instance of libcrux_ml_kem.serialize.compress_then_serialize_4 4675 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 4676 with const generics 4677 4678 */ 4679 static KRML_MUSTINLINE void 4680 compress_then_serialize_4_ea( 4681 libcrux_ml_kem_polynomial_PolynomialRingElement_1d re, 4682 Eurydice_slice serialized) 4683 { 4684 for (size_t i = (size_t)0U; i < VECTORS_IN_RING_ELEMENT; i++) { 4685 size_t i0 = i; 4686 libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = 4687 compress_b8_d1(to_unsigned_field_modulus_ea(re.coefficients[i0])); 4688 uint8_t bytes[8U]; 4689 libcrux_ml_kem_vector_portable_serialize_4_b8(coefficient, bytes); 4690 Eurydice_slice_copy( 4691 Eurydice_slice_subslice3(serialized, (size_t)8U * i0, 4692 (size_t)8U * i0 + (size_t)8U, uint8_t *), 4693 Eurydice_array_to_slice((size_t)8U, bytes, uint8_t), uint8_t); 4694 } 4695 } 4696 4697 /** 4698 A monomorphic instance of libcrux_ml_kem.vector.portable.compress.compress 4699 with const generics 4700 - COEFFICIENT_BITS= 5 4701 */ 4702 static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 4703 compress_f4(libcrux_ml_kem_vector_portable_vector_type_PortableVector a) 4704 { 4705 for (size_t i = (size_t)0U; 4706 i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { 4707 size_t i0 = i; 4708 int16_t uu____0 = libcrux_secrets_int_as_i16_f5( 4709 libcrux_ml_kem_vector_portable_compress_compress_ciphertext_coefficient( 4710 (uint8_t)(int32_t)5, 4711 libcrux_secrets_int_as_u16_f5(a.elements[i0]))); 4712 a.elements[i0] = uu____0; 4713 } 4714 return a; 4715 } 4716 4717 /** 4718 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 4719 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 4720 */ 4721 /** 4722 A monomorphic instance of libcrux_ml_kem.vector.portable.compress_b8 4723 with const generics 4724 - COEFFICIENT_BITS= 5 4725 */ 4726 static libcrux_ml_kem_vector_portable_vector_type_PortableVector 4727 compress_b8_f4( 4728 libcrux_ml_kem_vector_portable_vector_type_PortableVector a) 4729 { 4730 return compress_f4(a); 4731 } 4732 4733 /** 4734 A monomorphic instance of libcrux_ml_kem.serialize.compress_then_serialize_5 4735 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 4736 with const generics 4737 4738 */ 4739 static KRML_MUSTINLINE void 4740 compress_then_serialize_5_ea( 4741 libcrux_ml_kem_polynomial_PolynomialRingElement_1d re, 4742 Eurydice_slice serialized) 4743 { 4744 for (size_t i = (size_t)0U; i < VECTORS_IN_RING_ELEMENT; i++) { 4745 size_t i0 = i; 4746 libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficients = 4747 compress_b8_f4( 4748 libcrux_ml_kem_vector_portable_to_unsigned_representative_b8( 4749 re.coefficients[i0])); 4750 uint8_t bytes[10U]; 4751 libcrux_ml_kem_vector_portable_serialize_5_b8(coefficients, bytes); 4752 Eurydice_slice_copy( 4753 Eurydice_slice_subslice3(serialized, (size_t)10U * i0, 4754 (size_t)10U * i0 + (size_t)10U, uint8_t *), 4755 Eurydice_array_to_slice((size_t)10U, bytes, uint8_t), uint8_t); 4756 } 4757 } 4758 4759 /** 4760 A monomorphic instance of 4761 libcrux_ml_kem.serialize.compress_then_serialize_ring_element_v with types 4762 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 4763 - K= 4 4764 - COMPRESSION_FACTOR= 5 4765 - OUT_LEN= 160 4766 */ 4767 static KRML_MUSTINLINE void 4768 compress_then_serialize_ring_element_v_00( 4769 libcrux_ml_kem_polynomial_PolynomialRingElement_1d re, Eurydice_slice out) 4770 { 4771 compress_then_serialize_5_ea(re, out); 4772 } 4773 4774 /** 4775 A monomorphic instance of libcrux_ml_kem.ind_cpa.encrypt_c2 4776 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 4777 with const generics 4778 - K= 4 4779 - V_COMPRESSION_FACTOR= 5 4780 - C2_LEN= 160 4781 */ 4782 static KRML_MUSTINLINE void 4783 encrypt_c2_00( 4784 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *t_as_ntt, 4785 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *r_as_ntt, 4786 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *error_2, 4787 uint8_t *message, Eurydice_slice ciphertext) 4788 { 4789 libcrux_ml_kem_polynomial_PolynomialRingElement_1d message_as_ring_element = 4790 deserialize_then_decompress_message_ea(message); 4791 libcrux_ml_kem_polynomial_PolynomialRingElement_1d v = 4792 compute_ring_element_v_d0(t_as_ntt, r_as_ntt, error_2, 4793 &message_as_ring_element); 4794 compress_then_serialize_ring_element_v_00(v, ciphertext); 4795 } 4796 4797 /** 4798 This function implements <strong>Algorithm 13</strong> of the 4799 NIST FIPS 203 specification; this is the Kyber CPA-PKE encryption algorithm. 4800 4801 Algorithm 13 is reproduced below: 4802 4803 ```plaintext 4804 Input: encryption key ekₚₖₑ ∈ 𝔹^{384k+32}. 4805 Input: message m ∈ 𝔹^{32}. 4806 Input: encryption randomness r ∈ 𝔹^{32}. 4807 Output: ciphertext c ∈ 𝔹^{32(dᵤk + dᵥ)}. 4808 4809 N ← 0 4810 t̂ ← ByteDecode₁₂(ekₚₖₑ[0:384k]) 4811 ρ ← ekₚₖₑ[384k: 384k + 32] 4812 for (i ← 0; i < k; i++) 4813 for(j ← 0; j < k; j++) 4814 Â[i,j] ← SampleNTT(XOF(ρ, i, j)) 4815 end for 4816 end for 4817 for(i ← 0; i < k; i++) 4818 r[i] ← SamplePolyCBD_{η₁}(PRF_{η₁}(r,N)) 4819 N ← N + 1 4820 end for 4821 for(i ← 0; i < k; i++) 4822 e₁[i] ← SamplePolyCBD_{η₂}(PRF_{η₂}(r,N)) 4823 N ← N + 1 4824 end for 4825 e₂ ← SamplePolyCBD_{η₂}(PRF_{η₂}(r,N)) 4826 r̂ ← NTT(r) 4827 u ← NTT-¹(Âᵀ ◦ r̂) + e₁ 4828 μ ← Decompress₁(ByteDecode₁(m))) 4829 v ← NTT-¹(t̂ᵀ ◦ rˆ) + e₂ + μ 4830 c₁ ← ByteEncode_{dᵤ}(Compress_{dᵤ}(u)) 4831 c₂ ← ByteEncode_{dᵥ}(Compress_{dᵥ}(v)) 4832 return c ← (c₁ ‖ c₂) 4833 ``` 4834 4835 The NIST FIPS 203 standard can be found at 4836 <https://csrc.nist.gov/pubs/fips/203/ipd>. 4837 */ 4838 /** 4839 A monomorphic instance of libcrux_ml_kem.ind_cpa.encrypt_unpacked 4840 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 4841 libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] with const 4842 generics 4843 - K= 4 4844 - CIPHERTEXT_SIZE= 1568 4845 - T_AS_NTT_ENCODED_SIZE= 1536 4846 - C1_LEN= 1408 4847 - C2_LEN= 160 4848 - U_COMPRESSION_FACTOR= 11 4849 - V_COMPRESSION_FACTOR= 5 4850 - BLOCK_LEN= 352 4851 - ETA1= 2 4852 - ETA1_RANDOMNESS_SIZE= 128 4853 - ETA2= 2 4854 - ETA2_RANDOMNESS_SIZE= 128 4855 */ 4856 static KRML_MUSTINLINE void 4857 encrypt_unpacked_2a( 4858 IndCpaPublicKeyUnpacked_af *public_key, uint8_t *message, 4859 Eurydice_slice randomness, uint8_t ret[1568U]) 4860 { 4861 uint8_t ciphertext[1568U] = { 0U }; 4862 tuple_08 uu____0 = 4863 encrypt_c1_85(randomness, public_key->A, 4864 Eurydice_array_to_subslice3(ciphertext, (size_t)0U, 4865 (size_t)1408U, uint8_t *)); 4866 libcrux_ml_kem_polynomial_PolynomialRingElement_1d r_as_ntt[4U]; 4867 memcpy( 4868 r_as_ntt, uu____0.fst, 4869 (size_t)4U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); 4870 libcrux_ml_kem_polynomial_PolynomialRingElement_1d error_2 = uu____0.snd; 4871 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *uu____1 = 4872 public_key->t_as_ntt; 4873 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *uu____2 = r_as_ntt; 4874 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *uu____3 = &error_2; 4875 uint8_t *uu____4 = message; 4876 encrypt_c2_00( 4877 uu____1, uu____2, uu____3, uu____4, 4878 Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, (size_t)1408U, 4879 uint8_t, size_t, uint8_t[])); 4880 memcpy(ret, ciphertext, (size_t)1568U * sizeof(uint8_t)); 4881 } 4882 4883 /** 4884 A monomorphic instance of libcrux_ml_kem.ind_cpa.encrypt 4885 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 4886 libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] with const 4887 generics 4888 - K= 4 4889 - CIPHERTEXT_SIZE= 1568 4890 - T_AS_NTT_ENCODED_SIZE= 1536 4891 - C1_LEN= 1408 4892 - C2_LEN= 160 4893 - U_COMPRESSION_FACTOR= 11 4894 - V_COMPRESSION_FACTOR= 5 4895 - BLOCK_LEN= 352 4896 - ETA1= 2 4897 - ETA1_RANDOMNESS_SIZE= 128 4898 - ETA2= 2 4899 - ETA2_RANDOMNESS_SIZE= 128 4900 */ 4901 static KRML_MUSTINLINE void 4902 encrypt_2a0(Eurydice_slice public_key, 4903 uint8_t *message, 4904 Eurydice_slice randomness, 4905 uint8_t ret[1568U]) 4906 { 4907 IndCpaPublicKeyUnpacked_af unpacked_public_key = 4908 build_unpacked_public_key_3f0(public_key); 4909 uint8_t ret0[1568U]; 4910 encrypt_unpacked_2a(&unpacked_public_key, message, randomness, ret0); 4911 memcpy(ret, ret0, (size_t)1568U * sizeof(uint8_t)); 4912 } 4913 4914 /** 4915 This function found in impl {libcrux_ml_kem::variant::Variant for 4916 libcrux_ml_kem::variant::MlKem} 4917 */ 4918 /** 4919 A monomorphic instance of libcrux_ml_kem.variant.kdf_39 4920 with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] 4921 with const generics 4922 - K= 4 4923 - CIPHERTEXT_SIZE= 1568 4924 */ 4925 static KRML_MUSTINLINE void 4926 kdf_39_60(Eurydice_slice shared_secret, 4927 uint8_t ret[32U]) 4928 { 4929 uint8_t out[32U] = { 0U }; 4930 Eurydice_slice_copy(Eurydice_array_to_slice((size_t)32U, out, uint8_t), 4931 shared_secret, uint8_t); 4932 memcpy(ret, out, (size_t)32U * sizeof(uint8_t)); 4933 } 4934 4935 /** 4936 A monomorphic instance of libcrux_ml_kem.ind_cca.encapsulate 4937 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 4938 libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]], 4939 libcrux_ml_kem_variant_MlKem with const generics 4940 - K= 4 4941 - CIPHERTEXT_SIZE= 1568 4942 - PUBLIC_KEY_SIZE= 1568 4943 - T_AS_NTT_ENCODED_SIZE= 1536 4944 - C1_SIZE= 1408 4945 - C2_SIZE= 160 4946 - VECTOR_U_COMPRESSION_FACTOR= 11 4947 - VECTOR_V_COMPRESSION_FACTOR= 5 4948 - C1_BLOCK_SIZE= 352 4949 - ETA1= 2 4950 - ETA1_RANDOMNESS_SIZE= 128 4951 - ETA2= 2 4952 - ETA2_RANDOMNESS_SIZE= 128 4953 */ 4954 tuple_fa 4955 libcrux_ml_kem_ind_cca_encapsulate_ca0( 4956 libcrux_ml_kem_types_MlKemPublicKey_64 *public_key, uint8_t *randomness) 4957 { 4958 uint8_t randomness0[32U]; 4959 entropy_preprocess_39_03( 4960 Eurydice_array_to_slice((size_t)32U, randomness, uint8_t), randomness0); 4961 uint8_t to_hash[64U]; 4962 libcrux_ml_kem_utils_into_padded_array_24( 4963 Eurydice_array_to_slice((size_t)32U, randomness0, uint8_t), to_hash); 4964 Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( 4965 (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, 4966 size_t, uint8_t[]); 4967 uint8_t ret0[32U]; 4968 H_4a_ac(Eurydice_array_to_slice( 4969 (size_t)1568U, libcrux_ml_kem_types_as_slice_e6_af(public_key), 4970 uint8_t), 4971 ret0); 4972 Eurydice_slice_copy( 4973 uu____0, Eurydice_array_to_slice((size_t)32U, ret0, uint8_t), uint8_t); 4974 uint8_t hashed[64U]; 4975 G_4a_ac(Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t), hashed); 4976 Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( 4977 Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), 4978 LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, 4979 Eurydice_slice_uint8_t_x2); 4980 Eurydice_slice shared_secret = uu____1.fst; 4981 Eurydice_slice pseudorandomness = uu____1.snd; 4982 uint8_t ciphertext[1568U]; 4983 encrypt_2a0(Eurydice_array_to_slice( 4984 (size_t)1568U, 4985 libcrux_ml_kem_types_as_slice_e6_af(public_key), uint8_t), 4986 randomness0, pseudorandomness, ciphertext); 4987 /* Passing arrays by value in Rust generates a copy in C */ 4988 uint8_t copy_of_ciphertext[1568U]; 4989 memcpy(copy_of_ciphertext, ciphertext, (size_t)1568U * sizeof(uint8_t)); 4990 tuple_fa lit; 4991 lit.fst = libcrux_ml_kem_types_from_e0_af(copy_of_ciphertext); 4992 uint8_t ret[32U]; 4993 kdf_39_60(shared_secret, ret); 4994 memcpy(lit.snd, ret, (size_t)32U * sizeof(uint8_t)); 4995 return lit; 4996 } 4997 4998 /** 4999 This function found in impl {core::ops::function::FnMut<(usize), 5000 libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0, 5001 TraitClause@1]> for libcrux_ml_kem::ind_cpa::decrypt::closure<Vector, K, 5002 CIPHERTEXT_SIZE, VECTOR_U_ENCODED_SIZE, U_COMPRESSION_FACTOR, 5003 V_COMPRESSION_FACTOR>[TraitClause@0, TraitClause@1]} 5004 */ 5005 /** 5006 A monomorphic instance of libcrux_ml_kem.ind_cpa.decrypt.call_mut_0b 5007 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 5008 with const generics 5009 - K= 4 5010 - CIPHERTEXT_SIZE= 1568 5011 - VECTOR_U_ENCODED_SIZE= 1408 5012 - U_COMPRESSION_FACTOR= 11 5013 - V_COMPRESSION_FACTOR= 5 5014 */ 5015 static libcrux_ml_kem_polynomial_PolynomialRingElement_1d 5016 call_mut_0b_7d( 5017 void **_) 5018 { 5019 return ZERO_d6_ea(); 5020 } 5021 5022 /** 5023 A monomorphic instance of 5024 libcrux_ml_kem.serialize.deserialize_to_uncompressed_ring_element with types 5025 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 5026 5027 */ 5028 static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d 5029 deserialize_to_uncompressed_ring_element_ea(Eurydice_slice serialized) 5030 { 5031 libcrux_ml_kem_polynomial_PolynomialRingElement_1d re = ZERO_d6_ea(); 5032 for (size_t i = (size_t)0U; 5033 i < Eurydice_slice_len(serialized, uint8_t) / (size_t)24U; i++) { 5034 size_t i0 = i; 5035 Eurydice_slice bytes = 5036 Eurydice_slice_subslice3(serialized, i0 * (size_t)24U, 5037 i0 * (size_t)24U + (size_t)24U, uint8_t *); 5038 libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = 5039 libcrux_ml_kem_vector_portable_deserialize_12_b8(bytes); 5040 re.coefficients[i0] = uu____0; 5041 } 5042 return re; 5043 } 5044 5045 /** 5046 Call [`deserialize_to_uncompressed_ring_element`] for each ring element. 5047 */ 5048 /** 5049 A monomorphic instance of libcrux_ml_kem.ind_cpa.deserialize_vector 5050 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 5051 with const generics 5052 - K= 4 5053 */ 5054 static KRML_MUSTINLINE void 5055 deserialize_vector_d0( 5056 Eurydice_slice secret_key, 5057 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *secret_as_ntt) 5058 { 5059 KRML_MAYBE_FOR4( 5060 i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; 5061 libcrux_ml_kem_polynomial_PolynomialRingElement_1d uu____0 = 5062 deserialize_to_uncompressed_ring_element_ea(Eurydice_slice_subslice3( 5063 secret_key, i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, 5064 (i0 + (size_t)1U) * 5065 LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, 5066 uint8_t *)); 5067 secret_as_ntt[i0] = uu____0;); 5068 } 5069 5070 /** 5071 This function found in impl {core::ops::function::FnMut<(usize), 5072 libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0, 5073 TraitClause@1]> for 5074 libcrux_ml_kem::ind_cpa::deserialize_then_decompress_u::closure<Vector, K, 5075 CIPHERTEXT_SIZE, U_COMPRESSION_FACTOR>[TraitClause@0, TraitClause@1]} 5076 */ 5077 /** 5078 A monomorphic instance of 5079 libcrux_ml_kem.ind_cpa.deserialize_then_decompress_u.call_mut_35 with types 5080 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 5081 - K= 4 5082 - CIPHERTEXT_SIZE= 1568 5083 - U_COMPRESSION_FACTOR= 11 5084 */ 5085 static libcrux_ml_kem_polynomial_PolynomialRingElement_1d 5086 call_mut_35_00( 5087 void **_) 5088 { 5089 return ZERO_d6_ea(); 5090 } 5091 5092 /** 5093 A monomorphic instance of 5094 libcrux_ml_kem.vector.portable.compress.decompress_ciphertext_coefficient with 5095 const generics 5096 - COEFFICIENT_BITS= 10 5097 */ 5098 static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 5099 decompress_ciphertext_coefficient_ef( 5100 libcrux_ml_kem_vector_portable_vector_type_PortableVector a) 5101 { 5102 for (size_t i = (size_t)0U; 5103 i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { 5104 size_t i0 = i; 5105 int32_t decompressed = 5106 libcrux_secrets_int_as_i32_f5(a.elements[i0]) * 5107 libcrux_secrets_int_as_i32_f5( 5108 libcrux_secrets_int_public_integers_classify_27_39( 5109 LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); 5110 decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)10); 5111 decompressed = decompressed >> (uint32_t)((int32_t)10 + (int32_t)1); 5112 a.elements[i0] = libcrux_secrets_int_as_i16_36(decompressed); 5113 } 5114 return a; 5115 } 5116 5117 /** 5118 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 5119 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 5120 */ 5121 /** 5122 A monomorphic instance of 5123 libcrux_ml_kem.vector.portable.decompress_ciphertext_coefficient_b8 with const 5124 generics 5125 - COEFFICIENT_BITS= 10 5126 */ 5127 static libcrux_ml_kem_vector_portable_vector_type_PortableVector 5128 decompress_ciphertext_coefficient_b8_ef( 5129 libcrux_ml_kem_vector_portable_vector_type_PortableVector a) 5130 { 5131 return decompress_ciphertext_coefficient_ef(a); 5132 } 5133 5134 /** 5135 A monomorphic instance of 5136 libcrux_ml_kem.serialize.deserialize_then_decompress_10 with types 5137 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 5138 5139 */ 5140 static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d 5141 deserialize_then_decompress_10_ea(Eurydice_slice serialized) 5142 { 5143 libcrux_ml_kem_polynomial_PolynomialRingElement_1d re = ZERO_d6_ea(); 5144 for (size_t i = (size_t)0U; 5145 i < Eurydice_slice_len(serialized, uint8_t) / (size_t)20U; i++) { 5146 size_t i0 = i; 5147 Eurydice_slice bytes = 5148 Eurydice_slice_subslice3(serialized, i0 * (size_t)20U, 5149 i0 * (size_t)20U + (size_t)20U, uint8_t *); 5150 libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = 5151 libcrux_ml_kem_vector_portable_deserialize_10_b8(bytes); 5152 libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = 5153 decompress_ciphertext_coefficient_b8_ef(coefficient); 5154 re.coefficients[i0] = uu____0; 5155 } 5156 return re; 5157 } 5158 5159 /** 5160 A monomorphic instance of 5161 libcrux_ml_kem.vector.portable.compress.decompress_ciphertext_coefficient with 5162 const generics 5163 - COEFFICIENT_BITS= 11 5164 */ 5165 static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 5166 decompress_ciphertext_coefficient_c4( 5167 libcrux_ml_kem_vector_portable_vector_type_PortableVector a) 5168 { 5169 for (size_t i = (size_t)0U; 5170 i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { 5171 size_t i0 = i; 5172 int32_t decompressed = 5173 libcrux_secrets_int_as_i32_f5(a.elements[i0]) * 5174 libcrux_secrets_int_as_i32_f5( 5175 libcrux_secrets_int_public_integers_classify_27_39( 5176 LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); 5177 decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)11); 5178 decompressed = decompressed >> (uint32_t)((int32_t)11 + (int32_t)1); 5179 a.elements[i0] = libcrux_secrets_int_as_i16_36(decompressed); 5180 } 5181 return a; 5182 } 5183 5184 /** 5185 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 5186 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 5187 */ 5188 /** 5189 A monomorphic instance of 5190 libcrux_ml_kem.vector.portable.decompress_ciphertext_coefficient_b8 with const 5191 generics 5192 - COEFFICIENT_BITS= 11 5193 */ 5194 static libcrux_ml_kem_vector_portable_vector_type_PortableVector 5195 decompress_ciphertext_coefficient_b8_c4( 5196 libcrux_ml_kem_vector_portable_vector_type_PortableVector a) 5197 { 5198 return decompress_ciphertext_coefficient_c4(a); 5199 } 5200 5201 /** 5202 A monomorphic instance of 5203 libcrux_ml_kem.serialize.deserialize_then_decompress_11 with types 5204 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 5205 5206 */ 5207 static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d 5208 deserialize_then_decompress_11_ea(Eurydice_slice serialized) 5209 { 5210 libcrux_ml_kem_polynomial_PolynomialRingElement_1d re = ZERO_d6_ea(); 5211 for (size_t i = (size_t)0U; 5212 i < Eurydice_slice_len(serialized, uint8_t) / (size_t)22U; i++) { 5213 size_t i0 = i; 5214 Eurydice_slice bytes = 5215 Eurydice_slice_subslice3(serialized, i0 * (size_t)22U, 5216 i0 * (size_t)22U + (size_t)22U, uint8_t *); 5217 libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = 5218 libcrux_ml_kem_vector_portable_deserialize_11_b8(bytes); 5219 libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = 5220 decompress_ciphertext_coefficient_b8_c4(coefficient); 5221 re.coefficients[i0] = uu____0; 5222 } 5223 return re; 5224 } 5225 5226 /** 5227 A monomorphic instance of 5228 libcrux_ml_kem.serialize.deserialize_then_decompress_ring_element_u with types 5229 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 5230 - COMPRESSION_FACTOR= 11 5231 */ 5232 static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d 5233 deserialize_then_decompress_ring_element_u_5e(Eurydice_slice serialized) 5234 { 5235 return deserialize_then_decompress_11_ea(serialized); 5236 } 5237 5238 /** 5239 A monomorphic instance of libcrux_ml_kem.ntt.ntt_vector_u 5240 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 5241 with const generics 5242 - VECTOR_U_COMPRESSION_FACTOR= 11 5243 */ 5244 static KRML_MUSTINLINE void 5245 ntt_vector_u_5e( 5246 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re) 5247 { 5248 size_t zeta_i = (size_t)0U; 5249 ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)7U); 5250 ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)6U); 5251 ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)5U); 5252 ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)4U); 5253 ntt_at_layer_3_ea(&zeta_i, re); 5254 ntt_at_layer_2_ea(&zeta_i, re); 5255 ntt_at_layer_1_ea(&zeta_i, re); 5256 poly_barrett_reduce_d6_ea(re); 5257 } 5258 5259 /** 5260 Call [`deserialize_then_decompress_ring_element_u`] on each ring element 5261 in the `ciphertext`. 5262 */ 5263 /** 5264 A monomorphic instance of libcrux_ml_kem.ind_cpa.deserialize_then_decompress_u 5265 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 5266 with const generics 5267 - K= 4 5268 - CIPHERTEXT_SIZE= 1568 5269 - U_COMPRESSION_FACTOR= 11 5270 */ 5271 static KRML_MUSTINLINE void 5272 deserialize_then_decompress_u_00( 5273 uint8_t *ciphertext, 5274 libcrux_ml_kem_polynomial_PolynomialRingElement_1d ret[4U]) 5275 { 5276 libcrux_ml_kem_polynomial_PolynomialRingElement_1d u_as_ntt[4U]; 5277 KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, 5278 /* original Rust expression is not an lvalue in C */ 5279 void *lvalue = (void *)0U; 5280 u_as_ntt[i] = call_mut_35_00(&lvalue);); 5281 for (size_t i = (size_t)0U; 5282 i < Eurydice_slice_len( 5283 Eurydice_array_to_slice((size_t)1568U, ciphertext, uint8_t), 5284 uint8_t) / 5285 (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * 5286 (size_t)11U / (size_t)8U); 5287 i++) { 5288 size_t i0 = i; 5289 Eurydice_slice u_bytes = Eurydice_array_to_subslice3( 5290 ciphertext, 5291 i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * 5292 (size_t)11U / (size_t)8U), 5293 i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * 5294 (size_t)11U / (size_t)8U) + 5295 LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * 5296 (size_t)11U / (size_t)8U, 5297 uint8_t *); 5298 u_as_ntt[i0] = deserialize_then_decompress_ring_element_u_5e(u_bytes); 5299 ntt_vector_u_5e(&u_as_ntt[i0]); 5300 } 5301 memcpy( 5302 ret, u_as_ntt, 5303 (size_t)4U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); 5304 } 5305 5306 /** 5307 A monomorphic instance of 5308 libcrux_ml_kem.vector.portable.compress.decompress_ciphertext_coefficient with 5309 const generics 5310 - COEFFICIENT_BITS= 4 5311 */ 5312 static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 5313 decompress_ciphertext_coefficient_d1( 5314 libcrux_ml_kem_vector_portable_vector_type_PortableVector a) 5315 { 5316 for (size_t i = (size_t)0U; 5317 i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { 5318 size_t i0 = i; 5319 int32_t decompressed = 5320 libcrux_secrets_int_as_i32_f5(a.elements[i0]) * 5321 libcrux_secrets_int_as_i32_f5( 5322 libcrux_secrets_int_public_integers_classify_27_39( 5323 LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); 5324 decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)4); 5325 decompressed = decompressed >> (uint32_t)((int32_t)4 + (int32_t)1); 5326 a.elements[i0] = libcrux_secrets_int_as_i16_36(decompressed); 5327 } 5328 return a; 5329 } 5330 5331 /** 5332 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 5333 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 5334 */ 5335 /** 5336 A monomorphic instance of 5337 libcrux_ml_kem.vector.portable.decompress_ciphertext_coefficient_b8 with const 5338 generics 5339 - COEFFICIENT_BITS= 4 5340 */ 5341 static libcrux_ml_kem_vector_portable_vector_type_PortableVector 5342 decompress_ciphertext_coefficient_b8_d1( 5343 libcrux_ml_kem_vector_portable_vector_type_PortableVector a) 5344 { 5345 return decompress_ciphertext_coefficient_d1(a); 5346 } 5347 5348 /** 5349 A monomorphic instance of libcrux_ml_kem.serialize.deserialize_then_decompress_4 5350 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 5351 with const generics 5352 5353 */ 5354 static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d 5355 deserialize_then_decompress_4_ea(Eurydice_slice serialized) 5356 { 5357 libcrux_ml_kem_polynomial_PolynomialRingElement_1d re = ZERO_d6_ea(); 5358 for (size_t i = (size_t)0U; 5359 i < Eurydice_slice_len(serialized, uint8_t) / (size_t)8U; i++) { 5360 size_t i0 = i; 5361 Eurydice_slice bytes = Eurydice_slice_subslice3( 5362 serialized, i0 * (size_t)8U, i0 * (size_t)8U + (size_t)8U, uint8_t *); 5363 libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = 5364 libcrux_ml_kem_vector_portable_deserialize_4_b8(bytes); 5365 libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = 5366 decompress_ciphertext_coefficient_b8_d1(coefficient); 5367 re.coefficients[i0] = uu____0; 5368 } 5369 return re; 5370 } 5371 5372 /** 5373 A monomorphic instance of 5374 libcrux_ml_kem.vector.portable.compress.decompress_ciphertext_coefficient with 5375 const generics 5376 - COEFFICIENT_BITS= 5 5377 */ 5378 static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector 5379 decompress_ciphertext_coefficient_f4( 5380 libcrux_ml_kem_vector_portable_vector_type_PortableVector a) 5381 { 5382 for (size_t i = (size_t)0U; 5383 i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { 5384 size_t i0 = i; 5385 int32_t decompressed = 5386 libcrux_secrets_int_as_i32_f5(a.elements[i0]) * 5387 libcrux_secrets_int_as_i32_f5( 5388 libcrux_secrets_int_public_integers_classify_27_39( 5389 LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); 5390 decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)5); 5391 decompressed = decompressed >> (uint32_t)((int32_t)5 + (int32_t)1); 5392 a.elements[i0] = libcrux_secrets_int_as_i16_36(decompressed); 5393 } 5394 return a; 5395 } 5396 5397 /** 5398 This function found in impl {libcrux_ml_kem::vector::traits::Operations for 5399 libcrux_ml_kem::vector::portable::vector_type::PortableVector} 5400 */ 5401 /** 5402 A monomorphic instance of 5403 libcrux_ml_kem.vector.portable.decompress_ciphertext_coefficient_b8 with const 5404 generics 5405 - COEFFICIENT_BITS= 5 5406 */ 5407 static libcrux_ml_kem_vector_portable_vector_type_PortableVector 5408 decompress_ciphertext_coefficient_b8_f4( 5409 libcrux_ml_kem_vector_portable_vector_type_PortableVector a) 5410 { 5411 return decompress_ciphertext_coefficient_f4(a); 5412 } 5413 5414 /** 5415 A monomorphic instance of libcrux_ml_kem.serialize.deserialize_then_decompress_5 5416 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 5417 with const generics 5418 5419 */ 5420 static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d 5421 deserialize_then_decompress_5_ea(Eurydice_slice serialized) 5422 { 5423 libcrux_ml_kem_polynomial_PolynomialRingElement_1d re = ZERO_d6_ea(); 5424 for (size_t i = (size_t)0U; 5425 i < Eurydice_slice_len(serialized, uint8_t) / (size_t)10U; i++) { 5426 size_t i0 = i; 5427 Eurydice_slice bytes = 5428 Eurydice_slice_subslice3(serialized, i0 * (size_t)10U, 5429 i0 * (size_t)10U + (size_t)10U, uint8_t *); 5430 re.coefficients[i0] = 5431 libcrux_ml_kem_vector_portable_deserialize_5_b8(bytes); 5432 libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____1 = 5433 decompress_ciphertext_coefficient_b8_f4(re.coefficients[i0]); 5434 re.coefficients[i0] = uu____1; 5435 } 5436 return re; 5437 } 5438 5439 /** 5440 A monomorphic instance of 5441 libcrux_ml_kem.serialize.deserialize_then_decompress_ring_element_v with types 5442 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 5443 - K= 4 5444 - COMPRESSION_FACTOR= 5 5445 */ 5446 static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d 5447 deserialize_then_decompress_ring_element_v_ff(Eurydice_slice serialized) 5448 { 5449 return deserialize_then_decompress_5_ea(serialized); 5450 } 5451 5452 /** 5453 A monomorphic instance of libcrux_ml_kem.polynomial.subtract_reduce 5454 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 5455 with const generics 5456 5457 */ 5458 static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d 5459 subtract_reduce_ea(libcrux_ml_kem_polynomial_PolynomialRingElement_1d *myself, 5460 libcrux_ml_kem_polynomial_PolynomialRingElement_1d b) 5461 { 5462 for (size_t i = (size_t)0U; i < VECTORS_IN_RING_ELEMENT; i++) { 5463 size_t i0 = i; 5464 libcrux_ml_kem_vector_portable_vector_type_PortableVector 5465 coefficient_normal_form = 5466 libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_b8( 5467 b.coefficients[i0], (int16_t)1441); 5468 libcrux_ml_kem_vector_portable_vector_type_PortableVector diff = 5469 libcrux_ml_kem_vector_portable_sub_b8(myself->coefficients[i0], 5470 &coefficient_normal_form); 5471 libcrux_ml_kem_vector_portable_vector_type_PortableVector red = 5472 libcrux_ml_kem_vector_portable_barrett_reduce_b8(diff); 5473 b.coefficients[i0] = red; 5474 } 5475 return b; 5476 } 5477 5478 /** 5479 This function found in impl 5480 {libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0, 5481 TraitClause@1]} 5482 */ 5483 /** 5484 A monomorphic instance of libcrux_ml_kem.polynomial.subtract_reduce_d6 5485 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 5486 with const generics 5487 5488 */ 5489 static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d 5490 subtract_reduce_d6_ea(libcrux_ml_kem_polynomial_PolynomialRingElement_1d *self, 5491 libcrux_ml_kem_polynomial_PolynomialRingElement_1d b) 5492 { 5493 return subtract_reduce_ea(self, b); 5494 } 5495 5496 /** 5497 The following functions compute various expressions involving 5498 vectors and matrices. The computation of these expressions has been 5499 abstracted away into these functions in order to save on loop iterations. 5500 Compute v − InverseNTT(sᵀ ◦ NTT(u)) 5501 */ 5502 /** 5503 A monomorphic instance of libcrux_ml_kem.matrix.compute_message 5504 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 5505 with const generics 5506 - K= 4 5507 */ 5508 static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d 5509 compute_message_d0( 5510 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *v, 5511 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *secret_as_ntt, 5512 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *u_as_ntt) 5513 { 5514 libcrux_ml_kem_polynomial_PolynomialRingElement_1d result = ZERO_d6_ea(); 5515 KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; 5516 libcrux_ml_kem_polynomial_PolynomialRingElement_1d product = 5517 ntt_multiply_d6_ea(&secret_as_ntt[i0], &u_as_ntt[i0]); 5518 add_to_ring_element_d6_d0(&result, &product);); 5519 invert_ntt_montgomery_d0(&result); 5520 return subtract_reduce_d6_ea(v, result); 5521 } 5522 5523 /** 5524 A monomorphic instance of 5525 libcrux_ml_kem.serialize.compress_then_serialize_message with types 5526 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 5527 5528 */ 5529 static KRML_MUSTINLINE void 5530 compress_then_serialize_message_ea( 5531 libcrux_ml_kem_polynomial_PolynomialRingElement_1d re, uint8_t ret[32U]) 5532 { 5533 uint8_t serialized[32U] = { 0U }; 5534 KRML_MAYBE_FOR16( 5535 i, (size_t)0U, (size_t)16U, (size_t)1U, size_t i0 = i; 5536 libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = 5537 to_unsigned_field_modulus_ea(re.coefficients[i0]); 5538 libcrux_ml_kem_vector_portable_vector_type_PortableVector 5539 coefficient_compressed = 5540 libcrux_ml_kem_vector_portable_compress_1_b8(coefficient); 5541 uint8_t bytes[2U]; libcrux_ml_kem_vector_portable_serialize_1_b8( 5542 coefficient_compressed, bytes); 5543 Eurydice_slice_copy( 5544 Eurydice_array_to_subslice3(serialized, (size_t)2U * i0, 5545 (size_t)2U * i0 + (size_t)2U, uint8_t *), 5546 Eurydice_array_to_slice((size_t)2U, bytes, uint8_t), uint8_t);); 5547 memcpy(ret, serialized, (size_t)32U * sizeof(uint8_t)); 5548 } 5549 5550 /** 5551 This function implements <strong>Algorithm 14</strong> of the 5552 NIST FIPS 203 specification; this is the Kyber CPA-PKE decryption algorithm. 5553 5554 Algorithm 14 is reproduced below: 5555 5556 ```plaintext 5557 Input: decryption key dkₚₖₑ ∈ 𝔹^{384k}. 5558 Input: ciphertext c ∈ 𝔹^{32(dᵤk + dᵥ)}. 5559 Output: message m ∈ 𝔹^{32}. 5560 5561 c₁ ← c[0 : 32dᵤk] 5562 c₂ ← c[32dᵤk : 32(dᵤk + dᵥ)] 5563 u ← Decompress_{dᵤ}(ByteDecode_{dᵤ}(c₁)) 5564 v ← Decompress_{dᵥ}(ByteDecode_{dᵥ}(c₂)) 5565 ŝ ← ByteDecode₁₂(dkₚₖₑ) 5566 w ← v - NTT-¹(ŝᵀ ◦ NTT(u)) 5567 m ← ByteEncode₁(Compress₁(w)) 5568 return m 5569 ``` 5570 5571 The NIST FIPS 203 standard can be found at 5572 <https://csrc.nist.gov/pubs/fips/203/ipd>. 5573 */ 5574 /** 5575 A monomorphic instance of libcrux_ml_kem.ind_cpa.decrypt_unpacked 5576 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 5577 with const generics 5578 - K= 4 5579 - CIPHERTEXT_SIZE= 1568 5580 - VECTOR_U_ENCODED_SIZE= 1408 5581 - U_COMPRESSION_FACTOR= 11 5582 - V_COMPRESSION_FACTOR= 5 5583 */ 5584 static KRML_MUSTINLINE void 5585 decrypt_unpacked_7d( 5586 IndCpaPrivateKeyUnpacked_af *secret_key, uint8_t *ciphertext, 5587 uint8_t ret[32U]) 5588 { 5589 libcrux_ml_kem_polynomial_PolynomialRingElement_1d u_as_ntt[4U]; 5590 deserialize_then_decompress_u_00(ciphertext, u_as_ntt); 5591 libcrux_ml_kem_polynomial_PolynomialRingElement_1d v = 5592 deserialize_then_decompress_ring_element_v_ff( 5593 Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, 5594 (size_t)1408U, uint8_t, size_t, 5595 uint8_t[])); 5596 libcrux_ml_kem_polynomial_PolynomialRingElement_1d message = 5597 compute_message_d0(&v, secret_key->secret_as_ntt, u_as_ntt); 5598 uint8_t ret0[32U]; 5599 compress_then_serialize_message_ea(message, ret0); 5600 memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); 5601 } 5602 5603 /** 5604 A monomorphic instance of libcrux_ml_kem.ind_cpa.decrypt 5605 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 5606 with const generics 5607 - K= 4 5608 - CIPHERTEXT_SIZE= 1568 5609 - VECTOR_U_ENCODED_SIZE= 1408 5610 - U_COMPRESSION_FACTOR= 11 5611 - V_COMPRESSION_FACTOR= 5 5612 */ 5613 static KRML_MUSTINLINE void 5614 decrypt_7d(Eurydice_slice secret_key, 5615 uint8_t *ciphertext, uint8_t ret[32U]) 5616 { 5617 IndCpaPrivateKeyUnpacked_af secret_key_unpacked; 5618 libcrux_ml_kem_polynomial_PolynomialRingElement_1d ret0[4U]; 5619 KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, 5620 /* original Rust expression is not an lvalue in C */ 5621 void *lvalue = (void *)0U; 5622 ret0[i] = call_mut_0b_7d(&lvalue);); 5623 memcpy( 5624 secret_key_unpacked.secret_as_ntt, ret0, 5625 (size_t)4U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); 5626 deserialize_vector_d0(secret_key, secret_key_unpacked.secret_as_ntt); 5627 uint8_t ret1[32U]; 5628 decrypt_unpacked_7d(&secret_key_unpacked, ciphertext, ret1); 5629 memcpy(ret, ret1, (size_t)32U * sizeof(uint8_t)); 5630 } 5631 5632 /** 5633 A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRF 5634 with const generics 5635 - LEN= 32 5636 */ 5637 static inline void 5638 PRF_9e(Eurydice_slice input, uint8_t ret[32U]) 5639 { 5640 uint8_t digest[32U] = { 0U }; 5641 libcrux_sha3_portable_shake256( 5642 Eurydice_array_to_slice((size_t)32U, digest, uint8_t), input); 5643 memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); 5644 } 5645 5646 /** 5647 This function found in impl {libcrux_ml_kem::hash_functions::Hash<K> for 5648 libcrux_ml_kem::hash_functions::portable::PortableHash<K>} 5649 */ 5650 /** 5651 A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRF_4a 5652 with const generics 5653 - K= 4 5654 - LEN= 32 5655 */ 5656 static inline void 5657 PRF_4a_44(Eurydice_slice input, uint8_t ret[32U]) 5658 { 5659 PRF_9e(input, ret); 5660 } 5661 5662 /** 5663 This code verifies on some machines, runs out of memory on others 5664 */ 5665 /** 5666 A monomorphic instance of libcrux_ml_kem.ind_cca.decapsulate 5667 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 5668 libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]], 5669 libcrux_ml_kem_variant_MlKem with const generics 5670 - K= 4 5671 - SECRET_KEY_SIZE= 3168 5672 - CPA_SECRET_KEY_SIZE= 1536 5673 - PUBLIC_KEY_SIZE= 1568 5674 - CIPHERTEXT_SIZE= 1568 5675 - T_AS_NTT_ENCODED_SIZE= 1536 5676 - C1_SIZE= 1408 5677 - C2_SIZE= 160 5678 - VECTOR_U_COMPRESSION_FACTOR= 11 5679 - VECTOR_V_COMPRESSION_FACTOR= 5 5680 - C1_BLOCK_SIZE= 352 5681 - ETA1= 2 5682 - ETA1_RANDOMNESS_SIZE= 128 5683 - ETA2= 2 5684 - ETA2_RANDOMNESS_SIZE= 128 5685 - IMPLICIT_REJECTION_HASH_INPUT_SIZE= 1600 5686 */ 5687 void 5688 libcrux_ml_kem_ind_cca_decapsulate_620( 5689 libcrux_ml_kem_types_MlKemPrivateKey_83 *private_key, 5690 libcrux_ml_kem_types_MlKemCiphertext_64 *ciphertext, uint8_t ret[32U]) 5691 { 5692 Eurydice_slice_uint8_t_x4 uu____0 = 5693 libcrux_ml_kem_types_unpack_private_key_1f( 5694 Eurydice_array_to_slice((size_t)3168U, private_key->value, uint8_t)); 5695 Eurydice_slice ind_cpa_secret_key = uu____0.fst; 5696 Eurydice_slice ind_cpa_public_key = uu____0.snd; 5697 Eurydice_slice ind_cpa_public_key_hash = uu____0.thd; 5698 Eurydice_slice implicit_rejection_value = uu____0.f3; 5699 uint8_t decrypted[32U]; 5700 decrypt_7d(ind_cpa_secret_key, ciphertext->value, decrypted); 5701 uint8_t to_hash0[64U]; 5702 libcrux_ml_kem_utils_into_padded_array_24( 5703 Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t), to_hash0); 5704 Eurydice_slice_copy( 5705 Eurydice_array_to_subslice_from( 5706 (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, 5707 uint8_t, size_t, uint8_t[]), 5708 ind_cpa_public_key_hash, uint8_t); 5709 uint8_t hashed[64U]; 5710 G_4a_ac(Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t), hashed); 5711 Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( 5712 Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), 5713 LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, 5714 Eurydice_slice_uint8_t_x2); 5715 Eurydice_slice shared_secret0 = uu____1.fst; 5716 Eurydice_slice pseudorandomness = uu____1.snd; 5717 uint8_t to_hash[1600U]; 5718 libcrux_ml_kem_utils_into_padded_array_7f(implicit_rejection_value, to_hash); 5719 Eurydice_slice uu____2 = Eurydice_array_to_subslice_from( 5720 (size_t)1600U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, 5721 uint8_t, size_t, uint8_t[]); 5722 Eurydice_slice_copy(uu____2, libcrux_ml_kem_types_as_ref_d3_af(ciphertext), 5723 uint8_t); 5724 uint8_t implicit_rejection_shared_secret0[32U]; 5725 PRF_4a_44(Eurydice_array_to_slice((size_t)1600U, to_hash, uint8_t), 5726 implicit_rejection_shared_secret0); 5727 uint8_t expected_ciphertext[1568U]; 5728 encrypt_2a0(ind_cpa_public_key, decrypted, pseudorandomness, 5729 expected_ciphertext); 5730 uint8_t implicit_rejection_shared_secret[32U]; 5731 kdf_39_60(Eurydice_array_to_slice((size_t)32U, 5732 implicit_rejection_shared_secret0, uint8_t), 5733 implicit_rejection_shared_secret); 5734 uint8_t shared_secret[32U]; 5735 kdf_39_60(shared_secret0, shared_secret); 5736 uint8_t ret0[32U]; 5737 libcrux_ml_kem_constant_time_ops_compare_ciphertexts_select_shared_secret_in_constant_time( 5738 libcrux_ml_kem_types_as_ref_d3_af(ciphertext), 5739 Eurydice_array_to_slice((size_t)1568U, expected_ciphertext, uint8_t), 5740 Eurydice_array_to_slice((size_t)32U, shared_secret, uint8_t), 5741 Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, 5742 uint8_t), 5743 ret0); 5744 memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); 5745 } 5746 5747 /** 5748 This function found in impl {core::ops::function::FnMut<(usize), 5749 libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0, 5750 TraitClause@1]> for 5751 libcrux_ml_kem::serialize::deserialize_ring_elements_reduced_out::closure<Vector, 5752 K>[TraitClause@0, TraitClause@1]} 5753 */ 5754 /** 5755 A monomorphic instance of 5756 libcrux_ml_kem.serialize.deserialize_ring_elements_reduced_out.call_mut_0b with 5757 types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const 5758 generics 5759 - K= 3 5760 */ 5761 static libcrux_ml_kem_polynomial_PolynomialRingElement_1d 5762 call_mut_0b_1b( 5763 void **_) 5764 { 5765 return ZERO_d6_ea(); 5766 } 5767 5768 /** 5769 See [deserialize_ring_elements_reduced_out]. 5770 */ 5771 /** 5772 A monomorphic instance of 5773 libcrux_ml_kem.serialize.deserialize_ring_elements_reduced with types 5774 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 5775 - K= 3 5776 */ 5777 static KRML_MUSTINLINE void 5778 deserialize_ring_elements_reduced_1b( 5779 Eurydice_slice public_key, 5780 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *deserialized_pk) 5781 { 5782 for (size_t i = (size_t)0U; 5783 i < Eurydice_slice_len(public_key, uint8_t) / 5784 LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; 5785 i++) { 5786 size_t i0 = i; 5787 Eurydice_slice ring_element = Eurydice_slice_subslice3( 5788 public_key, i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, 5789 i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + 5790 LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, 5791 uint8_t *); 5792 libcrux_ml_kem_polynomial_PolynomialRingElement_1d uu____0 = 5793 deserialize_to_reduced_ring_element_ea(ring_element); 5794 deserialized_pk[i0] = uu____0; 5795 } 5796 } 5797 5798 /** 5799 This function deserializes ring elements and reduces the result by the field 5800 modulus. 5801 5802 This function MUST NOT be used on secret inputs. 5803 */ 5804 /** 5805 A monomorphic instance of 5806 libcrux_ml_kem.serialize.deserialize_ring_elements_reduced_out with types 5807 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 5808 - K= 3 5809 */ 5810 static KRML_MUSTINLINE void 5811 deserialize_ring_elements_reduced_out_1b( 5812 Eurydice_slice public_key, 5813 libcrux_ml_kem_polynomial_PolynomialRingElement_1d ret[3U]) 5814 { 5815 libcrux_ml_kem_polynomial_PolynomialRingElement_1d deserialized_pk[3U]; 5816 KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, 5817 /* original Rust expression is not an lvalue in C */ 5818 void *lvalue = (void *)0U; 5819 deserialized_pk[i] = call_mut_0b_1b(&lvalue);); 5820 deserialize_ring_elements_reduced_1b(public_key, deserialized_pk); 5821 memcpy( 5822 ret, deserialized_pk, 5823 (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); 5824 } 5825 5826 /** 5827 Call [`serialize_uncompressed_ring_element`] for each ring element. 5828 */ 5829 /** 5830 A monomorphic instance of libcrux_ml_kem.ind_cpa.serialize_vector 5831 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 5832 with const generics 5833 - K= 3 5834 */ 5835 static KRML_MUSTINLINE void 5836 serialize_vector_1b( 5837 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *key, 5838 Eurydice_slice out) 5839 { 5840 for (size_t i = (size_t)0U; 5841 i < Eurydice_slice_len( 5842 Eurydice_array_to_slice( 5843 (size_t)3U, key, 5844 libcrux_ml_kem_polynomial_PolynomialRingElement_1d), 5845 libcrux_ml_kem_polynomial_PolynomialRingElement_1d); 5846 i++) { 5847 size_t i0 = i; 5848 libcrux_ml_kem_polynomial_PolynomialRingElement_1d re = key[i0]; 5849 Eurydice_slice uu____0 = Eurydice_slice_subslice3( 5850 out, i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, 5851 (i0 + (size_t)1U) * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, 5852 uint8_t *); 5853 uint8_t ret[384U]; 5854 serialize_uncompressed_ring_element_ea(&re, ret); 5855 Eurydice_slice_copy( 5856 uu____0, Eurydice_array_to_slice((size_t)384U, ret, uint8_t), uint8_t); 5857 } 5858 } 5859 5860 /** 5861 Concatenate `t` and `ρ` into the public key. 5862 */ 5863 /** 5864 A monomorphic instance of libcrux_ml_kem.ind_cpa.serialize_public_key_mut 5865 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 5866 with const generics 5867 - K= 3 5868 - PUBLIC_KEY_SIZE= 1184 5869 */ 5870 static KRML_MUSTINLINE void 5871 serialize_public_key_mut_89( 5872 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *t_as_ntt, 5873 Eurydice_slice seed_for_a, uint8_t *serialized) 5874 { 5875 serialize_vector_1b( 5876 t_as_ntt, 5877 Eurydice_array_to_subslice3( 5878 serialized, (size_t)0U, 5879 libcrux_ml_kem_constants_ranked_bytes_per_ring_element((size_t)3U), 5880 uint8_t *)); 5881 Eurydice_slice_copy( 5882 Eurydice_array_to_subslice_from( 5883 (size_t)1184U, serialized, 5884 libcrux_ml_kem_constants_ranked_bytes_per_ring_element((size_t)3U), 5885 uint8_t, size_t, uint8_t[]), 5886 seed_for_a, uint8_t); 5887 } 5888 5889 /** 5890 Concatenate `t` and `ρ` into the public key. 5891 */ 5892 /** 5893 A monomorphic instance of libcrux_ml_kem.ind_cpa.serialize_public_key 5894 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 5895 with const generics 5896 - K= 3 5897 - PUBLIC_KEY_SIZE= 1184 5898 */ 5899 static KRML_MUSTINLINE void 5900 serialize_public_key_89( 5901 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *t_as_ntt, 5902 Eurydice_slice seed_for_a, uint8_t ret[1184U]) 5903 { 5904 uint8_t public_key_serialized[1184U] = { 0U }; 5905 serialize_public_key_mut_89(t_as_ntt, seed_for_a, public_key_serialized); 5906 memcpy(ret, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); 5907 } 5908 5909 /** 5910 Validate an ML-KEM public key. 5911 5912 This implements the Modulus check in 7.2 2. 5913 Note that the size check in 7.2 1 is covered by the `PUBLIC_KEY_SIZE` in the 5914 `public_key` type. 5915 */ 5916 /** 5917 A monomorphic instance of libcrux_ml_kem.ind_cca.validate_public_key 5918 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 5919 with const generics 5920 - K= 3 5921 - PUBLIC_KEY_SIZE= 1184 5922 */ 5923 bool 5924 libcrux_ml_kem_ind_cca_validate_public_key_89(uint8_t *public_key) 5925 { 5926 libcrux_ml_kem_polynomial_PolynomialRingElement_1d deserialized_pk[3U]; 5927 deserialize_ring_elements_reduced_out_1b( 5928 Eurydice_array_to_subslice_to( 5929 (size_t)1184U, public_key, 5930 libcrux_ml_kem_constants_ranked_bytes_per_ring_element((size_t)3U), 5931 uint8_t, size_t, uint8_t[]), 5932 deserialized_pk); 5933 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *uu____0 = deserialized_pk; 5934 uint8_t public_key_serialized[1184U]; 5935 serialize_public_key_89( 5936 uu____0, 5937 Eurydice_array_to_subslice_from( 5938 (size_t)1184U, public_key, 5939 libcrux_ml_kem_constants_ranked_bytes_per_ring_element((size_t)3U), 5940 uint8_t, size_t, uint8_t[]), 5941 public_key_serialized); 5942 return Eurydice_array_eq((size_t)1184U, public_key, public_key_serialized, 5943 uint8_t); 5944 } 5945 5946 /** 5947 This function found in impl {libcrux_ml_kem::hash_functions::Hash<K> for 5948 libcrux_ml_kem::hash_functions::portable::PortableHash<K>} 5949 */ 5950 /** 5951 A monomorphic instance of libcrux_ml_kem.hash_functions.portable.H_4a 5952 with const generics 5953 - K= 3 5954 */ 5955 static inline void 5956 H_4a_e0(Eurydice_slice input, uint8_t ret[32U]) 5957 { 5958 libcrux_ml_kem_hash_functions_portable_H(input, ret); 5959 } 5960 5961 /** 5962 Validate an ML-KEM private key. 5963 5964 This implements the Hash check in 7.3 3. 5965 */ 5966 /** 5967 A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key_only 5968 with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] 5969 with const generics 5970 - K= 3 5971 - SECRET_KEY_SIZE= 2400 5972 */ 5973 bool 5974 libcrux_ml_kem_ind_cca_validate_private_key_only_d6( 5975 libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key) 5976 { 5977 uint8_t t[32U]; 5978 H_4a_e0(Eurydice_array_to_subslice3( 5979 private_key->value, (size_t)384U * (size_t)3U, 5980 (size_t)768U * (size_t)3U + (size_t)32U, uint8_t *), 5981 t); 5982 Eurydice_slice expected = Eurydice_array_to_subslice3( 5983 private_key->value, (size_t)768U * (size_t)3U + (size_t)32U, 5984 (size_t)768U * (size_t)3U + (size_t)64U, uint8_t *); 5985 return Eurydice_array_eq_slice((size_t)32U, t, &expected, uint8_t, bool); 5986 } 5987 5988 /** 5989 Validate an ML-KEM private key. 5990 5991 This implements the Hash check in 7.3 3. 5992 Note that the size checks in 7.2 1 and 2 are covered by the `SECRET_KEY_SIZE` 5993 and `CIPHERTEXT_SIZE` in the `private_key` and `ciphertext` types. 5994 */ 5995 /** 5996 A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key 5997 with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] 5998 with const generics 5999 - K= 3 6000 - SECRET_KEY_SIZE= 2400 6001 - CIPHERTEXT_SIZE= 1088 6002 */ 6003 bool 6004 libcrux_ml_kem_ind_cca_validate_private_key_37( 6005 libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, 6006 libcrux_ml_kem_mlkem768_MlKem768Ciphertext *_ciphertext) 6007 { 6008 return libcrux_ml_kem_ind_cca_validate_private_key_only_d6(private_key); 6009 } 6010 6011 /** 6012 A monomorphic instance of 6013 libcrux_ml_kem.ind_cpa.unpacked.IndCpaPrivateKeyUnpacked with types 6014 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 6015 - $3size_t 6016 */ 6017 typedef struct IndCpaPrivateKeyUnpacked_a0_s { 6018 libcrux_ml_kem_polynomial_PolynomialRingElement_1d secret_as_ntt[3U]; 6019 } IndCpaPrivateKeyUnpacked_a0; 6020 6021 /** 6022 This function found in impl {core::default::Default for 6023 libcrux_ml_kem::ind_cpa::unpacked::IndCpaPrivateKeyUnpacked<Vector, 6024 K>[TraitClause@0, TraitClause@1]} 6025 */ 6026 /** 6027 A monomorphic instance of libcrux_ml_kem.ind_cpa.unpacked.default_70 6028 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 6029 with const generics 6030 - K= 3 6031 */ 6032 static IndCpaPrivateKeyUnpacked_a0 6033 default_70_1b(void) 6034 { 6035 IndCpaPrivateKeyUnpacked_a0 lit; 6036 libcrux_ml_kem_polynomial_PolynomialRingElement_1d repeat_expression[3U]; 6037 KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, 6038 repeat_expression[i] = ZERO_d6_ea();); 6039 memcpy( 6040 lit.secret_as_ntt, repeat_expression, 6041 (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); 6042 return lit; 6043 } 6044 6045 /** 6046 A monomorphic instance of 6047 libcrux_ml_kem.ind_cpa.unpacked.IndCpaPublicKeyUnpacked with types 6048 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 6049 - $3size_t 6050 */ 6051 typedef struct IndCpaPublicKeyUnpacked_a0_s { 6052 libcrux_ml_kem_polynomial_PolynomialRingElement_1d t_as_ntt[3U]; 6053 uint8_t seed_for_A[32U]; 6054 libcrux_ml_kem_polynomial_PolynomialRingElement_1d A[3U][3U]; 6055 } IndCpaPublicKeyUnpacked_a0; 6056 6057 /** 6058 This function found in impl {core::default::Default for 6059 libcrux_ml_kem::ind_cpa::unpacked::IndCpaPublicKeyUnpacked<Vector, 6060 K>[TraitClause@0, TraitClause@1]} 6061 */ 6062 /** 6063 A monomorphic instance of libcrux_ml_kem.ind_cpa.unpacked.default_8b 6064 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 6065 with const generics 6066 - K= 3 6067 */ 6068 static IndCpaPublicKeyUnpacked_a0 6069 default_8b_1b(void) 6070 { 6071 libcrux_ml_kem_polynomial_PolynomialRingElement_1d uu____0[3U]; 6072 KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, 6073 uu____0[i] = ZERO_d6_ea();); 6074 uint8_t uu____1[32U] = { 0U }; 6075 IndCpaPublicKeyUnpacked_a0 lit; 6076 memcpy( 6077 lit.t_as_ntt, uu____0, 6078 (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); 6079 memcpy(lit.seed_for_A, uu____1, (size_t)32U * sizeof(uint8_t)); 6080 libcrux_ml_kem_polynomial_PolynomialRingElement_1d repeat_expression0[3U][3U]; 6081 KRML_MAYBE_FOR3( 6082 i0, (size_t)0U, (size_t)3U, (size_t)1U, 6083 libcrux_ml_kem_polynomial_PolynomialRingElement_1d repeat_expression[3U]; 6084 KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, 6085 repeat_expression[i] = ZERO_d6_ea();); 6086 memcpy(repeat_expression0[i0], repeat_expression, 6087 (size_t)3U * 6088 sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d));); 6089 memcpy(lit.A, repeat_expression0, 6090 (size_t)3U * 6091 sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d[3U])); 6092 return lit; 6093 } 6094 6095 /** 6096 This function found in impl {libcrux_ml_kem::hash_functions::Hash<K> for 6097 libcrux_ml_kem::hash_functions::portable::PortableHash<K>} 6098 */ 6099 /** 6100 A monomorphic instance of libcrux_ml_kem.hash_functions.portable.G_4a 6101 with const generics 6102 - K= 3 6103 */ 6104 static inline void 6105 G_4a_e0(Eurydice_slice input, uint8_t ret[64U]) 6106 { 6107 libcrux_ml_kem_hash_functions_portable_G(input, ret); 6108 } 6109 6110 /** 6111 This function found in impl {libcrux_ml_kem::variant::Variant for 6112 libcrux_ml_kem::variant::MlKem} 6113 */ 6114 /** 6115 A monomorphic instance of libcrux_ml_kem.variant.cpa_keygen_seed_39 6116 with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] 6117 with const generics 6118 - K= 3 6119 */ 6120 static KRML_MUSTINLINE void 6121 cpa_keygen_seed_39_9c( 6122 Eurydice_slice key_generation_seed, uint8_t ret[64U]) 6123 { 6124 uint8_t seed[33U] = { 0U }; 6125 Eurydice_slice_copy( 6126 Eurydice_array_to_subslice3( 6127 seed, (size_t)0U, 6128 LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t *), 6129 key_generation_seed, uint8_t); 6130 seed[LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE] = 6131 (uint8_t)(size_t)3U; 6132 uint8_t ret0[64U]; 6133 G_4a_e0(Eurydice_array_to_slice((size_t)33U, seed, uint8_t), ret0); 6134 memcpy(ret, ret0, (size_t)64U * sizeof(uint8_t)); 6135 } 6136 6137 /** 6138 A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PortableHash 6139 with const generics 6140 - $3size_t 6141 */ 6142 typedef struct PortableHash_88_s { 6143 libcrux_sha3_generic_keccak_KeccakState_17 shake128_state[3U]; 6144 } PortableHash_88; 6145 6146 /** 6147 A monomorphic instance of 6148 libcrux_ml_kem.hash_functions.portable.shake128_init_absorb_final with const 6149 generics 6150 - K= 3 6151 */ 6152 static inline PortableHash_88 6153 shake128_init_absorb_final_e0( 6154 uint8_t (*input)[34U]) 6155 { 6156 PortableHash_88 shake128_state; 6157 libcrux_sha3_generic_keccak_KeccakState_17 repeat_expression[3U]; 6158 KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, 6159 repeat_expression[i] = 6160 libcrux_sha3_portable_incremental_shake128_init();); 6161 memcpy(shake128_state.shake128_state, repeat_expression, 6162 (size_t)3U * sizeof(libcrux_sha3_generic_keccak_KeccakState_17)); 6163 KRML_MAYBE_FOR3( 6164 i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; 6165 libcrux_sha3_portable_incremental_shake128_absorb_final( 6166 &shake128_state.shake128_state[i0], 6167 Eurydice_array_to_slice((size_t)34U, input[i0], uint8_t));); 6168 return shake128_state; 6169 } 6170 6171 /** 6172 This function found in impl {libcrux_ml_kem::hash_functions::Hash<K> for 6173 libcrux_ml_kem::hash_functions::portable::PortableHash<K>} 6174 */ 6175 /** 6176 A monomorphic instance of 6177 libcrux_ml_kem.hash_functions.portable.shake128_init_absorb_final_4a with const 6178 generics 6179 - K= 3 6180 */ 6181 static inline PortableHash_88 6182 shake128_init_absorb_final_4a_e0( 6183 uint8_t (*input)[34U]) 6184 { 6185 return shake128_init_absorb_final_e0(input); 6186 } 6187 6188 /** 6189 A monomorphic instance of 6190 libcrux_ml_kem.hash_functions.portable.shake128_squeeze_first_three_blocks with 6191 const generics 6192 - K= 3 6193 */ 6194 static inline void 6195 shake128_squeeze_first_three_blocks_e0( 6196 PortableHash_88 *st, uint8_t ret[3U][504U]) 6197 { 6198 uint8_t out[3U][504U] = { { 0U } }; 6199 KRML_MAYBE_FOR3( 6200 i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; 6201 libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks( 6202 &st->shake128_state[i0], 6203 Eurydice_array_to_slice((size_t)504U, out[i0], uint8_t));); 6204 memcpy(ret, out, (size_t)3U * sizeof(uint8_t[504U])); 6205 } 6206 6207 /** 6208 This function found in impl {libcrux_ml_kem::hash_functions::Hash<K> for 6209 libcrux_ml_kem::hash_functions::portable::PortableHash<K>} 6210 */ 6211 /** 6212 A monomorphic instance of 6213 libcrux_ml_kem.hash_functions.portable.shake128_squeeze_first_three_blocks_4a 6214 with const generics 6215 - K= 3 6216 */ 6217 static inline void 6218 shake128_squeeze_first_three_blocks_4a_e0( 6219 PortableHash_88 *self, uint8_t ret[3U][504U]) 6220 { 6221 shake128_squeeze_first_three_blocks_e0(self, ret); 6222 } 6223 6224 /** 6225 If `bytes` contains a set of uniformly random bytes, this function 6226 uniformly samples a ring element `â` that is treated as being the NTT 6227 representation of the corresponding polynomial `a`. 6228 6229 Since rejection sampling is used, it is possible the supplied bytes are 6230 not enough to sample the element, in which case an `Err` is returned and the 6231 caller must try again with a fresh set of bytes. 6232 6233 This function <strong>partially</strong> implements <strong>Algorithm 6234 6</strong> of the NIST FIPS 203 standard, We say "partially" because this 6235 implementation only accepts a finite set of bytes as input and returns an error 6236 if the set is not enough; Algorithm 6 of the FIPS 203 standard on the other 6237 hand samples from an infinite stream of bytes until the ring element is filled. 6238 Algorithm 6 is reproduced below: 6239 6240 ```plaintext 6241 Input: byte stream B ∈ 𝔹*. 6242 Output: array â ∈ ℤ₂₅₆. 6243 6244 i ← 0 6245 j ← 0 6246 while j < 256 do 6247 d₁ ← B[i] + 256·(B[i+1] mod 16) 6248 d₂ ← ⌊B[i+1]/16⌋ + 16·B[i+2] 6249 if d₁ < q then 6250 â[j] ← d₁ 6251 j ← j + 1 6252 end if 6253 if d₂ < q and j < 256 then 6254 â[j] ← d₂ 6255 j ← j + 1 6256 end if 6257 i ← i + 3 6258 end while 6259 return â 6260 ``` 6261 6262 The NIST FIPS 203 standard can be found at 6263 <https://csrc.nist.gov/pubs/fips/203/ipd>. 6264 */ 6265 /** 6266 A monomorphic instance of 6267 libcrux_ml_kem.sampling.sample_from_uniform_distribution_next with types 6268 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 6269 - K= 3 6270 - N= 504 6271 */ 6272 static KRML_MUSTINLINE bool 6273 sample_from_uniform_distribution_next_89( 6274 uint8_t (*randomness)[504U], size_t *sampled_coefficients, 6275 int16_t (*out)[272U]) 6276 { 6277 KRML_MAYBE_FOR3( 6278 i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; 6279 for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { 6280 size_t r = i; 6281 if (sampled_coefficients[i1] < 6282 LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { 6283 size_t sampled = libcrux_ml_kem_vector_portable_rej_sample_b8( 6284 Eurydice_array_to_subslice3(randomness[i1], r * (size_t)24U, 6285 r * (size_t)24U + (size_t)24U, 6286 uint8_t *), 6287 Eurydice_array_to_subslice3( 6288 out[i1], sampled_coefficients[i1], 6289 sampled_coefficients[i1] + (size_t)16U, int16_t *)); 6290 size_t uu____0 = i1; 6291 sampled_coefficients[uu____0] = 6292 sampled_coefficients[uu____0] + sampled; 6293 } 6294 }); 6295 bool done = true; 6296 KRML_MAYBE_FOR3( 6297 i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; 6298 if (sampled_coefficients[i0] >= 6299 LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { 6300 sampled_coefficients[i0] = 6301 LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; 6302 } else { done = false; }); 6303 return done; 6304 } 6305 6306 /** 6307 A monomorphic instance of 6308 libcrux_ml_kem.hash_functions.portable.shake128_squeeze_next_block with const 6309 generics 6310 - K= 3 6311 */ 6312 static inline void 6313 shake128_squeeze_next_block_e0(PortableHash_88 *st, 6314 uint8_t ret[3U][168U]) 6315 { 6316 uint8_t out[3U][168U] = { { 0U } }; 6317 KRML_MAYBE_FOR3( 6318 i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; 6319 libcrux_sha3_portable_incremental_shake128_squeeze_next_block( 6320 &st->shake128_state[i0], 6321 Eurydice_array_to_slice((size_t)168U, out[i0], uint8_t));); 6322 memcpy(ret, out, (size_t)3U * sizeof(uint8_t[168U])); 6323 } 6324 6325 /** 6326 This function found in impl {libcrux_ml_kem::hash_functions::Hash<K> for 6327 libcrux_ml_kem::hash_functions::portable::PortableHash<K>} 6328 */ 6329 /** 6330 A monomorphic instance of 6331 libcrux_ml_kem.hash_functions.portable.shake128_squeeze_next_block_4a with const 6332 generics 6333 - K= 3 6334 */ 6335 static inline void 6336 shake128_squeeze_next_block_4a_e0(PortableHash_88 *self, 6337 uint8_t ret[3U][168U]) 6338 { 6339 shake128_squeeze_next_block_e0(self, ret); 6340 } 6341 6342 /** 6343 If `bytes` contains a set of uniformly random bytes, this function 6344 uniformly samples a ring element `â` that is treated as being the NTT 6345 representation of the corresponding polynomial `a`. 6346 6347 Since rejection sampling is used, it is possible the supplied bytes are 6348 not enough to sample the element, in which case an `Err` is returned and the 6349 caller must try again with a fresh set of bytes. 6350 6351 This function <strong>partially</strong> implements <strong>Algorithm 6352 6</strong> of the NIST FIPS 203 standard, We say "partially" because this 6353 implementation only accepts a finite set of bytes as input and returns an error 6354 if the set is not enough; Algorithm 6 of the FIPS 203 standard on the other 6355 hand samples from an infinite stream of bytes until the ring element is filled. 6356 Algorithm 6 is reproduced below: 6357 6358 ```plaintext 6359 Input: byte stream B ∈ 𝔹*. 6360 Output: array â ∈ ℤ₂₅₆. 6361 6362 i ← 0 6363 j ← 0 6364 while j < 256 do 6365 d₁ ← B[i] + 256·(B[i+1] mod 16) 6366 d₂ ← ⌊B[i+1]/16⌋ + 16·B[i+2] 6367 if d₁ < q then 6368 â[j] ← d₁ 6369 j ← j + 1 6370 end if 6371 if d₂ < q and j < 256 then 6372 â[j] ← d₂ 6373 j ← j + 1 6374 end if 6375 i ← i + 3 6376 end while 6377 return â 6378 ``` 6379 6380 The NIST FIPS 203 standard can be found at 6381 <https://csrc.nist.gov/pubs/fips/203/ipd>. 6382 */ 6383 /** 6384 A monomorphic instance of 6385 libcrux_ml_kem.sampling.sample_from_uniform_distribution_next with types 6386 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 6387 - K= 3 6388 - N= 168 6389 */ 6390 static KRML_MUSTINLINE bool 6391 sample_from_uniform_distribution_next_890( 6392 uint8_t (*randomness)[168U], size_t *sampled_coefficients, 6393 int16_t (*out)[272U]) 6394 { 6395 KRML_MAYBE_FOR3( 6396 i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; 6397 for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { 6398 size_t r = i; 6399 if (sampled_coefficients[i1] < 6400 LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { 6401 size_t sampled = libcrux_ml_kem_vector_portable_rej_sample_b8( 6402 Eurydice_array_to_subslice3(randomness[i1], r * (size_t)24U, 6403 r * (size_t)24U + (size_t)24U, 6404 uint8_t *), 6405 Eurydice_array_to_subslice3( 6406 out[i1], sampled_coefficients[i1], 6407 sampled_coefficients[i1] + (size_t)16U, int16_t *)); 6408 size_t uu____0 = i1; 6409 sampled_coefficients[uu____0] = 6410 sampled_coefficients[uu____0] + sampled; 6411 } 6412 }); 6413 bool done = true; 6414 KRML_MAYBE_FOR3( 6415 i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; 6416 if (sampled_coefficients[i0] >= 6417 LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { 6418 sampled_coefficients[i0] = 6419 LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; 6420 } else { done = false; }); 6421 return done; 6422 } 6423 6424 /** 6425 This function found in impl {core::ops::function::FnMut<(@Array<i16, 272usize>), 6426 libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0, 6427 TraitClause@2]> for libcrux_ml_kem::sampling::sample_from_xof::closure<Vector, 6428 Hasher, K>[TraitClause@0, TraitClause@1, TraitClause@2, TraitClause@3]} 6429 */ 6430 /** 6431 A monomorphic instance of libcrux_ml_kem.sampling.sample_from_xof.call_mut_e7 6432 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 6433 libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const 6434 generics 6435 - K= 3 6436 */ 6437 static libcrux_ml_kem_polynomial_PolynomialRingElement_1d 6438 call_mut_e7_2b0( 6439 int16_t tupled_args[272U]) 6440 { 6441 int16_t s[272U]; 6442 memcpy(s, tupled_args, (size_t)272U * sizeof(int16_t)); 6443 return from_i16_array_d6_ea( 6444 Eurydice_array_to_subslice3(s, (size_t)0U, (size_t)256U, int16_t *)); 6445 } 6446 6447 /** 6448 A monomorphic instance of libcrux_ml_kem.sampling.sample_from_xof 6449 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 6450 libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const 6451 generics 6452 - K= 3 6453 */ 6454 static KRML_MUSTINLINE void 6455 sample_from_xof_2b0( 6456 uint8_t (*seeds)[34U], 6457 libcrux_ml_kem_polynomial_PolynomialRingElement_1d ret[3U]) 6458 { 6459 size_t sampled_coefficients[3U] = { 0U }; 6460 int16_t out[3U][272U] = { { 0U } }; 6461 PortableHash_88 xof_state = shake128_init_absorb_final_4a_e0(seeds); 6462 uint8_t randomness0[3U][504U]; 6463 shake128_squeeze_first_three_blocks_4a_e0(&xof_state, randomness0); 6464 bool done = sample_from_uniform_distribution_next_89( 6465 randomness0, sampled_coefficients, out); 6466 while (true) { 6467 if (done) { 6468 break; 6469 } else { 6470 uint8_t randomness[3U][168U]; 6471 shake128_squeeze_next_block_4a_e0(&xof_state, randomness); 6472 done = sample_from_uniform_distribution_next_890( 6473 randomness, sampled_coefficients, out); 6474 } 6475 } 6476 /* Passing arrays by value in Rust generates a copy in C */ 6477 int16_t copy_of_out[3U][272U]; 6478 memcpy(copy_of_out, out, (size_t)3U * sizeof(int16_t[272U])); 6479 libcrux_ml_kem_polynomial_PolynomialRingElement_1d ret0[3U]; 6480 KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, 6481 ret0[i] = call_mut_e7_2b0(copy_of_out[i]);); 6482 memcpy( 6483 ret, ret0, 6484 (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); 6485 } 6486 6487 /** 6488 A monomorphic instance of libcrux_ml_kem.matrix.sample_matrix_A 6489 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 6490 libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const 6491 generics 6492 - K= 3 6493 */ 6494 static KRML_MUSTINLINE void 6495 sample_matrix_A_2b0( 6496 libcrux_ml_kem_polynomial_PolynomialRingElement_1d (*A_transpose)[3U], 6497 uint8_t *seed, bool transpose) 6498 { 6499 KRML_MAYBE_FOR3( 6500 i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; 6501 uint8_t seeds[3U][34U]; 6502 KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, 6503 core_array__core__clone__Clone_for__Array_T__N___clone( 6504 (size_t)34U, seed, seeds[i], uint8_t, void *);); 6505 KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t j = i; 6506 seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); 6507 libcrux_ml_kem_polynomial_PolynomialRingElement_1d sampled[3U]; 6508 sample_from_xof_2b0(seeds, sampled); 6509 for (size_t i = (size_t)0U; 6510 i < Eurydice_slice_len( 6511 Eurydice_array_to_slice( 6512 (size_t)3U, sampled, 6513 libcrux_ml_kem_polynomial_PolynomialRingElement_1d), 6514 libcrux_ml_kem_polynomial_PolynomialRingElement_1d); 6515 i++) { 6516 size_t j = i; 6517 libcrux_ml_kem_polynomial_PolynomialRingElement_1d sample = sampled[j]; 6518 if (transpose) { 6519 A_transpose[j][i1] = sample; 6520 } else { 6521 A_transpose[i1][j] = sample; 6522 } 6523 }); 6524 } 6525 6526 /** 6527 A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRFxN 6528 with const generics 6529 - K= 3 6530 - LEN= 128 6531 */ 6532 static inline void 6533 PRFxN_41(uint8_t (*input)[33U], uint8_t ret[3U][128U]) 6534 { 6535 uint8_t out[3U][128U] = { { 0U } }; 6536 KRML_MAYBE_FOR3( 6537 i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; 6538 libcrux_sha3_portable_shake256( 6539 Eurydice_array_to_slice((size_t)128U, out[i0], uint8_t), 6540 Eurydice_array_to_slice((size_t)33U, input[i0], uint8_t));); 6541 memcpy(ret, out, (size_t)3U * sizeof(uint8_t[128U])); 6542 } 6543 6544 /** 6545 This function found in impl {libcrux_ml_kem::hash_functions::Hash<K> for 6546 libcrux_ml_kem::hash_functions::portable::PortableHash<K>} 6547 */ 6548 /** 6549 A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRFxN_4a 6550 with const generics 6551 - K= 3 6552 - LEN= 128 6553 */ 6554 static inline void 6555 PRFxN_4a_41(uint8_t (*input)[33U], uint8_t ret[3U][128U]) 6556 { 6557 PRFxN_41(input, ret); 6558 } 6559 6560 /** 6561 Sample a vector of ring elements from a centered binomial distribution and 6562 convert them into their NTT representations. 6563 */ 6564 /** 6565 A monomorphic instance of libcrux_ml_kem.ind_cpa.sample_vector_cbd_then_ntt 6566 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 6567 libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const 6568 generics 6569 - K= 3 6570 - ETA= 2 6571 - ETA_RANDOMNESS_SIZE= 128 6572 */ 6573 static KRML_MUSTINLINE uint8_t 6574 sample_vector_cbd_then_ntt_3b0( 6575 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re_as_ntt, 6576 uint8_t *prf_input, uint8_t domain_separator) 6577 { 6578 uint8_t prf_inputs[3U][33U]; 6579 KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, 6580 core_array__core__clone__Clone_for__Array_T__N___clone( 6581 (size_t)33U, prf_input, prf_inputs[i], uint8_t, void *);); 6582 domain_separator = 6583 libcrux_ml_kem_utils_prf_input_inc_e0(prf_inputs, domain_separator); 6584 uint8_t prf_outputs[3U][128U]; 6585 PRFxN_4a_41(prf_inputs, prf_outputs); 6586 KRML_MAYBE_FOR3( 6587 i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; 6588 re_as_ntt[i0] = sample_from_binomial_distribution_a0( 6589 Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], uint8_t)); 6590 ntt_binomially_sampled_ring_element_ea(&re_as_ntt[i0]);); 6591 return domain_separator; 6592 } 6593 6594 /** 6595 This function found in impl {core::ops::function::FnMut<(usize), 6596 libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0, 6597 TraitClause@3]> for 6598 libcrux_ml_kem::ind_cpa::generate_keypair_unpacked::closure<Vector, Hasher, 6599 Scheme, K, ETA1, ETA1_RANDOMNESS_SIZE>[TraitClause@0, TraitClause@1, 6600 TraitClause@2, TraitClause@3, TraitClause@4, TraitClause@5]} 6601 */ 6602 /** 6603 A monomorphic instance of 6604 libcrux_ml_kem.ind_cpa.generate_keypair_unpacked.call_mut_73 with types 6605 libcrux_ml_kem_vector_portable_vector_type_PortableVector, 6606 libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]], 6607 libcrux_ml_kem_variant_MlKem with const generics 6608 - K= 3 6609 - ETA1= 2 6610 - ETA1_RANDOMNESS_SIZE= 128 6611 */ 6612 static libcrux_ml_kem_polynomial_PolynomialRingElement_1d 6613 call_mut_73_1c0( 6614 void **_) 6615 { 6616 return ZERO_d6_ea(); 6617 } 6618 6619 /** 6620 Given two polynomial ring elements `lhs` and `rhs`, compute the pointwise 6621 sum of their constituent coefficients. 6622 */ 6623 /** 6624 A monomorphic instance of libcrux_ml_kem.polynomial.add_to_ring_element 6625 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 6626 with const generics 6627 - K= 3 6628 */ 6629 static KRML_MUSTINLINE void 6630 add_to_ring_element_1b( 6631 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *myself, 6632 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *rhs) 6633 { 6634 for (size_t i = (size_t)0U; 6635 i < Eurydice_slice_len( 6636 Eurydice_array_to_slice( 6637 (size_t)16U, myself->coefficients, 6638 libcrux_ml_kem_vector_portable_vector_type_PortableVector), 6639 libcrux_ml_kem_vector_portable_vector_type_PortableVector); 6640 i++) { 6641 size_t i0 = i; 6642 libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = 6643 libcrux_ml_kem_vector_portable_add_b8(myself->coefficients[i0], 6644 &rhs->coefficients[i0]); 6645 myself->coefficients[i0] = uu____0; 6646 } 6647 } 6648 6649 /** 6650 This function found in impl 6651 {libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0, 6652 TraitClause@1]} 6653 */ 6654 /** 6655 A monomorphic instance of libcrux_ml_kem.polynomial.add_to_ring_element_d6 6656 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 6657 with const generics 6658 - K= 3 6659 */ 6660 static KRML_MUSTINLINE void 6661 add_to_ring_element_d6_1b( 6662 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *self, 6663 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *rhs) 6664 { 6665 add_to_ring_element_1b(self, rhs); 6666 } 6667 6668 /** 6669 Compute  ◦ ŝ + ê 6670 */ 6671 /** 6672 A monomorphic instance of libcrux_ml_kem.matrix.compute_As_plus_e 6673 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 6674 with const generics 6675 - K= 3 6676 */ 6677 static KRML_MUSTINLINE void 6678 compute_As_plus_e_1b( 6679 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *t_as_ntt, 6680 libcrux_ml_kem_polynomial_PolynomialRingElement_1d (*matrix_A)[3U], 6681 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *s_as_ntt, 6682 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *error_as_ntt) 6683 { 6684 for (size_t i = (size_t)0U; 6685 i < Eurydice_slice_len( 6686 Eurydice_array_to_slice( 6687 (size_t)3U, matrix_A, 6688 libcrux_ml_kem_polynomial_PolynomialRingElement_1d[3U]), 6689 libcrux_ml_kem_polynomial_PolynomialRingElement_1d[3U]); 6690 i++) { 6691 size_t i0 = i; 6692 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *row = matrix_A[i0]; 6693 libcrux_ml_kem_polynomial_PolynomialRingElement_1d uu____0 = ZERO_d6_ea(); 6694 t_as_ntt[i0] = uu____0; 6695 for (size_t i1 = (size_t)0U; 6696 i1 < Eurydice_slice_len( 6697 Eurydice_array_to_slice( 6698 (size_t)3U, row, 6699 libcrux_ml_kem_polynomial_PolynomialRingElement_1d), 6700 libcrux_ml_kem_polynomial_PolynomialRingElement_1d); 6701 i1++) { 6702 size_t j = i1; 6703 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *matrix_element = 6704 &row[j]; 6705 libcrux_ml_kem_polynomial_PolynomialRingElement_1d product = 6706 ntt_multiply_d6_ea(matrix_element, &s_as_ntt[j]); 6707 add_to_ring_element_d6_1b(&t_as_ntt[i0], &product); 6708 } 6709 add_standard_error_reduce_d6_ea(&t_as_ntt[i0], &error_as_ntt[i0]); 6710 } 6711 } 6712 6713 /** 6714 This function implements most of <strong>Algorithm 12</strong> of the 6715 NIST FIPS 203 specification; this is the Kyber CPA-PKE key generation 6716 algorithm. 6717 6718 We say "most of" since Algorithm 12 samples the required randomness within 6719 the function itself, whereas this implementation expects it to be provided 6720 through the `key_generation_seed` parameter. 6721 6722 Algorithm 12 is reproduced below: 6723 6724 ```plaintext 6725 Output: encryption key ekₚₖₑ ∈ 𝔹^{384k+32}. 6726 Output: decryption key dkₚₖₑ ∈ 𝔹^{384k}. 6727 6728 d ←$ B 6729 (ρ,σ) ← G(d) 6730 N ← 0 6731 for (i ← 0; i < k; i++) 6732 for(j ← 0; j < k; j++) 6733 Â[i,j] ← SampleNTT(XOF(ρ, i, j)) 6734 end for 6735 end for 6736 for(i ← 0; i < k; i++) 6737 s[i] ← SamplePolyCBD_{η₁}(PRF_{η₁}(σ,N)) 6738 N ← N + 1 6739 end for 6740 for(i ← 0; i < k; i++) 6741 e[i] ← SamplePolyCBD_{η₂}(PRF_{η₂}(σ,N)) 6742 N ← N + 1 6743 end for 6744 ŝ ← NTT(s) 6745 ê ← NTT(e) 6746 t̂ ← Â◦ŝ + ê 6747 ekₚₖₑ ← ByteEncode₁₂(t̂) ‖ ρ 6748 dkₚₖₑ ← ByteEncode₁₂(ŝ) 6749 ``` 6750 6751 The NIST FIPS 203 standard can be found at 6752 <https://csrc.nist.gov/pubs/fips/203/ipd>. 6753 */ 6754 /** 6755 A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair_unpacked 6756 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 6757 libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]], 6758 libcrux_ml_kem_variant_MlKem with const generics 6759 - K= 3 6760 - ETA1= 2 6761 - ETA1_RANDOMNESS_SIZE= 128 6762 */ 6763 static KRML_MUSTINLINE void 6764 generate_keypair_unpacked_1c0( 6765 Eurydice_slice key_generation_seed, 6766 IndCpaPrivateKeyUnpacked_a0 *private_key, 6767 IndCpaPublicKeyUnpacked_a0 *public_key) 6768 { 6769 uint8_t hashed[64U]; 6770 cpa_keygen_seed_39_9c(key_generation_seed, hashed); 6771 Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at( 6772 Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), (size_t)32U, 6773 uint8_t, Eurydice_slice_uint8_t_x2); 6774 Eurydice_slice seed_for_A = uu____0.fst; 6775 Eurydice_slice seed_for_secret_and_error = uu____0.snd; 6776 libcrux_ml_kem_polynomial_PolynomialRingElement_1d(*uu____1)[3U] = 6777 public_key->A; 6778 uint8_t ret[34U]; 6779 libcrux_ml_kem_utils_into_padded_array_b6(seed_for_A, ret); 6780 sample_matrix_A_2b0(uu____1, ret, true); 6781 uint8_t prf_input[33U]; 6782 libcrux_ml_kem_utils_into_padded_array_c8(seed_for_secret_and_error, 6783 prf_input); 6784 uint8_t domain_separator = 6785 sample_vector_cbd_then_ntt_3b0(private_key->secret_as_ntt, prf_input, 0U); 6786 libcrux_ml_kem_polynomial_PolynomialRingElement_1d error_as_ntt[3U]; 6787 KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, 6788 /* original Rust expression is not an lvalue in C */ 6789 void *lvalue = (void *)0U; 6790 error_as_ntt[i] = call_mut_73_1c0(&lvalue);); 6791 sample_vector_cbd_then_ntt_3b0(error_as_ntt, prf_input, domain_separator); 6792 compute_As_plus_e_1b(public_key->t_as_ntt, public_key->A, 6793 private_key->secret_as_ntt, error_as_ntt); 6794 uint8_t uu____2[32U]; 6795 core_result_Result_fb dst; 6796 Eurydice_slice_to_array2(&dst, seed_for_A, Eurydice_slice, uint8_t[32U], 6797 core_array_TryFromSliceError); 6798 core_result_unwrap_26_b3(dst, uu____2); 6799 memcpy(public_key->seed_for_A, uu____2, (size_t)32U * sizeof(uint8_t)); 6800 } 6801 6802 /** 6803 Serialize the secret key from the unpacked key pair generation. 6804 */ 6805 /** 6806 A monomorphic instance of libcrux_ml_kem.ind_cpa.serialize_unpacked_secret_key 6807 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 6808 with const generics 6809 - K= 3 6810 - PRIVATE_KEY_SIZE= 1152 6811 - PUBLIC_KEY_SIZE= 1184 6812 */ 6813 static libcrux_ml_kem_utils_extraction_helper_Keypair768 6814 serialize_unpacked_secret_key_6c(IndCpaPublicKeyUnpacked_a0 *public_key, 6815 IndCpaPrivateKeyUnpacked_a0 *private_key) 6816 { 6817 uint8_t public_key_serialized[1184U]; 6818 serialize_public_key_89( 6819 public_key->t_as_ntt, 6820 Eurydice_array_to_slice((size_t)32U, public_key->seed_for_A, uint8_t), 6821 public_key_serialized); 6822 uint8_t secret_key_serialized[1152U] = { 0U }; 6823 serialize_vector_1b( 6824 private_key->secret_as_ntt, 6825 Eurydice_array_to_slice((size_t)1152U, secret_key_serialized, uint8_t)); 6826 /* Passing arrays by value in Rust generates a copy in C */ 6827 uint8_t copy_of_secret_key_serialized[1152U]; 6828 memcpy(copy_of_secret_key_serialized, secret_key_serialized, 6829 (size_t)1152U * sizeof(uint8_t)); 6830 /* Passing arrays by value in Rust generates a copy in C */ 6831 uint8_t copy_of_public_key_serialized[1184U]; 6832 memcpy(copy_of_public_key_serialized, public_key_serialized, 6833 (size_t)1184U * sizeof(uint8_t)); 6834 libcrux_ml_kem_utils_extraction_helper_Keypair768 lit; 6835 memcpy(lit.fst, copy_of_secret_key_serialized, 6836 (size_t)1152U * sizeof(uint8_t)); 6837 memcpy(lit.snd, copy_of_public_key_serialized, 6838 (size_t)1184U * sizeof(uint8_t)); 6839 return lit; 6840 } 6841 6842 /** 6843 A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair 6844 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 6845 libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]], 6846 libcrux_ml_kem_variant_MlKem with const generics 6847 - K= 3 6848 - PRIVATE_KEY_SIZE= 1152 6849 - PUBLIC_KEY_SIZE= 1184 6850 - ETA1= 2 6851 - ETA1_RANDOMNESS_SIZE= 128 6852 */ 6853 static KRML_MUSTINLINE libcrux_ml_kem_utils_extraction_helper_Keypair768 6854 generate_keypair_ea(Eurydice_slice key_generation_seed) 6855 { 6856 IndCpaPrivateKeyUnpacked_a0 private_key = default_70_1b(); 6857 IndCpaPublicKeyUnpacked_a0 public_key = default_8b_1b(); 6858 generate_keypair_unpacked_1c0(key_generation_seed, &private_key, &public_key); 6859 return serialize_unpacked_secret_key_6c(&public_key, &private_key); 6860 } 6861 6862 /** 6863 Serialize the secret key. 6864 */ 6865 /** 6866 A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key_mut 6867 with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] 6868 with const generics 6869 - K= 3 6870 - SERIALIZED_KEY_LEN= 2400 6871 */ 6872 static KRML_MUSTINLINE void 6873 serialize_kem_secret_key_mut_d6( 6874 Eurydice_slice private_key, Eurydice_slice public_key, 6875 Eurydice_slice implicit_rejection_value, uint8_t *serialized) 6876 { 6877 size_t pointer = (size_t)0U; 6878 uint8_t *uu____0 = serialized; 6879 size_t uu____1 = pointer; 6880 size_t uu____2 = pointer; 6881 Eurydice_slice_copy( 6882 Eurydice_array_to_subslice3( 6883 uu____0, uu____1, uu____2 + Eurydice_slice_len(private_key, uint8_t), 6884 uint8_t *), 6885 private_key, uint8_t); 6886 pointer = pointer + Eurydice_slice_len(private_key, uint8_t); 6887 uint8_t *uu____3 = serialized; 6888 size_t uu____4 = pointer; 6889 size_t uu____5 = pointer; 6890 Eurydice_slice_copy( 6891 Eurydice_array_to_subslice3( 6892 uu____3, uu____4, uu____5 + Eurydice_slice_len(public_key, uint8_t), 6893 uint8_t *), 6894 public_key, uint8_t); 6895 pointer = pointer + Eurydice_slice_len(public_key, uint8_t); 6896 Eurydice_slice uu____6 = Eurydice_array_to_subslice3( 6897 serialized, pointer, pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, 6898 uint8_t *); 6899 uint8_t ret[32U]; 6900 H_4a_e0(public_key, ret); 6901 Eurydice_slice_copy( 6902 uu____6, Eurydice_array_to_slice((size_t)32U, ret, uint8_t), uint8_t); 6903 pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; 6904 uint8_t *uu____7 = serialized; 6905 size_t uu____8 = pointer; 6906 size_t uu____9 = pointer; 6907 Eurydice_slice_copy( 6908 Eurydice_array_to_subslice3( 6909 uu____7, uu____8, 6910 uu____9 + Eurydice_slice_len(implicit_rejection_value, uint8_t), 6911 uint8_t *), 6912 implicit_rejection_value, uint8_t); 6913 } 6914 6915 /** 6916 A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key 6917 with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] 6918 with const generics 6919 - K= 3 6920 - SERIALIZED_KEY_LEN= 2400 6921 */ 6922 static KRML_MUSTINLINE void 6923 serialize_kem_secret_key_d6( 6924 Eurydice_slice private_key, Eurydice_slice public_key, 6925 Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) 6926 { 6927 uint8_t out[2400U] = { 0U }; 6928 serialize_kem_secret_key_mut_d6(private_key, public_key, 6929 implicit_rejection_value, out); 6930 memcpy(ret, out, (size_t)2400U * sizeof(uint8_t)); 6931 } 6932 6933 /** 6934 Packed API 6935 6936 Generate a key pair. 6937 6938 Depending on the `Vector` and `Hasher` used, this requires different hardware 6939 features 6940 */ 6941 /** 6942 A monomorphic instance of libcrux_ml_kem.ind_cca.generate_keypair 6943 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 6944 libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]], 6945 libcrux_ml_kem_variant_MlKem with const generics 6946 - K= 3 6947 - CPA_PRIVATE_KEY_SIZE= 1152 6948 - PRIVATE_KEY_SIZE= 2400 6949 - PUBLIC_KEY_SIZE= 1184 6950 - ETA1= 2 6951 - ETA1_RANDOMNESS_SIZE= 128 6952 */ 6953 libcrux_ml_kem_mlkem768_MlKem768KeyPair 6954 libcrux_ml_kem_ind_cca_generate_keypair_15(uint8_t *randomness) 6955 { 6956 Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice3( 6957 randomness, (size_t)0U, 6958 LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t *); 6959 Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( 6960 (size_t)64U, randomness, 6961 LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, 6962 size_t, uint8_t[]); 6963 libcrux_ml_kem_utils_extraction_helper_Keypair768 uu____0 = 6964 generate_keypair_ea(ind_cpa_keypair_randomness); 6965 uint8_t ind_cpa_private_key[1152U]; 6966 memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof(uint8_t)); 6967 uint8_t public_key[1184U]; 6968 memcpy(public_key, uu____0.snd, (size_t)1184U * sizeof(uint8_t)); 6969 uint8_t secret_key_serialized[2400U]; 6970 serialize_kem_secret_key_d6( 6971 Eurydice_array_to_slice((size_t)1152U, ind_cpa_private_key, uint8_t), 6972 Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t), 6973 implicit_rejection_value, secret_key_serialized); 6974 /* Passing arrays by value in Rust generates a copy in C */ 6975 uint8_t copy_of_secret_key_serialized[2400U]; 6976 memcpy(copy_of_secret_key_serialized, secret_key_serialized, 6977 (size_t)2400U * sizeof(uint8_t)); 6978 libcrux_ml_kem_types_MlKemPrivateKey_d9 private_key = 6979 libcrux_ml_kem_types_from_77_28(copy_of_secret_key_serialized); 6980 libcrux_ml_kem_types_MlKemPrivateKey_d9 uu____2 = private_key; 6981 /* Passing arrays by value in Rust generates a copy in C */ 6982 uint8_t copy_of_public_key[1184U]; 6983 memcpy(copy_of_public_key, public_key, (size_t)1184U * sizeof(uint8_t)); 6984 return libcrux_ml_kem_types_from_17_74( 6985 uu____2, libcrux_ml_kem_types_from_fd_d0(copy_of_public_key)); 6986 } 6987 6988 /** 6989 This function found in impl {libcrux_ml_kem::variant::Variant for 6990 libcrux_ml_kem::variant::MlKem} 6991 */ 6992 /** 6993 A monomorphic instance of libcrux_ml_kem.variant.entropy_preprocess_39 6994 with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] 6995 with const generics 6996 - K= 3 6997 */ 6998 static KRML_MUSTINLINE void 6999 entropy_preprocess_39_9c(Eurydice_slice randomness, 7000 uint8_t ret[32U]) 7001 { 7002 uint8_t out[32U] = { 0U }; 7003 Eurydice_slice_copy(Eurydice_array_to_slice((size_t)32U, out, uint8_t), 7004 randomness, uint8_t); 7005 memcpy(ret, out, (size_t)32U * sizeof(uint8_t)); 7006 } 7007 7008 /** 7009 A monomorphic instance of libcrux_ml_kem.ind_cpa.build_unpacked_public_key_mut 7010 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 7011 libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const 7012 generics 7013 - K= 3 7014 - T_AS_NTT_ENCODED_SIZE= 1152 7015 */ 7016 static KRML_MUSTINLINE void 7017 build_unpacked_public_key_mut_3f0( 7018 Eurydice_slice public_key, 7019 IndCpaPublicKeyUnpacked_a0 *unpacked_public_key) 7020 { 7021 Eurydice_slice uu____0 = Eurydice_slice_subslice_to( 7022 public_key, (size_t)1152U, uint8_t, size_t, uint8_t[]); 7023 deserialize_ring_elements_reduced_1b(uu____0, unpacked_public_key->t_as_ntt); 7024 Eurydice_slice seed = Eurydice_slice_subslice_from( 7025 public_key, (size_t)1152U, uint8_t, size_t, uint8_t[]); 7026 libcrux_ml_kem_polynomial_PolynomialRingElement_1d(*uu____1)[3U] = 7027 unpacked_public_key->A; 7028 uint8_t ret[34U]; 7029 libcrux_ml_kem_utils_into_padded_array_b6(seed, ret); 7030 sample_matrix_A_2b0(uu____1, ret, false); 7031 } 7032 7033 /** 7034 A monomorphic instance of libcrux_ml_kem.ind_cpa.build_unpacked_public_key 7035 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 7036 libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const 7037 generics 7038 - K= 3 7039 - T_AS_NTT_ENCODED_SIZE= 1152 7040 */ 7041 static KRML_MUSTINLINE IndCpaPublicKeyUnpacked_a0 7042 build_unpacked_public_key_3f(Eurydice_slice public_key) 7043 { 7044 IndCpaPublicKeyUnpacked_a0 unpacked_public_key = default_8b_1b(); 7045 build_unpacked_public_key_mut_3f0(public_key, &unpacked_public_key); 7046 return unpacked_public_key; 7047 } 7048 7049 /** 7050 A monomorphic instance of K. 7051 with types libcrux_ml_kem_polynomial_PolynomialRingElement 7052 libcrux_ml_kem_vector_portable_vector_type_PortableVector[3size_t], 7053 libcrux_ml_kem_polynomial_PolynomialRingElement 7054 libcrux_ml_kem_vector_portable_vector_type_PortableVector 7055 7056 */ 7057 typedef struct tuple_ed_s { 7058 libcrux_ml_kem_polynomial_PolynomialRingElement_1d fst[3U]; 7059 libcrux_ml_kem_polynomial_PolynomialRingElement_1d snd; 7060 } tuple_ed; 7061 7062 /** 7063 This function found in impl {core::ops::function::FnMut<(usize), 7064 libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0, 7065 TraitClause@2]> for libcrux_ml_kem::ind_cpa::encrypt_c1::closure<Vector, Hasher, 7066 K, C1_LEN, U_COMPRESSION_FACTOR, BLOCK_LEN, ETA1, ETA1_RANDOMNESS_SIZE, ETA2, 7067 ETA2_RANDOMNESS_SIZE>[TraitClause@0, TraitClause@1, TraitClause@2, 7068 TraitClause@3]} 7069 */ 7070 /** 7071 A monomorphic instance of libcrux_ml_kem.ind_cpa.encrypt_c1.call_mut_f1 7072 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 7073 libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const 7074 generics 7075 - K= 3 7076 - C1_LEN= 960 7077 - U_COMPRESSION_FACTOR= 10 7078 - BLOCK_LEN= 320 7079 - ETA1= 2 7080 - ETA1_RANDOMNESS_SIZE= 128 7081 - ETA2= 2 7082 - ETA2_RANDOMNESS_SIZE= 128 7083 */ 7084 static libcrux_ml_kem_polynomial_PolynomialRingElement_1d 7085 call_mut_f1_850( 7086 void **_) 7087 { 7088 return ZERO_d6_ea(); 7089 } 7090 7091 /** 7092 This function found in impl {core::ops::function::FnMut<(usize), 7093 libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0, 7094 TraitClause@2]> for libcrux_ml_kem::ind_cpa::encrypt_c1::closure#1<Vector, 7095 Hasher, K, C1_LEN, U_COMPRESSION_FACTOR, BLOCK_LEN, ETA1, ETA1_RANDOMNESS_SIZE, 7096 ETA2, ETA2_RANDOMNESS_SIZE>[TraitClause@0, TraitClause@1, TraitClause@2, 7097 TraitClause@3]} 7098 */ 7099 /** 7100 A monomorphic instance of libcrux_ml_kem.ind_cpa.encrypt_c1.call_mut_dd 7101 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 7102 libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const 7103 generics 7104 - K= 3 7105 - C1_LEN= 960 7106 - U_COMPRESSION_FACTOR= 10 7107 - BLOCK_LEN= 320 7108 - ETA1= 2 7109 - ETA1_RANDOMNESS_SIZE= 128 7110 - ETA2= 2 7111 - ETA2_RANDOMNESS_SIZE= 128 7112 */ 7113 static libcrux_ml_kem_polynomial_PolynomialRingElement_1d 7114 call_mut_dd_850( 7115 void **_) 7116 { 7117 return ZERO_d6_ea(); 7118 } 7119 7120 /** 7121 Sample a vector of ring elements from a centered binomial distribution. 7122 */ 7123 /** 7124 A monomorphic instance of libcrux_ml_kem.ind_cpa.sample_ring_element_cbd 7125 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 7126 libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const 7127 generics 7128 - K= 3 7129 - ETA2_RANDOMNESS_SIZE= 128 7130 - ETA2= 2 7131 */ 7132 static KRML_MUSTINLINE uint8_t 7133 sample_ring_element_cbd_3b0( 7134 uint8_t *prf_input, uint8_t domain_separator, 7135 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *error_1) 7136 { 7137 uint8_t prf_inputs[3U][33U]; 7138 KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, 7139 core_array__core__clone__Clone_for__Array_T__N___clone( 7140 (size_t)33U, prf_input, prf_inputs[i], uint8_t, void *);); 7141 domain_separator = 7142 libcrux_ml_kem_utils_prf_input_inc_e0(prf_inputs, domain_separator); 7143 uint8_t prf_outputs[3U][128U]; 7144 PRFxN_4a_41(prf_inputs, prf_outputs); 7145 KRML_MAYBE_FOR3( 7146 i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; 7147 libcrux_ml_kem_polynomial_PolynomialRingElement_1d uu____0 = 7148 sample_from_binomial_distribution_a0( 7149 Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], uint8_t)); 7150 error_1[i0] = uu____0;); 7151 return domain_separator; 7152 } 7153 7154 /** 7155 This function found in impl {libcrux_ml_kem::hash_functions::Hash<K> for 7156 libcrux_ml_kem::hash_functions::portable::PortableHash<K>} 7157 */ 7158 /** 7159 A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRF_4a 7160 with const generics 7161 - K= 3 7162 - LEN= 128 7163 */ 7164 static inline void 7165 PRF_4a_410(Eurydice_slice input, uint8_t ret[128U]) 7166 { 7167 PRF_a6(input, ret); 7168 } 7169 7170 /** 7171 This function found in impl {core::ops::function::FnMut<(usize), 7172 libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0, 7173 TraitClause@1]> for libcrux_ml_kem::matrix::compute_vector_u::closure<Vector, 7174 K>[TraitClause@0, TraitClause@1]} 7175 */ 7176 /** 7177 A monomorphic instance of libcrux_ml_kem.matrix.compute_vector_u.call_mut_a8 7178 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 7179 with const generics 7180 - K= 3 7181 */ 7182 static libcrux_ml_kem_polynomial_PolynomialRingElement_1d 7183 call_mut_a8_1b( 7184 void **_) 7185 { 7186 return ZERO_d6_ea(); 7187 } 7188 7189 /** 7190 A monomorphic instance of libcrux_ml_kem.invert_ntt.invert_ntt_montgomery 7191 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 7192 with const generics 7193 - K= 3 7194 */ 7195 static KRML_MUSTINLINE void 7196 invert_ntt_montgomery_1b( 7197 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re) 7198 { 7199 size_t zeta_i = 7200 LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; 7201 invert_ntt_at_layer_1_ea(&zeta_i, re); 7202 invert_ntt_at_layer_2_ea(&zeta_i, re); 7203 invert_ntt_at_layer_3_ea(&zeta_i, re); 7204 invert_ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)4U); 7205 invert_ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)5U); 7206 invert_ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)6U); 7207 invert_ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)7U); 7208 poly_barrett_reduce_d6_ea(re); 7209 } 7210 7211 /** 7212 Compute u := InvertNTT(Aᵀ ◦ r̂) + e₁ 7213 */ 7214 /** 7215 A monomorphic instance of libcrux_ml_kem.matrix.compute_vector_u 7216 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 7217 with const generics 7218 - K= 3 7219 */ 7220 static KRML_MUSTINLINE void 7221 compute_vector_u_1b( 7222 libcrux_ml_kem_polynomial_PolynomialRingElement_1d (*a_as_ntt)[3U], 7223 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *r_as_ntt, 7224 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *error_1, 7225 libcrux_ml_kem_polynomial_PolynomialRingElement_1d ret[3U]) 7226 { 7227 libcrux_ml_kem_polynomial_PolynomialRingElement_1d result[3U]; 7228 KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, 7229 /* original Rust expression is not an lvalue in C */ 7230 void *lvalue = (void *)0U; 7231 result[i] = call_mut_a8_1b(&lvalue);); 7232 for (size_t i0 = (size_t)0U; 7233 i0 < Eurydice_slice_len( 7234 Eurydice_array_to_slice( 7235 (size_t)3U, a_as_ntt, 7236 libcrux_ml_kem_polynomial_PolynomialRingElement_1d[3U]), 7237 libcrux_ml_kem_polynomial_PolynomialRingElement_1d[3U]); 7238 i0++) { 7239 size_t i1 = i0; 7240 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *row = a_as_ntt[i1]; 7241 for (size_t i = (size_t)0U; 7242 i < Eurydice_slice_len( 7243 Eurydice_array_to_slice( 7244 (size_t)3U, row, 7245 libcrux_ml_kem_polynomial_PolynomialRingElement_1d), 7246 libcrux_ml_kem_polynomial_PolynomialRingElement_1d); 7247 i++) { 7248 size_t j = i; 7249 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *a_element = &row[j]; 7250 libcrux_ml_kem_polynomial_PolynomialRingElement_1d product = 7251 ntt_multiply_d6_ea(a_element, &r_as_ntt[j]); 7252 add_to_ring_element_d6_1b(&result[i1], &product); 7253 } 7254 invert_ntt_montgomery_1b(&result[i1]); 7255 add_error_reduce_d6_ea(&result[i1], &error_1[i1]); 7256 } 7257 memcpy( 7258 ret, result, 7259 (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); 7260 } 7261 7262 /** 7263 A monomorphic instance of libcrux_ml_kem.serialize.compress_then_serialize_10 7264 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 7265 with const generics 7266 - OUT_LEN= 320 7267 */ 7268 static KRML_MUSTINLINE void 7269 compress_then_serialize_10_ff( 7270 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re, uint8_t ret[320U]) 7271 { 7272 uint8_t serialized[320U] = { 0U }; 7273 for (size_t i = (size_t)0U; i < VECTORS_IN_RING_ELEMENT; i++) { 7274 size_t i0 = i; 7275 libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = 7276 compress_b8_ef(to_unsigned_field_modulus_ea(re->coefficients[i0])); 7277 uint8_t bytes[20U]; 7278 libcrux_ml_kem_vector_portable_serialize_10_b8(coefficient, bytes); 7279 Eurydice_slice_copy( 7280 Eurydice_array_to_subslice3(serialized, (size_t)20U * i0, 7281 (size_t)20U * i0 + (size_t)20U, uint8_t *), 7282 Eurydice_array_to_slice((size_t)20U, bytes, uint8_t), uint8_t); 7283 } 7284 memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); 7285 } 7286 7287 /** 7288 A monomorphic instance of 7289 libcrux_ml_kem.serialize.compress_then_serialize_ring_element_u with types 7290 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 7291 - COMPRESSION_FACTOR= 10 7292 - OUT_LEN= 320 7293 */ 7294 static KRML_MUSTINLINE void 7295 compress_then_serialize_ring_element_u_fe( 7296 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re, uint8_t ret[320U]) 7297 { 7298 uint8_t uu____0[320U]; 7299 compress_then_serialize_10_ff(re, uu____0); 7300 memcpy(ret, uu____0, (size_t)320U * sizeof(uint8_t)); 7301 } 7302 7303 /** 7304 Call [`compress_then_serialize_ring_element_u`] on each ring element. 7305 */ 7306 /** 7307 A monomorphic instance of libcrux_ml_kem.ind_cpa.compress_then_serialize_u 7308 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 7309 with const generics 7310 - K= 3 7311 - OUT_LEN= 960 7312 - COMPRESSION_FACTOR= 10 7313 - BLOCK_LEN= 320 7314 */ 7315 static KRML_MUSTINLINE void 7316 compress_then_serialize_u_43( 7317 libcrux_ml_kem_polynomial_PolynomialRingElement_1d input[3U], 7318 Eurydice_slice out) 7319 { 7320 for (size_t i = (size_t)0U; 7321 i < Eurydice_slice_len( 7322 Eurydice_array_to_slice( 7323 (size_t)3U, input, 7324 libcrux_ml_kem_polynomial_PolynomialRingElement_1d), 7325 libcrux_ml_kem_polynomial_PolynomialRingElement_1d); 7326 i++) { 7327 size_t i0 = i; 7328 libcrux_ml_kem_polynomial_PolynomialRingElement_1d re = input[i0]; 7329 Eurydice_slice uu____0 = Eurydice_slice_subslice3( 7330 out, i0 * ((size_t)960U / (size_t)3U), 7331 (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U), uint8_t *); 7332 uint8_t ret[320U]; 7333 compress_then_serialize_ring_element_u_fe(&re, ret); 7334 Eurydice_slice_copy( 7335 uu____0, Eurydice_array_to_slice((size_t)320U, ret, uint8_t), uint8_t); 7336 } 7337 } 7338 7339 /** 7340 A monomorphic instance of libcrux_ml_kem.ind_cpa.encrypt_c1 7341 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 7342 libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const 7343 generics 7344 - K= 3 7345 - C1_LEN= 960 7346 - U_COMPRESSION_FACTOR= 10 7347 - BLOCK_LEN= 320 7348 - ETA1= 2 7349 - ETA1_RANDOMNESS_SIZE= 128 7350 - ETA2= 2 7351 - ETA2_RANDOMNESS_SIZE= 128 7352 */ 7353 static KRML_MUSTINLINE tuple_ed 7354 encrypt_c1_850(Eurydice_slice randomness, 7355 libcrux_ml_kem_polynomial_PolynomialRingElement_1d (*matrix)[3U], 7356 Eurydice_slice ciphertext) 7357 { 7358 uint8_t prf_input[33U]; 7359 libcrux_ml_kem_utils_into_padded_array_c8(randomness, prf_input); 7360 libcrux_ml_kem_polynomial_PolynomialRingElement_1d r_as_ntt[3U]; 7361 KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, 7362 /* original Rust expression is not an lvalue in C */ 7363 void *lvalue = (void *)0U; 7364 r_as_ntt[i] = call_mut_f1_850(&lvalue);); 7365 uint8_t domain_separator0 = 7366 sample_vector_cbd_then_ntt_3b0(r_as_ntt, prf_input, 0U); 7367 libcrux_ml_kem_polynomial_PolynomialRingElement_1d error_1[3U]; 7368 KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, 7369 /* original Rust expression is not an lvalue in C */ 7370 void *lvalue = (void *)0U; 7371 error_1[i] = call_mut_dd_850(&lvalue);); 7372 uint8_t domain_separator = 7373 sample_ring_element_cbd_3b0(prf_input, domain_separator0, error_1); 7374 prf_input[32U] = domain_separator; 7375 uint8_t prf_output[128U]; 7376 PRF_4a_410(Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t), 7377 prf_output); 7378 libcrux_ml_kem_polynomial_PolynomialRingElement_1d error_2 = 7379 sample_from_binomial_distribution_a0( 7380 Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t)); 7381 libcrux_ml_kem_polynomial_PolynomialRingElement_1d u[3U]; 7382 compute_vector_u_1b(matrix, r_as_ntt, error_1, u); 7383 libcrux_ml_kem_polynomial_PolynomialRingElement_1d uu____0[3U]; 7384 memcpy( 7385 uu____0, u, 7386 (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); 7387 compress_then_serialize_u_43(uu____0, ciphertext); 7388 /* Passing arrays by value in Rust generates a copy in C */ 7389 libcrux_ml_kem_polynomial_PolynomialRingElement_1d copy_of_r_as_ntt[3U]; 7390 memcpy( 7391 copy_of_r_as_ntt, r_as_ntt, 7392 (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); 7393 tuple_ed lit; 7394 memcpy( 7395 lit.fst, copy_of_r_as_ntt, 7396 (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); 7397 lit.snd = error_2; 7398 return lit; 7399 } 7400 7401 /** 7402 Compute InverseNTT(tᵀ ◦ r̂) + e₂ + message 7403 */ 7404 /** 7405 A monomorphic instance of libcrux_ml_kem.matrix.compute_ring_element_v 7406 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 7407 with const generics 7408 - K= 3 7409 */ 7410 static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d 7411 compute_ring_element_v_1b( 7412 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *t_as_ntt, 7413 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *r_as_ntt, 7414 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *error_2, 7415 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *message) 7416 { 7417 libcrux_ml_kem_polynomial_PolynomialRingElement_1d result = ZERO_d6_ea(); 7418 KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; 7419 libcrux_ml_kem_polynomial_PolynomialRingElement_1d product = 7420 ntt_multiply_d6_ea(&t_as_ntt[i0], &r_as_ntt[i0]); 7421 add_to_ring_element_d6_1b(&result, &product);); 7422 invert_ntt_montgomery_1b(&result); 7423 return add_message_error_reduce_d6_ea(error_2, message, result); 7424 } 7425 7426 /** 7427 A monomorphic instance of 7428 libcrux_ml_kem.serialize.compress_then_serialize_ring_element_v with types 7429 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 7430 - K= 3 7431 - COMPRESSION_FACTOR= 4 7432 - OUT_LEN= 128 7433 */ 7434 static KRML_MUSTINLINE void 7435 compress_then_serialize_ring_element_v_6c( 7436 libcrux_ml_kem_polynomial_PolynomialRingElement_1d re, Eurydice_slice out) 7437 { 7438 compress_then_serialize_4_ea(re, out); 7439 } 7440 7441 /** 7442 A monomorphic instance of libcrux_ml_kem.ind_cpa.encrypt_c2 7443 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 7444 with const generics 7445 - K= 3 7446 - V_COMPRESSION_FACTOR= 4 7447 - C2_LEN= 128 7448 */ 7449 static KRML_MUSTINLINE void 7450 encrypt_c2_6c( 7451 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *t_as_ntt, 7452 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *r_as_ntt, 7453 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *error_2, 7454 uint8_t *message, Eurydice_slice ciphertext) 7455 { 7456 libcrux_ml_kem_polynomial_PolynomialRingElement_1d message_as_ring_element = 7457 deserialize_then_decompress_message_ea(message); 7458 libcrux_ml_kem_polynomial_PolynomialRingElement_1d v = 7459 compute_ring_element_v_1b(t_as_ntt, r_as_ntt, error_2, 7460 &message_as_ring_element); 7461 compress_then_serialize_ring_element_v_6c(v, ciphertext); 7462 } 7463 7464 /** 7465 This function implements <strong>Algorithm 13</strong> of the 7466 NIST FIPS 203 specification; this is the Kyber CPA-PKE encryption algorithm. 7467 7468 Algorithm 13 is reproduced below: 7469 7470 ```plaintext 7471 Input: encryption key ekₚₖₑ ∈ 𝔹^{384k+32}. 7472 Input: message m ∈ 𝔹^{32}. 7473 Input: encryption randomness r ∈ 𝔹^{32}. 7474 Output: ciphertext c ∈ 𝔹^{32(dᵤk + dᵥ)}. 7475 7476 N ← 0 7477 t̂ ← ByteDecode₁₂(ekₚₖₑ[0:384k]) 7478 ρ ← ekₚₖₑ[384k: 384k + 32] 7479 for (i ← 0; i < k; i++) 7480 for(j ← 0; j < k; j++) 7481 Â[i,j] ← SampleNTT(XOF(ρ, i, j)) 7482 end for 7483 end for 7484 for(i ← 0; i < k; i++) 7485 r[i] ← SamplePolyCBD_{η₁}(PRF_{η₁}(r,N)) 7486 N ← N + 1 7487 end for 7488 for(i ← 0; i < k; i++) 7489 e₁[i] ← SamplePolyCBD_{η₂}(PRF_{η₂}(r,N)) 7490 N ← N + 1 7491 end for 7492 e₂ ← SamplePolyCBD_{η₂}(PRF_{η₂}(r,N)) 7493 r̂ ← NTT(r) 7494 u ← NTT-¹(Âᵀ ◦ r̂) + e₁ 7495 μ ← Decompress₁(ByteDecode₁(m))) 7496 v ← NTT-¹(t̂ᵀ ◦ rˆ) + e₂ + μ 7497 c₁ ← ByteEncode_{dᵤ}(Compress_{dᵤ}(u)) 7498 c₂ ← ByteEncode_{dᵥ}(Compress_{dᵥ}(v)) 7499 return c ← (c₁ ‖ c₂) 7500 ``` 7501 7502 The NIST FIPS 203 standard can be found at 7503 <https://csrc.nist.gov/pubs/fips/203/ipd>. 7504 */ 7505 /** 7506 A monomorphic instance of libcrux_ml_kem.ind_cpa.encrypt_unpacked 7507 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 7508 libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const 7509 generics 7510 - K= 3 7511 - CIPHERTEXT_SIZE= 1088 7512 - T_AS_NTT_ENCODED_SIZE= 1152 7513 - C1_LEN= 960 7514 - C2_LEN= 128 7515 - U_COMPRESSION_FACTOR= 10 7516 - V_COMPRESSION_FACTOR= 4 7517 - BLOCK_LEN= 320 7518 - ETA1= 2 7519 - ETA1_RANDOMNESS_SIZE= 128 7520 - ETA2= 2 7521 - ETA2_RANDOMNESS_SIZE= 128 7522 */ 7523 static KRML_MUSTINLINE void 7524 encrypt_unpacked_2a0( 7525 IndCpaPublicKeyUnpacked_a0 *public_key, uint8_t *message, 7526 Eurydice_slice randomness, uint8_t ret[1088U]) 7527 { 7528 uint8_t ciphertext[1088U] = { 0U }; 7529 tuple_ed uu____0 = 7530 encrypt_c1_850(randomness, public_key->A, 7531 Eurydice_array_to_subslice3(ciphertext, (size_t)0U, 7532 (size_t)960U, uint8_t *)); 7533 libcrux_ml_kem_polynomial_PolynomialRingElement_1d r_as_ntt[3U]; 7534 memcpy( 7535 r_as_ntt, uu____0.fst, 7536 (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); 7537 libcrux_ml_kem_polynomial_PolynomialRingElement_1d error_2 = uu____0.snd; 7538 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *uu____1 = 7539 public_key->t_as_ntt; 7540 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *uu____2 = r_as_ntt; 7541 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *uu____3 = &error_2; 7542 uint8_t *uu____4 = message; 7543 encrypt_c2_6c( 7544 uu____1, uu____2, uu____3, uu____4, 7545 Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, (size_t)960U, 7546 uint8_t, size_t, uint8_t[])); 7547 memcpy(ret, ciphertext, (size_t)1088U * sizeof(uint8_t)); 7548 } 7549 7550 /** 7551 A monomorphic instance of libcrux_ml_kem.ind_cpa.encrypt 7552 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 7553 libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const 7554 generics 7555 - K= 3 7556 - CIPHERTEXT_SIZE= 1088 7557 - T_AS_NTT_ENCODED_SIZE= 1152 7558 - C1_LEN= 960 7559 - C2_LEN= 128 7560 - U_COMPRESSION_FACTOR= 10 7561 - V_COMPRESSION_FACTOR= 4 7562 - BLOCK_LEN= 320 7563 - ETA1= 2 7564 - ETA1_RANDOMNESS_SIZE= 128 7565 - ETA2= 2 7566 - ETA2_RANDOMNESS_SIZE= 128 7567 */ 7568 static KRML_MUSTINLINE void 7569 encrypt_2a(Eurydice_slice public_key, 7570 uint8_t *message, 7571 Eurydice_slice randomness, 7572 uint8_t ret[1088U]) 7573 { 7574 IndCpaPublicKeyUnpacked_a0 unpacked_public_key = 7575 build_unpacked_public_key_3f(public_key); 7576 uint8_t ret0[1088U]; 7577 encrypt_unpacked_2a0(&unpacked_public_key, message, randomness, ret0); 7578 memcpy(ret, ret0, (size_t)1088U * sizeof(uint8_t)); 7579 } 7580 7581 /** 7582 This function found in impl {libcrux_ml_kem::variant::Variant for 7583 libcrux_ml_kem::variant::MlKem} 7584 */ 7585 /** 7586 A monomorphic instance of libcrux_ml_kem.variant.kdf_39 7587 with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] 7588 with const generics 7589 - K= 3 7590 - CIPHERTEXT_SIZE= 1088 7591 */ 7592 static KRML_MUSTINLINE void 7593 kdf_39_d6(Eurydice_slice shared_secret, 7594 uint8_t ret[32U]) 7595 { 7596 uint8_t out[32U] = { 0U }; 7597 Eurydice_slice_copy(Eurydice_array_to_slice((size_t)32U, out, uint8_t), 7598 shared_secret, uint8_t); 7599 memcpy(ret, out, (size_t)32U * sizeof(uint8_t)); 7600 } 7601 7602 /** 7603 A monomorphic instance of libcrux_ml_kem.ind_cca.encapsulate 7604 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 7605 libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]], 7606 libcrux_ml_kem_variant_MlKem with const generics 7607 - K= 3 7608 - CIPHERTEXT_SIZE= 1088 7609 - PUBLIC_KEY_SIZE= 1184 7610 - T_AS_NTT_ENCODED_SIZE= 1152 7611 - C1_SIZE= 960 7612 - C2_SIZE= 128 7613 - VECTOR_U_COMPRESSION_FACTOR= 10 7614 - VECTOR_V_COMPRESSION_FACTOR= 4 7615 - C1_BLOCK_SIZE= 320 7616 - ETA1= 2 7617 - ETA1_RANDOMNESS_SIZE= 128 7618 - ETA2= 2 7619 - ETA2_RANDOMNESS_SIZE= 128 7620 */ 7621 tuple_c2 7622 libcrux_ml_kem_ind_cca_encapsulate_ca( 7623 libcrux_ml_kem_types_MlKemPublicKey_30 *public_key, uint8_t *randomness) 7624 { 7625 uint8_t randomness0[32U]; 7626 entropy_preprocess_39_9c( 7627 Eurydice_array_to_slice((size_t)32U, randomness, uint8_t), randomness0); 7628 uint8_t to_hash[64U]; 7629 libcrux_ml_kem_utils_into_padded_array_24( 7630 Eurydice_array_to_slice((size_t)32U, randomness0, uint8_t), to_hash); 7631 Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( 7632 (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, 7633 size_t, uint8_t[]); 7634 uint8_t ret0[32U]; 7635 H_4a_e0(Eurydice_array_to_slice( 7636 (size_t)1184U, libcrux_ml_kem_types_as_slice_e6_d0(public_key), 7637 uint8_t), 7638 ret0); 7639 Eurydice_slice_copy( 7640 uu____0, Eurydice_array_to_slice((size_t)32U, ret0, uint8_t), uint8_t); 7641 uint8_t hashed[64U]; 7642 G_4a_e0(Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t), hashed); 7643 Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( 7644 Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), 7645 LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, 7646 Eurydice_slice_uint8_t_x2); 7647 Eurydice_slice shared_secret = uu____1.fst; 7648 Eurydice_slice pseudorandomness = uu____1.snd; 7649 uint8_t ciphertext[1088U]; 7650 encrypt_2a(Eurydice_array_to_slice( 7651 (size_t)1184U, libcrux_ml_kem_types_as_slice_e6_d0(public_key), 7652 uint8_t), 7653 randomness0, pseudorandomness, ciphertext); 7654 /* Passing arrays by value in Rust generates a copy in C */ 7655 uint8_t copy_of_ciphertext[1088U]; 7656 memcpy(copy_of_ciphertext, ciphertext, (size_t)1088U * sizeof(uint8_t)); 7657 tuple_c2 lit; 7658 lit.fst = libcrux_ml_kem_types_from_e0_80(copy_of_ciphertext); 7659 uint8_t ret[32U]; 7660 kdf_39_d6(shared_secret, ret); 7661 memcpy(lit.snd, ret, (size_t)32U * sizeof(uint8_t)); 7662 return lit; 7663 } 7664 7665 /** 7666 This function found in impl {core::ops::function::FnMut<(usize), 7667 libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0, 7668 TraitClause@1]> for libcrux_ml_kem::ind_cpa::decrypt::closure<Vector, K, 7669 CIPHERTEXT_SIZE, VECTOR_U_ENCODED_SIZE, U_COMPRESSION_FACTOR, 7670 V_COMPRESSION_FACTOR>[TraitClause@0, TraitClause@1]} 7671 */ 7672 /** 7673 A monomorphic instance of libcrux_ml_kem.ind_cpa.decrypt.call_mut_0b 7674 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 7675 with const generics 7676 - K= 3 7677 - CIPHERTEXT_SIZE= 1088 7678 - VECTOR_U_ENCODED_SIZE= 960 7679 - U_COMPRESSION_FACTOR= 10 7680 - V_COMPRESSION_FACTOR= 4 7681 */ 7682 static libcrux_ml_kem_polynomial_PolynomialRingElement_1d 7683 call_mut_0b_42( 7684 void **_) 7685 { 7686 return ZERO_d6_ea(); 7687 } 7688 7689 /** 7690 Call [`deserialize_to_uncompressed_ring_element`] for each ring element. 7691 */ 7692 /** 7693 A monomorphic instance of libcrux_ml_kem.ind_cpa.deserialize_vector 7694 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 7695 with const generics 7696 - K= 3 7697 */ 7698 static KRML_MUSTINLINE void 7699 deserialize_vector_1b( 7700 Eurydice_slice secret_key, 7701 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *secret_as_ntt) 7702 { 7703 KRML_MAYBE_FOR3( 7704 i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; 7705 libcrux_ml_kem_polynomial_PolynomialRingElement_1d uu____0 = 7706 deserialize_to_uncompressed_ring_element_ea(Eurydice_slice_subslice3( 7707 secret_key, i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, 7708 (i0 + (size_t)1U) * 7709 LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, 7710 uint8_t *)); 7711 secret_as_ntt[i0] = uu____0;); 7712 } 7713 7714 /** 7715 This function found in impl {core::ops::function::FnMut<(usize), 7716 libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0, 7717 TraitClause@1]> for 7718 libcrux_ml_kem::ind_cpa::deserialize_then_decompress_u::closure<Vector, K, 7719 CIPHERTEXT_SIZE, U_COMPRESSION_FACTOR>[TraitClause@0, TraitClause@1]} 7720 */ 7721 /** 7722 A monomorphic instance of 7723 libcrux_ml_kem.ind_cpa.deserialize_then_decompress_u.call_mut_35 with types 7724 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 7725 - K= 3 7726 - CIPHERTEXT_SIZE= 1088 7727 - U_COMPRESSION_FACTOR= 10 7728 */ 7729 static libcrux_ml_kem_polynomial_PolynomialRingElement_1d 7730 call_mut_35_6c( 7731 void **_) 7732 { 7733 return ZERO_d6_ea(); 7734 } 7735 7736 /** 7737 A monomorphic instance of 7738 libcrux_ml_kem.serialize.deserialize_then_decompress_ring_element_u with types 7739 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 7740 - COMPRESSION_FACTOR= 10 7741 */ 7742 static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d 7743 deserialize_then_decompress_ring_element_u_0a(Eurydice_slice serialized) 7744 { 7745 return deserialize_then_decompress_10_ea(serialized); 7746 } 7747 7748 /** 7749 A monomorphic instance of libcrux_ml_kem.ntt.ntt_vector_u 7750 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 7751 with const generics 7752 - VECTOR_U_COMPRESSION_FACTOR= 10 7753 */ 7754 static KRML_MUSTINLINE void 7755 ntt_vector_u_0a( 7756 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *re) 7757 { 7758 size_t zeta_i = (size_t)0U; 7759 ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)7U); 7760 ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)6U); 7761 ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)5U); 7762 ntt_at_layer_4_plus_ea(&zeta_i, re, (size_t)4U); 7763 ntt_at_layer_3_ea(&zeta_i, re); 7764 ntt_at_layer_2_ea(&zeta_i, re); 7765 ntt_at_layer_1_ea(&zeta_i, re); 7766 poly_barrett_reduce_d6_ea(re); 7767 } 7768 7769 /** 7770 Call [`deserialize_then_decompress_ring_element_u`] on each ring element 7771 in the `ciphertext`. 7772 */ 7773 /** 7774 A monomorphic instance of libcrux_ml_kem.ind_cpa.deserialize_then_decompress_u 7775 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 7776 with const generics 7777 - K= 3 7778 - CIPHERTEXT_SIZE= 1088 7779 - U_COMPRESSION_FACTOR= 10 7780 */ 7781 static KRML_MUSTINLINE void 7782 deserialize_then_decompress_u_6c( 7783 uint8_t *ciphertext, 7784 libcrux_ml_kem_polynomial_PolynomialRingElement_1d ret[3U]) 7785 { 7786 libcrux_ml_kem_polynomial_PolynomialRingElement_1d u_as_ntt[3U]; 7787 KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, 7788 /* original Rust expression is not an lvalue in C */ 7789 void *lvalue = (void *)0U; 7790 u_as_ntt[i] = call_mut_35_6c(&lvalue);); 7791 for (size_t i = (size_t)0U; 7792 i < Eurydice_slice_len( 7793 Eurydice_array_to_slice((size_t)1088U, ciphertext, uint8_t), 7794 uint8_t) / 7795 (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * 7796 (size_t)10U / (size_t)8U); 7797 i++) { 7798 size_t i0 = i; 7799 Eurydice_slice u_bytes = Eurydice_array_to_subslice3( 7800 ciphertext, 7801 i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * 7802 (size_t)10U / (size_t)8U), 7803 i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * 7804 (size_t)10U / (size_t)8U) + 7805 LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * 7806 (size_t)10U / (size_t)8U, 7807 uint8_t *); 7808 u_as_ntt[i0] = deserialize_then_decompress_ring_element_u_0a(u_bytes); 7809 ntt_vector_u_0a(&u_as_ntt[i0]); 7810 } 7811 memcpy( 7812 ret, u_as_ntt, 7813 (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); 7814 } 7815 7816 /** 7817 A monomorphic instance of 7818 libcrux_ml_kem.serialize.deserialize_then_decompress_ring_element_v with types 7819 libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics 7820 - K= 3 7821 - COMPRESSION_FACTOR= 4 7822 */ 7823 static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d 7824 deserialize_then_decompress_ring_element_v_89(Eurydice_slice serialized) 7825 { 7826 return deserialize_then_decompress_4_ea(serialized); 7827 } 7828 7829 /** 7830 The following functions compute various expressions involving 7831 vectors and matrices. The computation of these expressions has been 7832 abstracted away into these functions in order to save on loop iterations. 7833 Compute v − InverseNTT(sᵀ ◦ NTT(u)) 7834 */ 7835 /** 7836 A monomorphic instance of libcrux_ml_kem.matrix.compute_message 7837 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 7838 with const generics 7839 - K= 3 7840 */ 7841 static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d 7842 compute_message_1b( 7843 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *v, 7844 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *secret_as_ntt, 7845 libcrux_ml_kem_polynomial_PolynomialRingElement_1d *u_as_ntt) 7846 { 7847 libcrux_ml_kem_polynomial_PolynomialRingElement_1d result = ZERO_d6_ea(); 7848 KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; 7849 libcrux_ml_kem_polynomial_PolynomialRingElement_1d product = 7850 ntt_multiply_d6_ea(&secret_as_ntt[i0], &u_as_ntt[i0]); 7851 add_to_ring_element_d6_1b(&result, &product);); 7852 invert_ntt_montgomery_1b(&result); 7853 return subtract_reduce_d6_ea(v, result); 7854 } 7855 7856 /** 7857 This function implements <strong>Algorithm 14</strong> of the 7858 NIST FIPS 203 specification; this is the Kyber CPA-PKE decryption algorithm. 7859 7860 Algorithm 14 is reproduced below: 7861 7862 ```plaintext 7863 Input: decryption key dkₚₖₑ ∈ 𝔹^{384k}. 7864 Input: ciphertext c ∈ 𝔹^{32(dᵤk + dᵥ)}. 7865 Output: message m ∈ 𝔹^{32}. 7866 7867 c₁ ← c[0 : 32dᵤk] 7868 c₂ ← c[32dᵤk : 32(dᵤk + dᵥ)] 7869 u ← Decompress_{dᵤ}(ByteDecode_{dᵤ}(c₁)) 7870 v ← Decompress_{dᵥ}(ByteDecode_{dᵥ}(c₂)) 7871 ŝ ← ByteDecode₁₂(dkₚₖₑ) 7872 w ← v - NTT-¹(ŝᵀ ◦ NTT(u)) 7873 m ← ByteEncode₁(Compress₁(w)) 7874 return m 7875 ``` 7876 7877 The NIST FIPS 203 standard can be found at 7878 <https://csrc.nist.gov/pubs/fips/203/ipd>. 7879 */ 7880 /** 7881 A monomorphic instance of libcrux_ml_kem.ind_cpa.decrypt_unpacked 7882 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 7883 with const generics 7884 - K= 3 7885 - CIPHERTEXT_SIZE= 1088 7886 - VECTOR_U_ENCODED_SIZE= 960 7887 - U_COMPRESSION_FACTOR= 10 7888 - V_COMPRESSION_FACTOR= 4 7889 */ 7890 static KRML_MUSTINLINE void 7891 decrypt_unpacked_42( 7892 IndCpaPrivateKeyUnpacked_a0 *secret_key, uint8_t *ciphertext, 7893 uint8_t ret[32U]) 7894 { 7895 libcrux_ml_kem_polynomial_PolynomialRingElement_1d u_as_ntt[3U]; 7896 deserialize_then_decompress_u_6c(ciphertext, u_as_ntt); 7897 libcrux_ml_kem_polynomial_PolynomialRingElement_1d v = 7898 deserialize_then_decompress_ring_element_v_89( 7899 Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, 7900 (size_t)960U, uint8_t, size_t, 7901 uint8_t[])); 7902 libcrux_ml_kem_polynomial_PolynomialRingElement_1d message = 7903 compute_message_1b(&v, secret_key->secret_as_ntt, u_as_ntt); 7904 uint8_t ret0[32U]; 7905 compress_then_serialize_message_ea(message, ret0); 7906 memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); 7907 } 7908 7909 /** 7910 A monomorphic instance of libcrux_ml_kem.ind_cpa.decrypt 7911 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector 7912 with const generics 7913 - K= 3 7914 - CIPHERTEXT_SIZE= 1088 7915 - VECTOR_U_ENCODED_SIZE= 960 7916 - U_COMPRESSION_FACTOR= 10 7917 - V_COMPRESSION_FACTOR= 4 7918 */ 7919 static KRML_MUSTINLINE void 7920 decrypt_42(Eurydice_slice secret_key, 7921 uint8_t *ciphertext, uint8_t ret[32U]) 7922 { 7923 IndCpaPrivateKeyUnpacked_a0 secret_key_unpacked; 7924 libcrux_ml_kem_polynomial_PolynomialRingElement_1d ret0[3U]; 7925 KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, 7926 /* original Rust expression is not an lvalue in C */ 7927 void *lvalue = (void *)0U; 7928 ret0[i] = call_mut_0b_42(&lvalue);); 7929 memcpy( 7930 secret_key_unpacked.secret_as_ntt, ret0, 7931 (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); 7932 deserialize_vector_1b(secret_key, secret_key_unpacked.secret_as_ntt); 7933 uint8_t ret1[32U]; 7934 decrypt_unpacked_42(&secret_key_unpacked, ciphertext, ret1); 7935 memcpy(ret, ret1, (size_t)32U * sizeof(uint8_t)); 7936 } 7937 7938 /** 7939 This function found in impl {libcrux_ml_kem::hash_functions::Hash<K> for 7940 libcrux_ml_kem::hash_functions::portable::PortableHash<K>} 7941 */ 7942 /** 7943 A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRF_4a 7944 with const generics 7945 - K= 3 7946 - LEN= 32 7947 */ 7948 static inline void 7949 PRF_4a_41(Eurydice_slice input, uint8_t ret[32U]) 7950 { 7951 PRF_9e(input, ret); 7952 } 7953 7954 /** 7955 This code verifies on some machines, runs out of memory on others 7956 */ 7957 /** 7958 A monomorphic instance of libcrux_ml_kem.ind_cca.decapsulate 7959 with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, 7960 libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]], 7961 libcrux_ml_kem_variant_MlKem with const generics 7962 - K= 3 7963 - SECRET_KEY_SIZE= 2400 7964 - CPA_SECRET_KEY_SIZE= 1152 7965 - PUBLIC_KEY_SIZE= 1184 7966 - CIPHERTEXT_SIZE= 1088 7967 - T_AS_NTT_ENCODED_SIZE= 1152 7968 - C1_SIZE= 960 7969 - C2_SIZE= 128 7970 - VECTOR_U_COMPRESSION_FACTOR= 10 7971 - VECTOR_V_COMPRESSION_FACTOR= 4 7972 - C1_BLOCK_SIZE= 320 7973 - ETA1= 2 7974 - ETA1_RANDOMNESS_SIZE= 128 7975 - ETA2= 2 7976 - ETA2_RANDOMNESS_SIZE= 128 7977 - IMPLICIT_REJECTION_HASH_INPUT_SIZE= 1120 7978 */ 7979 void 7980 libcrux_ml_kem_ind_cca_decapsulate_62( 7981 libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, 7982 libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) 7983 { 7984 Eurydice_slice_uint8_t_x4 uu____0 = 7985 libcrux_ml_kem_types_unpack_private_key_b4( 7986 Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t)); 7987 Eurydice_slice ind_cpa_secret_key = uu____0.fst; 7988 Eurydice_slice ind_cpa_public_key = uu____0.snd; 7989 Eurydice_slice ind_cpa_public_key_hash = uu____0.thd; 7990 Eurydice_slice implicit_rejection_value = uu____0.f3; 7991 uint8_t decrypted[32U]; 7992 decrypt_42(ind_cpa_secret_key, ciphertext->value, decrypted); 7993 uint8_t to_hash0[64U]; 7994 libcrux_ml_kem_utils_into_padded_array_24( 7995 Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t), to_hash0); 7996 Eurydice_slice_copy( 7997 Eurydice_array_to_subslice_from( 7998 (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, 7999 uint8_t, size_t, uint8_t[]), 8000 ind_cpa_public_key_hash, uint8_t); 8001 uint8_t hashed[64U]; 8002 G_4a_e0(Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t), hashed); 8003 Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( 8004 Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), 8005 LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, 8006 Eurydice_slice_uint8_t_x2); 8007 Eurydice_slice shared_secret0 = uu____1.fst; 8008 Eurydice_slice pseudorandomness = uu____1.snd; 8009 uint8_t to_hash[1120U]; 8010 libcrux_ml_kem_utils_into_padded_array_15(implicit_rejection_value, to_hash); 8011 Eurydice_slice uu____2 = Eurydice_array_to_subslice_from( 8012 (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, 8013 uint8_t, size_t, uint8_t[]); 8014 Eurydice_slice_copy(uu____2, libcrux_ml_kem_types_as_ref_d3_80(ciphertext), 8015 uint8_t); 8016 uint8_t implicit_rejection_shared_secret0[32U]; 8017 PRF_4a_41(Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t), 8018 implicit_rejection_shared_secret0); 8019 uint8_t expected_ciphertext[1088U]; 8020 encrypt_2a(ind_cpa_public_key, decrypted, pseudorandomness, 8021 expected_ciphertext); 8022 uint8_t implicit_rejection_shared_secret[32U]; 8023 kdf_39_d6(Eurydice_array_to_slice((size_t)32U, 8024 implicit_rejection_shared_secret0, uint8_t), 8025 implicit_rejection_shared_secret); 8026 uint8_t shared_secret[32U]; 8027 kdf_39_d6(shared_secret0, shared_secret); 8028 uint8_t ret0[32U]; 8029 libcrux_ml_kem_constant_time_ops_compare_ciphertexts_select_shared_secret_in_constant_time( 8030 libcrux_ml_kem_types_as_ref_d3_80(ciphertext), 8031 Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, uint8_t), 8032 Eurydice_array_to_slice((size_t)32U, shared_secret, uint8_t), 8033 Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, 8034 uint8_t), 8035 ret0); 8036 memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); 8037 }