tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }