diff --git a/Cargo.lock b/Cargo.lock index 289347a87..87093de82 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -319,6 +319,17 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" +[[package]] +name = "classic-mceliece-rust" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45ce62f72a15a9071f83c5084bdf0af4e8cbf31431e79eb4a5509a2f7fe7fe5d" +dependencies = [ + "rand", + "sha3", + "zeroize", +] + [[package]] name = "colorchoice" version = "1.0.1" @@ -1045,6 +1056,18 @@ dependencies = [ "fs_extra", ] +[[package]] +name = "libcrux-psq" +version = "0.0.2-pre.2" +dependencies = [ + "classic-mceliece-rust", + "criterion", + "libcrux-hkdf", + "libcrux-hmac", + "libcrux-kem", + "rand", +] + [[package]] name = "libcrux-sha3" version = "0.0.2-pre.2" diff --git a/Cargo.toml b/Cargo.toml index cb0053d51..5c73a2917 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ members = [ "libcrux-kem", "libcrux-hmac", "libcrux-hkdf", - "libcrux-ecdh", + "libcrux-ecdh", "libcrux-psq", ] [workspace.package] diff --git a/benchmarks/benches/sha2.rs b/benchmarks/benches/sha2.rs index 297dee805..d9f82577e 100644 --- a/benchmarks/benches/sha2.rs +++ b/benchmarks/benches/sha2.rs @@ -10,7 +10,7 @@ macro_rules! impl_comp { ($fun:ident, $libcrux:expr, $ring:expr, $rust_crypto:ty, $openssl:expr) => { // Comparing libcrux performance for different payload sizes and other implementations. fn $fun(c: &mut Criterion) { - const PAYLOAD_SIZES: [usize; 1] = [1024 * 1024 * 10]; + const PAYLOAD_SIZES: [usize; 5] = [100, 1024, 2048, 4096, 8192]; let mut group = c.benchmark_group(stringify!($fun).replace("_", " ")); diff --git a/libcrux-ml-kem/Cargo.toml b/libcrux-ml-kem/Cargo.toml index f608db3a4..aba4166bb 100644 --- a/libcrux-ml-kem/Cargo.toml +++ b/libcrux-ml-kem/Cargo.toml @@ -29,9 +29,12 @@ libcrux-intrinsics = { version = "0.0.2-pre.2", path = "../libcrux-intrinsics" } hax-lib = { version = "0.1.0-pre.1", git = "https://github.com/hacspec/hax/" } [features] -default = ["std"] +default = ["std", "mlkem512", "mlkem768", "mlkem1024"] simd128 = ["libcrux-sha3/simd128"] simd256 = ["libcrux-sha3/simd256"] +mlkem512 = [] +mlkem768 = [] +mlkem1024 = [] std = [] kyber = [] diff --git a/libcrux-ml-kem/c.sh b/libcrux-ml-kem/c.sh index e1129e50c..73e296a44 100755 --- a/libcrux-ml-kem/c.sh +++ b/libcrux-ml-kem/c.sh @@ -16,6 +16,10 @@ portable_only=0 no_hacl=0 no_charon=0 clean=0 +config=c.yaml +out=c +glue=$EURYDICE_HOME/include/eurydice_glue.h +features= # Parse command line arguments. all_args=("$@") @@ -25,6 +29,10 @@ while [ $# -gt 0 ]; do --no-hacl) no_hacl=1 ;; --no-charon) no_charon=1 ;; -c | --clean) clean=1 ;; + --config) config="$2"; shift ;; + --out) out="$2"; shift ;; + --glue) glue="$2"; shift ;; + --mlkem768) features="--cargo-arg=--no-default-features --cargo-arg=--features=mlkem768" ;; esac shift done @@ -38,20 +46,20 @@ fi if [[ "$no_charon" = 0 ]]; then rm -rf ../libcrux_ml_kem.llbc ../libcrux_sha3.llbc echo "Running charon (sha3) ..." - (cd ../libcrux-sha3 && RUSTFLAGS="--cfg eurydice" $CHARON_HOME/bin/charon --errors-as-warnings) + (cd ../libcrux-sha3 && RUSTFLAGS="--cfg eurydice" $CHARON_HOME/bin/charon) if ! [[ -f ../libcrux_sha3.llbc ]]; then echo "😱😱😱 You are the victim of this bug: https://hacspec.zulipchat.com/#narrow/stream/433829-Circus/topic/charon.20declines.20to.20generate.20an.20llbc.20file" echo "Suggestion: rm -rf ../target or cargo clean" exit 1 fi echo "Running charon (ml-kem) ..." - RUSTFLAGS="--cfg eurydice" $CHARON_HOME/bin/charon --errors-as-warnings + RUSTFLAGS="--cfg eurydice" $CHARON_HOME/bin/charon $features else echo "Skipping charon" fi -mkdir -p c -cd c +mkdir -p $out +cd $out # Clean only when requesting it. # Note that we can not extract for all platforms on any platform right now. @@ -62,7 +70,7 @@ if [[ "$clean" = 1 ]]; then fi echo "Running eurydice ..." -$EURYDICE_HOME/eurydice --config ../c.yaml ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc +$EURYDICE_HOME/eurydice --config ../$config ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc cp $EURYDICE_HOME/include/eurydice_glue.h . clang-format --style=Google -i *.c *.h @@ -70,10 +78,10 @@ clang-format --style=Google -i internal/*.h clang-format --style=Google -i intrinsics/*.h # Write out infos about the used tools -[ -n "$CHARON_REV" ] || export CHARON_REV=$(git -C $CHARON_HOME rev-parse HEAD) -[ -n "$EURYDICE_REV" ] || export EURYDICE_REV=$(git -C $EURYDICE_HOME rev-parse HEAD) -[ -n "$KRML_REV" ] || export KRML_REV=$(git -C $KRML_HOME rev-parse HEAD) -[ -n "$FSTAR_REV" ] || export FSTAR_REV=$(git -C $FSTAR_HOME rev-parse HEAD) +[[ -z "$CHARON_REV" && -d $CHARON_HOME/.git ]] && export CHARON_REV=$(git -C $CHARON_HOME rev-parse HEAD) +[[ -z "$EURYDICE_REV" && -d $EURYDICE_HOME/.git ]] && export EURYDICE_REV=$(git -C $EURYDICE_HOME rev-parse HEAD) +[[ -z "$KRML_REV" && -d $KRML_HOME/.git ]] && export KRML_REV=$(git -C $KRML_HOME rev-parse HEAD) +[[ -z "$FSTAR_REV" && -d $FSTAR_HOME/.git ]] && export FSTAR_REV=$(git -C $FSTAR_HOME rev-parse HEAD) rm -f code_gen.txt echo "This code was generated with the following tools:" >> code_gen.txt echo -n "Charon: " >> code_gen.txt diff --git a/libcrux-ml-kem/c/internal/libcrux_core.h b/libcrux-ml-kem/c/internal/libcrux_core.h index d0fde74d7..093f9f802 100644 --- a/libcrux-ml-kem/c/internal/libcrux_core.h +++ b/libcrux-ml-kem/c/internal/libcrux_core.h @@ -15,12 +15,6 @@ extern "C" { #include "../libcrux_core.h" #include "eurydice_glue.h" -extern void core_fmt_rt__core__fmt__rt__Argument__a__1__none( - core_fmt_rt_Argument *x0); - -extern core_fmt_Arguments core_fmt__core__fmt__Arguments__a__2__new_v1( - Eurydice_slice x0, Eurydice_slice x1); - #define CORE_NUM__U32_8__BITS (32U) static inline uint32_t core_num__u8_6__count_ones(uint8_t x0); @@ -216,11 +210,6 @@ void core_result__core__result__Result_T__E___unwrap__uint8_t_10size_t__core_arr core_result_Result__uint8_t_10size_t__core_array_TryFromSliceError self, uint8_t ret[10U]); -typedef struct core_option_Option__Eurydice_slice_uint8_t_s { - core_option_Option__size_t_tags tag; - Eurydice_slice f0; -} core_option_Option__Eurydice_slice_uint8_t; - typedef struct core_result_Result__int16_t_16size_t__core_array_TryFromSliceError_s { core_result_Result__uint8_t_32size_t__core_array_TryFromSliceError_tags tag; diff --git a/libcrux-ml-kem/c/libcrux_mlkem_portable.c b/libcrux-ml-kem/c/libcrux_mlkem_portable.c index 3be04989a..48acd7696 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem_portable.c @@ -2206,72 +2206,61 @@ libcrux_ml_kem_vector_portable___libcrux_ml_kem__vector__traits__Operations_for_ inline size_t libcrux_ml_kem_vector_portable_sampling_rej_sample( Eurydice_slice a, Eurydice_slice result) { size_t sampled = (size_t)0U; - core_slice_iter_Chunks iter = - core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( - core_slice___Slice_T___chunks(a, (size_t)3U, uint8_t, - core_slice_iter_Chunks), - core_slice_iter_Chunks, core_slice_iter_Chunks); - while (true) { - core_option_Option__Eurydice_slice_uint8_t uu____0 = - core_slice_iter___core__iter__traits__iterator__Iterator_for_core__slice__iter__Chunks__a__T___70__next( - &iter, uint8_t, core_option_Option__Eurydice_slice_uint8_t); - if (uu____0.tag == core_option_None) { - break; - } else { - Eurydice_slice bytes = uu____0.f0; - int16_t b1 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, - uint8_t *, uint8_t); - int16_t b2 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, - uint8_t *, uint8_t); - int16_t b3 = (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, - uint8_t *, uint8_t); - int16_t d1 = (b2 & (int16_t)15) << 8U | b1; - int16_t d2 = b3 << 4U | b2 >> 4U; - bool uu____1; - int16_t uu____2; - bool uu____3; - size_t uu____4; - int16_t uu____5; - size_t uu____6; - int16_t uu____7; - if (d1 < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS) { - if (sampled < (size_t)16U) { - int16_t uu____8 = d1; - Eurydice_slice_index(result, sampled, int16_t, int16_t *, int16_t) = - uu____8; - sampled++; - uu____2 = d2; - uu____7 = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; - uu____1 = uu____2 < uu____7; - if (uu____1) { - uu____4 = sampled; - uu____3 = uu____4 < (size_t)16U; - if (uu____3) { - uu____5 = d2; - uu____6 = sampled; - Eurydice_slice_index(result, uu____6, int16_t, int16_t *, - int16_t) = uu____5; - sampled++; - continue; - } + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(a, uint8_t, size_t) / (size_t)3U; i++) { + size_t i0 = i; + int16_t b1 = (int16_t)Eurydice_slice_index(a, i0 * (size_t)3U + (size_t)0U, + uint8_t, uint8_t *, uint8_t); + int16_t b2 = (int16_t)Eurydice_slice_index(a, i0 * (size_t)3U + (size_t)1U, + uint8_t, uint8_t *, uint8_t); + int16_t b3 = (int16_t)Eurydice_slice_index(a, i0 * (size_t)3U + (size_t)2U, + uint8_t, uint8_t *, uint8_t); + int16_t d1 = (b2 & (int16_t)15) << 8U | b1; + int16_t d2 = b3 << 4U | b2 >> 4U; + bool uu____0; + int16_t uu____1; + bool uu____2; + size_t uu____3; + int16_t uu____4; + size_t uu____5; + int16_t uu____6; + if (d1 < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS) { + if (sampled < (size_t)16U) { + int16_t uu____7 = d1; + Eurydice_slice_index(result, sampled, int16_t, int16_t *, int16_t) = + uu____7; + sampled++; + uu____1 = d2; + uu____6 = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + uu____0 = uu____1 < uu____6; + if (uu____0) { + uu____3 = sampled; + uu____2 = uu____3 < (size_t)16U; + if (uu____2) { + uu____4 = d2; + uu____5 = sampled; + Eurydice_slice_index(result, uu____5, int16_t, int16_t *, int16_t) = + uu____4; + sampled++; + continue; } - continue; } + continue; } - uu____2 = d2; - uu____7 = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; - uu____1 = uu____2 < uu____7; - if (uu____1) { - uu____4 = sampled; - uu____3 = uu____4 < (size_t)16U; - if (uu____3) { - uu____5 = d2; - uu____6 = sampled; - Eurydice_slice_index(result, uu____6, int16_t, int16_t *, int16_t) = - uu____5; - sampled++; - continue; - } + } + uu____1 = d2; + uu____6 = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + uu____0 = uu____1 < uu____6; + if (uu____0) { + uu____3 = sampled; + uu____2 = uu____3 < (size_t)16U; + if (uu____2) { + uu____4 = d2; + uu____5 = sampled; + Eurydice_slice_index(result, uu____5, int16_t, int16_t *, int16_t) = + uu____4; + sampled++; + continue; } } } diff --git a/libcrux-ml-kem/c/libcrux_sha3_neon.c b/libcrux-ml-kem/c/libcrux_sha3_neon.c index 290cc562b..f36816787 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_neon.c +++ b/libcrux-ml-kem/c/libcrux_sha3_neon.c @@ -7,22 +7,8 @@ #include "libcrux_sha3_neon.h" -#include "internal/libcrux_core.h" - inline void libcrux_sha3_neon_sha512(Eurydice_slice digest, Eurydice_slice data) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); KRML_HOST_EXIT(255U); @@ -30,18 +16,6 @@ inline void libcrux_sha3_neon_sha512(Eurydice_slice digest, inline void libcrux_sha3_neon_sha256(Eurydice_slice digest, Eurydice_slice data) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); KRML_HOST_EXIT(255U); @@ -51,18 +25,6 @@ inline void libcrux_sha3_neon_x2_shake256(Eurydice_slice input0, Eurydice_slice input1, Eurydice_slice out0, Eurydice_slice out1) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); KRML_HOST_EXIT(255U); @@ -70,18 +32,6 @@ inline void libcrux_sha3_neon_x2_shake256(Eurydice_slice input0, inline libcrux_sha3_neon_x2_incremental_KeccakState2 libcrux_sha3_neon_x2_incremental_shake128_init(void) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); KRML_HOST_EXIT(255U); @@ -90,18 +40,6 @@ libcrux_sha3_neon_x2_incremental_shake128_init(void) { inline void libcrux_sha3_neon_x2_incremental_shake128_absorb_final( libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice data0, Eurydice_slice data1) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); KRML_HOST_EXIT(255U); @@ -110,18 +48,6 @@ inline void libcrux_sha3_neon_x2_incremental_shake128_absorb_final( inline void libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice out0, Eurydice_slice out1) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); KRML_HOST_EXIT(255U); @@ -131,18 +57,6 @@ inline void libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice out0, Eurydice_slice out1) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); KRML_HOST_EXIT(255U); @@ -150,18 +64,6 @@ libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( inline void libcrux_sha3_neon_sha224(Eurydice_slice digest, Eurydice_slice data) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); KRML_HOST_EXIT(255U); @@ -169,18 +71,6 @@ inline void libcrux_sha3_neon_sha224(Eurydice_slice digest, inline void libcrux_sha3_neon_sha384(Eurydice_slice digest, Eurydice_slice data) { - Prims_string buf[1U] = { - "not implemented: The target architecture does not support neon " - "instructions."}; - Eurydice_slice uu____0 = - Eurydice_array_to_slice((size_t)1U, buf, Prims_string, Eurydice_slice); - core_fmt_rt_Argument ret[0U]; - core_fmt_rt__core__fmt__rt__Argument__a__1__none(ret); - LowStar_Ignore_ignore( - core_fmt__core__fmt__Arguments__a__2__new_v1( - uu____0, Eurydice_array_to_slice( - (size_t)0U, ret, core_fmt_rt_Argument, Eurydice_slice)), - core_fmt_Arguments, void *); KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, "panic!"); KRML_HOST_EXIT(255U); diff --git a/libcrux-ml-kem/c/libcrux_sha3_neon.h b/libcrux-ml-kem/c/libcrux_sha3_neon.h index 519ed63a4..281c9682e 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_neon.h +++ b/libcrux-ml-kem/c/libcrux_sha3_neon.h @@ -14,7 +14,6 @@ extern "C" { #include "eurydice_glue.h" #include "intrinsics/libcrux_intrinsics_arm64.h" -#include "libcrux_core.h" #include "libcrux_sha3_internal.h" void libcrux_sha3_neon_sha512(Eurydice_slice digest, Eurydice_slice data); diff --git a/libcrux-ml-kem/cg.yaml b/libcrux-ml-kem/cg.yaml new file mode 100644 index 000000000..d4b5be5a8 --- /dev/null +++ b/libcrux-ml-kem/cg.yaml @@ -0,0 +1,155 @@ +files: + # INTRINSICS + + - name: libcrux_intrinsics_avx2 + library: true + inline_static: true + api: + - [libcrux_intrinsics, avx2] + + # SHA3 (no mention of libcrux_mlkem in this section, please) + + - name: libcrux_sha3_avx2 + inline_static: true + # This is needed solely for the benchmarking test -- otherwise these would + # all be private. Note that the order matters! So we put these first so that + # they match immediately (and get promoted to internal), then the rest of + # the behavior applies. + api: + patterns: + - [libcrux_sha3, avx2, "*"] + - [libcrux_sha3, simd, avx2, "*"] + exact: + - [libcrux_sha3, avx2, x4, incremental, KeccakState4] + monomorphizations_exact: + - [libcrux_sha3, avx2, x4, incremental, KeccakState4] + - [libcrux_sha3, generic_keccak, absorb_final__core_core_arch_x86___m256i_4size_t_168size_t_31uint8_t ] + - [libcrux_sha3, generic_keccak, squeeze_first_three_blocks__core_core_arch_x86___m256i_4size_t_168size_t ] + - [libcrux_sha3, generic_keccak, "KeccakState__core_core_arch_x86___m256i_$4size_t"] + monomorphizations_of: + - [libcrux_sha3, avx2, "*"] + - [libcrux_sha3, simd, avx2, "*"] + monomorphizations_using: + # Should this also include the monomorphizations using + # core.arch.x86.__m256i? + - [libcrux_sha3, avx2, "*"] + - [libcrux_sha3, simd, avx2, "*"] + include_in_h: + - '"intrinsics/libcrux_intrinsics_avx2.h"' + + # Portable SHA3 + - name: libcrux_sha3_portable + inline_static: true + api: + patterns: + - [libcrux_sha3, "*"] + monomorphizations_of: + - [libcrux_sha3, "*"] + monomorphizations_using: + - [libcrux_sha3, "*"] + + # Common parts of SHA3 (this catches stuff that hasn't matched above). Must + # # come after the (more precise) patterns above concerning platform-specific hash_functions + # - name: libcrux_sha3_internal + # api: + # patterns: + # - [libcrux_sha3, "*"] + # monomorphizations_of: + # - [libcrux_sha3, "*"] + # monomorphizations_using: + # - [libcrux_sha3, "*"] + # inline_static: true + + # MLKEM: HASH FUNCTIONS (as used by mlkem) + + # - name: libcrux_mlkem_avx2 + # api: + # - [libcrux_ml_kem, vector, avx2, "*"] + # - [libcrux_ml_kem, hash_functions, avx2, "*"] + # private: + # monomorphizations_using: + # - [libcrux_ml_kem, vector, avx2, "*"] + # - [libcrux_ml_kem, hash_functions, avx2, "*"] + # monomorphizations_of: + # - [libcrux_ml_kem, vector, avx2, "*"] + # - [libcrux_ml_kem, hash_functions, avx2, "*"] + + # # This covers slightly more than the two bundles above, but this greatly + # # simplifies our lives. + # - name: libcrux_mlkem_portable + # inline_static: true + # api: + # patterns: + # - [libcrux_ml_kem, vector, "*"] + # - [libcrux_ml_kem, hash_functions, portable, "*"] + # - [ libcrux_ml_kem, polynomial, "*" ] + # monomorphizations_using: + # - [ libcrux_ml_kem, polynomial, "*" ] + # - [libcrux_ml_kem, vector, "*"] + # - [libcrux_ml_kem, hash_functions, portable, "*"] + # monomorphizations_of: + # - [ libcrux_ml_kem, polynomial, "*" ] + # - [libcrux_ml_kem, vector, "*"] + # - [libcrux_ml_kem, hash_functions, portable, "*"] + + # MLKEM: MISC NON-ARCHITECTURE SPECIFIC HEADERS + - name: libcrux_core + inline_static: true + private: + monomorphizations_of: + - [core, "*"] + - [libcrux_ml_kem, types, "*"] + - [libcrux_ml_kem, constant_time_ops, "*"] + - [libcrux_ml_kem, utils, "*" ] + monomorphizations_using: + - [Eurydice, "*" ] + - [libcrux_ml_kem, types, "*"] + patterns: + - [core, "*"] + - [libcrux_ml_kem, types ] + - [libcrux_ml_kem, constants ] + - [libcrux_ml_kem, constant_time_ops, "*"] + - [libcrux_ml_kem, utils, "*" ] + api: + - [Eurydice, "*"] + + # MLKEM-768 + + - name: libcrux_mlkem768_avx2 + inline_static: true + api: + patterns: + - [libcrux_ml_kem, vector, avx2, "*"] + - [libcrux_ml_kem, hash_functions, avx2, "*"] + - [libcrux_ml_kem, mlkem768, avx2] + - [libcrux_ml_kem, ind_cca, instantiations, avx2] + monomorphizations_of: + - [libcrux_ml_kem, vector, avx2, "*"] + - [libcrux_ml_kem, hash_functions, avx2, "*"] + - [libcrux_ml_kem, mlkem768, avx2] + - [libcrux_ml_kem, ind_cca, instantiations, avx2] + monomorphizations_using: + - [libcrux_ml_kem, vector, avx2, "*"] + - [libcrux_ml_kem, hash_functions, avx2, "*"] + + - name: libcrux_mlkem768_portable + inline_static: true + api: + patterns: + - [libcrux_ml_kem, "*"] + - [libcrux_ml_kem, vector, "*"] + - [libcrux_ml_kem, hash_functions, portable, "*"] + # - [libcrux_ml_kem, polynomial, "*" ] + - [libcrux_ml_kem, mlkem768, portable, "*"] + - [libcrux_ml_kem, ind_cca, instantiations, portable, "*"] + monomorphizations_of: + - [libcrux_ml_kem, polynomial, "*" ] + - [libcrux_ml_kem, vector, "*"] + - [libcrux_ml_kem, hash_functions, portable, "*"] + - [libcrux_ml_kem, mlkem768, portable] + - [libcrux_ml_kem, ind_cca, instantiations, portable, "*"] + monomorphizations_using: + - [libcrux_ml_kem, polynomial, "*" ] + - [libcrux_ml_kem, vector, "*"] + - [libcrux_ml_kem, hash_functions, portable, "*"] + - [libcrux_ml_kem, ind_cca, instantiations, portable, "*"] diff --git a/libcrux-ml-kem/cg/.gitignore b/libcrux-ml-kem/cg/.gitignore new file mode 100644 index 000000000..378eac25d --- /dev/null +++ b/libcrux-ml-kem/cg/.gitignore @@ -0,0 +1 @@ +build diff --git a/libcrux-ml-kem/cg/CMakeLists.txt b/libcrux-ml-kem/cg/CMakeLists.txt new file mode 100644 index 000000000..907860fd8 --- /dev/null +++ b/libcrux-ml-kem/cg/CMakeLists.txt @@ -0,0 +1,129 @@ +# cmake -B build -G "Ninja Multi-Config" +# cmake --build build +# # For release (benchmarks) +# cmake --build build --config Release + +cmake_minimum_required(VERSION 3.10) + +project(libcrux-ml-kem + VERSION 0.1.0 + LANGUAGES C CXX +) + +set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD 20) + +if(NOT MSVC) + # TODO: Clean up + add_compile_options( + -Wall + # -Wextra + # -pedantic + # -Wconversion + # -Wsign-conversion + $<$:-g> + $<$:-Og> + $<$:-g> + $<$:-O3> + ) +endif(NOT MSVC) + +set(CMAKE_COLOR_DIAGNOSTICS "ON") +include_directories( + ${PROJECT_SOURCE_DIR} + ${PROJECT_SOURCE_DIR}/internal + ${PROJECT_SOURCE_DIR}/karamel/include +) + +if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|AMD64") + message(STATUS "Detected an x64 architecture") + add_compile_definitions(LIBCRUX_X64) +endif() + +if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64|arm64v8" AND DEFINED ENV{LIBCRUX_NEON}) + message(STATUS "Detected an arm64 architecture") + add_compile_definitions(LIBCRUX_AARCH64) +endif() + +# --- Tests + +# Get gtests +include(FetchContent) +FetchContent_Declare(googletest + DOWNLOAD_EXTRACT_TIMESTAMP TRUE + URL https://github.com/google/googletest/archive/refs/tags/release-1.11.0.zip +) + +# For Windows: Prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +FetchContent_MakeAvailable(googletest) + +# Get nlohmann json +FetchContent_Declare(json + DOWNLOAD_EXTRACT_TIMESTAMP TRUE + URL https://github.com/nlohmann/json/archive/refs/tags/v3.10.3.zip +) +FetchContent_MakeAvailable(json) + +add_executable(ml_kem_test + ${PROJECT_SOURCE_DIR}/tests/mlkem768.cc +) +target_link_libraries(ml_kem_test PRIVATE + gtest_main + nlohmann_json::nlohmann_json +) + +add_executable(sha3_test + ${PROJECT_SOURCE_DIR}/tests/sha3.cc +) +target_link_libraries(sha3_test PRIVATE + gtest_main + nlohmann_json::nlohmann_json +) + +# --- Benchmarks +FetchContent_Declare(benchmark + GIT_REPOSITORY https://github.com/google/benchmark.git + GIT_TAG v1.8.4 +) +FetchContent_MakeAvailable(benchmark) + +add_executable(ml_kem_bench + ${PROJECT_SOURCE_DIR}/benches/mlkem768.cc +) +target_link_libraries(ml_kem_bench PRIVATE + benchmark::benchmark +) + +if(DEFINED ENV{SYMCRYPT_PATH}) + message("Symcrypt path: $ENV{SYMCRYPT_PATH}") + add_compile_definitions(LIBCRUX_SYMCRYPT) + target_include_directories(ml_kem_bench PRIVATE $ENV{SYMCRYPT_PATH}) + target_link_directories(ml_kem_bench PRIVATE $ENV{SYMCRYPT_PATH}/bin/lib) + target_link_libraries(ml_kem_bench PRIVATE symcrypt) +endif(DEFINED ENV{SYMCRYPT_PATH}) + +add_executable(ml_kem_keygen + ${PROJECT_SOURCE_DIR}/benches/mlkem768_keygen.cc +) +target_link_libraries(ml_kem_keygen PRIVATE + benchmark::benchmark +) + +add_executable(ml_kem_encaps + ${PROJECT_SOURCE_DIR}/benches/mlkem768_encaps.cc +) +target_link_libraries(ml_kem_encaps PRIVATE + benchmark::benchmark +) + +if(NOT MSVC) + # We benchmark internal functions here that are inlined and thus not available + # in MSVC. + add_executable(sha3_bench + ${PROJECT_SOURCE_DIR}/benches/sha3.cc + ) + target_link_libraries(sha3_bench PRIVATE + benchmark::benchmark + ) +endif(NOT MSVC) diff --git a/libcrux-ml-kem/cg/README.md b/libcrux-ml-kem/cg/README.md new file mode 100644 index 000000000..3e2297c0d --- /dev/null +++ b/libcrux-ml-kem/cg/README.md @@ -0,0 +1,40 @@ +# ML-KEM + +This folder contains the extracted ML-KEM C code. + +## Generating C code + +The C code is generated from Rust using [Charon], [Eurydice] and [Karamel]. +The [c.sh](../c.sh) bash script drives the extraction, using the [c.yaml](../c.yaml) +configuration file. +While running the commands separately is possible, it is not recommended because +the script sets all necessary configuration flags. + +## Build + +Make sure to use `CC=clang CXX=clang++` when benchmarking on Linux to get full performance. + +```bash +cmake -B build -G "Ninja Multi-Config" +cmake --build build +``` + +To enable neon builds, set `LIBCRUX_NEON=1`. + +### Test + +```bash +./build/Debug/ml_kem_test +``` + +## Benchmarks + +```bash +cmake -B build -G "Ninja Multi-Config" +cmake --build build --config Release +./build/Release/ml_kem_bench +``` + +[Charon]: https://github.com/AeneasVerif/charon/ +[Eurydice]: https://github.com/AeneasVerif/eurydice +[Karamel]: https://github.com/FStarLang/karamel diff --git a/libcrux-ml-kem/cg/benches/mlkem768.cc b/libcrux-ml-kem/cg/benches/mlkem768.cc new file mode 100644 index 000000000..b96be2b79 --- /dev/null +++ b/libcrux-ml-kem/cg/benches/mlkem768.cc @@ -0,0 +1,245 @@ +/* + * Copyright 2022 Cryspen Sarl + * + * Licensed under the Apache License, Version 2.0 or MIT. + * - http://www.apache.org/licenses/LICENSE-2.0 + * - http://opensource.org/licenses/MIT + */ + +#include + +#include "libcrux_mlkem768_portable.h" + +void generate_random(uint8_t *output, uint32_t output_len) +{ + for (int i = 0; i < output_len; i++) + output[i] = 13; +} + +static void +kyber768_key_generation(benchmark::State &state) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + auto key_pair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(randomness); + + for (auto _ : state) + { + key_pair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(randomness); + } +} + +static void +kyber768_encapsulation(benchmark::State &state) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + + auto key_pair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(randomness); + generate_random(randomness, 32); + auto ctxt = libcrux_ml_kem_mlkem768_portable_encapsulate(&key_pair.pk, randomness); + + for (auto _ : state) + { + ctxt = libcrux_ml_kem_mlkem768_portable_encapsulate(&key_pair.pk, randomness); + } +} + +static void +kyber768_decapsulation(benchmark::State &state) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + + auto key_pair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(randomness); + generate_random(randomness, 32); + auto ctxt = libcrux_ml_kem_mlkem768_portable_encapsulate(&key_pair.pk, randomness); + + uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; + + for (auto _ : state) + { + libcrux_ml_kem_mlkem768_portable_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + } +} + +BENCHMARK(kyber768_key_generation); +BENCHMARK(kyber768_encapsulation); +BENCHMARK(kyber768_decapsulation); + +#ifdef LIBCRUX_AARCH64 +#include "libcrux_mlkem768_neon.h" + +static void +kyber768_key_generation_neon(benchmark::State &state) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + auto key_pair = libcrux_ml_kem_mlkem768_neon_generate_key_pair(randomness); + + for (auto _ : state) + { + key_pair = libcrux_ml_kem_mlkem768_neon_generate_key_pair(randomness); + } +} + +static void +kyber768_encapsulation_neon(benchmark::State &state) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + + auto key_pair = libcrux_ml_kem_mlkem768_neon_generate_key_pair(randomness); + generate_random(randomness, 32); + auto ctxt = libcrux_ml_kem_mlkem768_neon_encapsulate(&key_pair.pk, randomness); + + for (auto _ : state) + { + ctxt = libcrux_ml_kem_mlkem768_neon_encapsulate(&key_pair.pk, randomness); + } +} + +static void +kyber768_decapsulation_neon(benchmark::State &state) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + + auto key_pair = libcrux_ml_kem_mlkem768_neon_generate_key_pair(randomness); + generate_random(randomness, 32); + auto ctxt = libcrux_ml_kem_mlkem768_neon_encapsulate(&key_pair.pk, randomness); + + uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; + + for (auto _ : state) + { + libcrux_ml_kem_mlkem768_neon_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + } +} + +BENCHMARK(kyber768_key_generation_neon); +BENCHMARK(kyber768_encapsulation_neon); +BENCHMARK(kyber768_decapsulation_neon); +#endif + +#ifdef LIBCRUX_X64 +#include "libcrux_mlkem768_avx2.h" + +static void +kyber768_key_generation_avx2(benchmark::State &state) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + auto key_pair = libcrux_ml_kem_mlkem768_avx2_generate_key_pair(randomness); + + for (auto _ : state) + { + key_pair = libcrux_ml_kem_mlkem768_avx2_generate_key_pair(randomness); + } +} + +static void +kyber768_encapsulation_avx2(benchmark::State &state) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + + auto key_pair = libcrux_ml_kem_mlkem768_avx2_generate_key_pair(randomness); + generate_random(randomness, 32); + auto ctxt = libcrux_ml_kem_mlkem768_avx2_encapsulate(&key_pair.pk, randomness); + + for (auto _ : state) + { + ctxt = libcrux_ml_kem_mlkem768_avx2_encapsulate(&key_pair.pk, randomness); + } +} + +static void +kyber768_decapsulation_avx2(benchmark::State &state) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + + auto key_pair = libcrux_ml_kem_mlkem768_avx2_generate_key_pair(randomness); + generate_random(randomness, 32); + auto ctxt = libcrux_ml_kem_mlkem768_avx2_encapsulate(&key_pair.pk, randomness); + + uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; + + for (auto _ : state) + { + libcrux_ml_kem_mlkem768_avx2_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + } +} + +BENCHMARK(kyber768_key_generation_avx2); +BENCHMARK(kyber768_encapsulation_avx2); +BENCHMARK(kyber768_decapsulation_avx2); +#endif + +#ifdef LIBCRUX_SYMCRYPT +#include "inc/symcrypt.h" + +static void +symcrypt_kyber768_key_generation(benchmark::State &state) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + auto pKey = SymCryptMlKemkeyAllocate(SymCryptMlKemParamsDraft203MlKem768); + SymCryptMlKemkeyGenerate(pKey, 0); + + for (auto _ : state) + { + pKey = SymCryptMlKemkeyAllocate(SymCryptMlKemParamsDraft203MlKem768); + SymCryptMlKemkeyGenerate(pKey, 0); + } +} + +static void +symcrypt_kyber768_encapsulation(benchmark::State &state) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + + auto pKey = SymCryptMlKemkeyAllocate(SymCryptMlKemParamsDraft203MlKem768); + SymCryptMlKemkeyGenerate(pKey, 0); + generate_random(randomness, 32); + + BYTE secret[32]; + BYTE cipher[1088]; + SymCryptMlKemEncapsulate(pKey, secret, 32, cipher, 1088); + + for (auto _ : state) + { + SymCryptMlKemEncapsulate(pKey, secret, 32, cipher, 1088); + } +} + +static void +symcrypt_kyber768_decapsulation(benchmark::State &state) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + + auto pKey = SymCryptMlKemkeyAllocate(SymCryptMlKemParamsDraft203MlKem768); + SymCryptMlKemkeyGenerate(pKey, 0); + + generate_random(randomness, 32); + BYTE secret[32]; + BYTE cipher[1088]; + SymCryptMlKemEncapsulate(pKey, secret, 32, cipher, 1088); + + BYTE sharedSecret2[32]; + + for (auto _ : state) + { + SymCryptMlKemDecapsulate(pKey, cipher, 1088, sharedSecret2, 32); + } +} + +BENCHMARK(symcrypt_kyber768_key_generation); +BENCHMARK(symcrypt_kyber768_encapsulation); +BENCHMARK(symcrypt_kyber768_decapsulation); +#endif + +BENCHMARK_MAIN(); diff --git a/libcrux-ml-kem/cg/benches/mlkem768_encaps.cc b/libcrux-ml-kem/cg/benches/mlkem768_encaps.cc new file mode 100644 index 000000000..28657ab5a --- /dev/null +++ b/libcrux-ml-kem/cg/benches/mlkem768_encaps.cc @@ -0,0 +1,34 @@ +/* + * Copyright 2022 Cryspen Sarl + * + * Licensed under the Apache License, Version 2.0 or MIT. + * - http://www.apache.org/licenses/LICENSE-2.0 + * - http://opensource.org/licenses/MIT + */ + +#include + +#include "libcrux_mlkem768_portable.h" + +void generate_random(uint8_t *output, uint32_t output_len) +{ + for (int i = 0; i < output_len; i++) + output[i] = 13; +} + +int main(int argc, char const *argv[]) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + + auto key_pair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(randomness); + generate_random(randomness, 32); + auto ctxt = libcrux_ml_kem_mlkem768_portable_encapsulate(&key_pair.pk, randomness); + + for (size_t i = 0; i < 100000; i++) + { + ctxt = libcrux_ml_kem_mlkem768_portable_encapsulate(&key_pair.pk, randomness); + } + + return 0; +} diff --git a/libcrux-ml-kem/cg/benches/mlkem768_keygen.cc b/libcrux-ml-kem/cg/benches/mlkem768_keygen.cc new file mode 100644 index 000000000..c4be578c0 --- /dev/null +++ b/libcrux-ml-kem/cg/benches/mlkem768_keygen.cc @@ -0,0 +1,30 @@ +/* + * Copyright 2022 Cryspen Sarl + * + * Licensed under the Apache License, Version 2.0 or MIT. + * - http://www.apache.org/licenses/LICENSE-2.0 + * - http://opensource.org/licenses/MIT + */ + +#include + +#include "libcrux_mlkem768_portable.h" + +void generate_random(uint8_t *output, uint32_t output_len) +{ + for (int i = 0; i < output_len; i++) + output[i] = 13; +} + +int main(int argc, char const *argv[]) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + auto key_pair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(randomness); + + for (size_t i = 0; i < 100000; i++) + { + key_pair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(randomness); + } + return 0; +} diff --git a/libcrux-ml-kem/cg/benches/sha3.cc b/libcrux-ml-kem/cg/benches/sha3.cc new file mode 100644 index 000000000..b7c9d7777 --- /dev/null +++ b/libcrux-ml-kem/cg/benches/sha3.cc @@ -0,0 +1,136 @@ +/* + * Copyright 2022 Cryspen Sarl + * + * Licensed under the Apache License, Version 2.0 or MIT. + * - http://www.apache.org/licenses/LICENSE-2.0 + * - http://opensource.org/licenses/MIT + */ + +#include + +// TODO: FIXME: why is the macro definition in +// karamel/include/krml/internal/target.h not working? +// This is only broken in C++ +#define KRML_HOST_EPRINTF(...) fprintf(stderr, __VA_ARGS__) + +#include "libcrux_sha3_portable.h" + +#ifdef LIBCRUX_X64 +#include "libcrux_sha3_avx2.h" +#endif + +void generate_random(uint8_t *output, uint32_t output_len) +{ + for (int i = 0; i < output_len; i++) + output[i] = 13; +} + +static void +sha3_256_1184(benchmark::State &state) +{ + uint8_t digest[32]; + uint8_t input[1184]; + generate_random(input, 1184); + + libcrux_sha3_portable_sha256(EURYDICE_SLICE(input, 0, 32), EURYDICE_SLICE(digest, 0, 32)); + + for (auto _ : state) + { + libcrux_sha3_portable_sha256(EURYDICE_SLICE(input, 0, 32), EURYDICE_SLICE(digest, 0, 32)); + } +} + +static void +sha3_512_64(benchmark::State &state) +{ + uint8_t digest[64]; + uint8_t input[64]; + generate_random(input, 64); + + libcrux_sha3_portable_sha512(EURYDICE_SLICE(input, 0, 64), EURYDICE_SLICE(digest, 0, 64)); + + for (auto _ : state) + { + libcrux_sha3_portable_sha512(EURYDICE_SLICE(input, 0, 64), EURYDICE_SLICE(digest, 0, 64)); + } +} + +#ifdef LIBCRUX_X64 +static void +shake128_34_504(benchmark::State &state) +{ + uint8_t digest0[504]; + uint8_t digest1[504]; + uint8_t digest2[504]; + uint8_t digest3[504]; + uint8_t input[34]; + generate_random(input, 34); + + Eurydice_slice last[4] = {EURYDICE_SLICE(input, 0, 34), EURYDICE_SLICE(input, 0, 34), EURYDICE_SLICE(input, 0, 34), EURYDICE_SLICE(input, 0, 34)}; + Eurydice_slice out[4] = {EURYDICE_SLICE(digest0, 0, 504), EURYDICE_SLICE(digest1, 0, 504), EURYDICE_SLICE(digest2, 0, 504), EURYDICE_SLICE(digest3, 0, 504)}; + libcrux_sha3_avx2_x4_incremental_KeccakState4 st = libcrux_sha3_avx2_x4_incremental_shake128_init(); + libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_168size_t_31uint8_t(&st, last); + libcrux_sha3_generic_keccak_squeeze_first_three_blocks__core_core_arch_x86___m256i_4size_t_168size_t(&st, out); + + for (auto _ : state) + { + libcrux_sha3_avx2_x4_incremental_KeccakState4 st = libcrux_sha3_avx2_x4_incremental_shake128_init(); + libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_168size_t_31uint8_t(&st, last); + libcrux_sha3_generic_keccak_squeeze_first_three_blocks__core_core_arch_x86___m256i_4size_t_168size_t(&st, out); + } +} + +static void +shake256_1120_32(benchmark::State &state) +{ + uint8_t input[1120]; + generate_random(input, 1120); + + uint8_t digest0[32]; + uint8_t digest1[32]; + uint8_t digest2[32]; + uint8_t digest3[32]; + Eurydice_slice out0 = EURYDICE_SLICE(digest0, 0, 32); + Eurydice_slice out1 = EURYDICE_SLICE(digest1, 0, 32); + Eurydice_slice out2 = EURYDICE_SLICE(digest2, 0, 32); + Eurydice_slice out3 = EURYDICE_SLICE(digest3, 0, 32); + + libcrux_sha3_avx2_x4_shake256(EURYDICE_SLICE(input, 0, 1120), EURYDICE_SLICE(input, 0, 1120), EURYDICE_SLICE(input, 0, 1120), EURYDICE_SLICE(input, 0, 1120), out0, out1, out2, out3); + + for (auto _ : state) + { + libcrux_sha3_avx2_x4_shake256(EURYDICE_SLICE(input, 0, 1120), EURYDICE_SLICE(input, 0, 1120), EURYDICE_SLICE(input, 0, 1120), EURYDICE_SLICE(input, 0, 1120), out0, out1, out2, out3); + } +} + +static void +shake256_33_128(benchmark::State &state) +{ + uint8_t input[33]; + generate_random(input, 33); + + uint8_t digest0[128]; + uint8_t digest1[128]; + uint8_t digest2[128]; + uint8_t digest3[128]; + Eurydice_slice out0 = EURYDICE_SLICE(digest0, 0, 128); + Eurydice_slice out1 = EURYDICE_SLICE(digest1, 0, 128); + Eurydice_slice out2 = EURYDICE_SLICE(digest2, 0, 128); + Eurydice_slice out3 = EURYDICE_SLICE(digest3, 0, 128); + + libcrux_sha3_avx2_x4_shake256(EURYDICE_SLICE(input, 0, 128), EURYDICE_SLICE(input, 0, 128), EURYDICE_SLICE(input, 0, 128), EURYDICE_SLICE(input, 0, 128), out0, out1, out2, out3); + + for (auto _ : state) + { + libcrux_sha3_avx2_x4_shake256(EURYDICE_SLICE(input, 0, 128), EURYDICE_SLICE(input, 0, 128), EURYDICE_SLICE(input, 0, 128), EURYDICE_SLICE(input, 0, 128), out0, out1, out2, out3); + } +} + +BENCHMARK(sha3_256_1184); +BENCHMARK(sha3_512_64); +BENCHMARK(shake128_34_504); +BENCHMARK(shake256_1120_32); +BENCHMARK(shake256_33_128); +#endif + +BENCHMARK_MAIN(); diff --git a/libcrux-ml-kem/cg/code_gen.txt b/libcrux-ml-kem/cg/code_gen.txt new file mode 100644 index 000000000..fdcf0ec5e --- /dev/null +++ b/libcrux-ml-kem/cg/code_gen.txt @@ -0,0 +1,5 @@ +This code was generated with the following tools: +Charon: d799ceb29f648614b276f60d227794ee535473d2 +Eurydice: b38d5dd3b4099cce6bbb9d91c80fb2bf0aaff1f7 +Karamel: 409fe4552f8f46351241cba1decfaa4d9fa6ffea +F*: diff --git a/libcrux-ml-kem/cg/eurydice_glue.h b/libcrux-ml-kem/cg/eurydice_glue.h new file mode 100644 index 000000000..bad6ff16d --- /dev/null +++ b/libcrux-ml-kem/cg/eurydice_glue.h @@ -0,0 +1,157 @@ +#pragma once + +#if defined(__cplusplus) +extern "C" { +#endif + +#include +#include +#include +#include +#include + +#include "karamel/lowstar_endianness.h" +#include "karamel/target.h" + +// SLICES, ARRAYS, ETC. + +#if defined(__cplusplus) +#define CLITERAL(type) type +#else +#define CLITERAL(type) (type) +#endif + +// We represent a slice as a pair of an (untyped) pointer, along with the length +// of the slice, i.e. the number of elements in the slice (this is NOT the +// number of bytes). This design choice has two important consequences. +// - if you need to use `ptr`, you MUST cast it to a proper type *before* +// performing pointer +// arithmetic on it (remember that C desugars pointer arithmetic based on the +// type of the address) +// - if you need to use `len` for a C style function (e.g. memcpy, memcmp), you +// need to multiply it +// by sizeof t, where t is the type of the elements. +typedef struct { + void *ptr; + size_t len; +} Eurydice_slice; + +// Helper macro to create a slice out of a pointer x, a start index in x +// (included), and an end index in x (excluded). The argument x must be suitably +// cast to something that can decay (see remark above about how pointer +// arithmetic works in C), meaning either pointer or array type. +#define EURYDICE_SLICE(x, start, end) \ + (CLITERAL(Eurydice_slice){.ptr = (void *)(x + start), .len = end - start}) +#define EURYDICE_SLICE_LEN(s, _) s.len +// This macro is a pain because in case the dereferenced element type is an +// array, you cannot simply write `t x` as it would yield `int[4] x` instead, +// which is NOT correct C syntax, so we add a dedicated phase in Eurydice that +// adds an extra argument to this macro at the last minute so that we have the +// correct type of *pointers* to elements. +#define Eurydice_slice_index(s, i, t, t_ptr_t, _ret_t) (((t_ptr_t)s.ptr)[i]) +#define Eurydice_slice_subslice(s, r, t, _, _ret_t) \ + EURYDICE_SLICE((t *)s.ptr, r.start, r.end) +#define Eurydice_slice_subslice_to(s, subslice_end_pos, t, _, _ret_t) \ + EURYDICE_SLICE((t *)s.ptr, 0, subslice_end_pos) +#define Eurydice_slice_subslice_from(s, subslice_start_pos, t, _, _ret_t) \ + EURYDICE_SLICE((t *)s.ptr, subslice_start_pos, s.len) +#define Eurydice_array_to_slice(end, x, t, _ret_t) \ + EURYDICE_SLICE(x, 0, \ + end) /* x is already at an array type, no need for cast */ +#define Eurydice_array_to_subslice(_arraylen, x, r, t, _, _ret_t) \ + EURYDICE_SLICE((t *)x, r.start, r.end) +#define Eurydice_array_to_subslice_to(_size, x, r, t, _range_t, _ret_t) \ + EURYDICE_SLICE((t *)x, 0, r) +#define Eurydice_array_to_subslice_from(size, x, r, t, _range_t, _ret_t) \ + EURYDICE_SLICE((t *)x, r, size) +#define core_slice___Slice_T___len(s, t, _ret_t) EURYDICE_SLICE_LEN(s, t) +#define core_slice___Slice_T___copy_from_slice(dst, src, t, _ret_t) \ + memcpy(dst.ptr, src.ptr, dst.len * sizeof(t)) +#define core_array___Array_T__N__23__as_slice(len_, ptr_, t, _ret_t) \ + ((Eurydice_slice){.ptr = ptr_, .len = len_}) + +#define core_array___core__clone__Clone_for__Array_T__N___20__clone( \ + len, src, dst, elem_type, _ret_t) \ + (memcpy(dst, src, len * sizeof(elem_type))) +#define core_array_TryFromSliceError uint8_t + +#define Eurydice_array_eq(sz, a1, a2, t, _, _ret_t) \ + (memcmp(a1, a2, sz * sizeof(t)) == 0) +#define core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq \ + Eurydice_array_eq + +#define core_slice___Slice_T___split_at(slice, mid, element_type, ret_t) \ + (CLITERAL(ret_t){ \ + .fst = EURYDICE_SLICE((element_type *)slice.ptr, 0, mid), \ + .snd = EURYDICE_SLICE((element_type *)slice.ptr, mid, slice.len)}) +#define core_slice___Slice_T___split_at_mut(slice, mid, element_type, ret_t) \ + (CLITERAL(ret_t){ \ + .fst = {.ptr = slice.ptr, .len = mid}, \ + .snd = {.ptr = (char *)slice.ptr + mid * sizeof(element_type), \ + .len = slice.len - mid}}) + +// Conversion of slice to an array, rewritten (by Eurydice) to name the +// destination array, since arrays are not values in C. +// N.B.: see note in karamel/lib/Inlining.ml if you change this. +#define Eurydice_slice_to_array2(dst, src, _, t_arr, _ret_t) \ + Eurydice_slice_to_array3(&(dst)->tag, (char *)&(dst)->val.case_Ok, src, \ + sizeof(t_arr)) + +static inline void Eurydice_slice_to_array3(uint8_t *dst_tag, char *dst_ok, + Eurydice_slice src, size_t sz) { + *dst_tag = 0; + memcpy(dst_ok, src.ptr, sz); +} + +// CORE STUFF (conversions, endianness, ...) + +static inline void core_num__u64_9__to_le_bytes(uint64_t v, uint8_t buf[8]) { + store64_le(buf, v); +} +static inline uint64_t core_num__u64_9__from_le_bytes(uint8_t buf[8]) { + return load64_le(buf); +} + +static inline uint32_t core_num__u8_6__count_ones(uint8_t x0) { +#ifdef _MSC_VER + return __popcnt(x0); +#else + return __builtin_popcount(x0); +#endif +} + +// unsigned overflow wraparound semantics in C +static inline uint16_t core_num__u16_7__wrapping_add(uint16_t x, uint16_t y) { + return x + y; +} +static inline uint8_t core_num__u8_6__wrapping_sub(uint8_t x, uint8_t y) { + return x - y; +} + + +// static inline uint8_t Eurydice_bitand_pv_u8(uint8_t *p, uint8_t v) { +// return (*p) & v; +// } +// static inline uint8_t Eurydice_shr_pv_u8(uint8_t *p, int32_t v) { +// return (*p) >> v; +// } + +// ITERATORS + +#define Eurydice_range_iter_next(iter_ptr, t, ret_t) \ + (((iter_ptr)->start == (iter_ptr)->end) \ + ? (CLITERAL(ret_t){.tag = core_option_None}) \ + : (CLITERAL(ret_t){.tag = core_option_Some, \ + .f0 = (iter_ptr)->start++})) + +#define core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next \ + Eurydice_range_iter_next + +// See note in karamel/lib/Inlining.ml if you change this +#define Eurydice_into_iter(x, t, _ret_t) (x) +#define core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter \ + Eurydice_into_iter + +#if defined(__cplusplus) +} +#endif diff --git a/libcrux-ml-kem/cg/intrinsics/libcrux_intrinsics_avx2.h b/libcrux-ml-kem/cg/intrinsics/libcrux_intrinsics_avx2.h new file mode 100644 index 000000000..e504a6da3 --- /dev/null +++ b/libcrux-ml-kem/cg/intrinsics/libcrux_intrinsics_avx2.h @@ -0,0 +1,233 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: + /nix/store/c9m211bm84ncjmaxx27ki9dymd4qkwm2-ocaml4.14.1-eurydice-dirty/eurydice + --config ../c.yaml ../../libcrux_ml_kem.llbc F* version: KaRaMeL + version: + */ + +#ifndef __libcrux_intrinsics_avx2_H +#define __libcrux_intrinsics_avx2_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "../eurydice_glue.h" +#include "immintrin.h" + +typedef __m128i core_core_arch_x86___m128i; +typedef __m256i core_core_arch_x86___m256i; + +// Cast and Convert + +#define libcrux_intrinsics_avx2_mm256_castsi256_si128(a) \ + (_mm256_castsi256_si128(a)) + +#define libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(a) \ + (_mm256_cvtepi16_epi32(a)) + +#define libcrux_intrinsics_avx2_mm256_castsi128_si256(a) \ + (_mm256_castsi128_si256(a)) + +// Initialize, Load, Store + +#define libcrux_intrinsics_avx2_mm256_setzero_si256(void) \ + (_mm256_setzero_si256()) + +#define libcrux_intrinsics_avx2_mm256_set1_epi16(a) (_mm256_set1_epi16(a)) + +#define libcrux_intrinsics_avx2_mm256_set1_epi32(a) (_mm256_set1_epi32(a)) + +#define libcrux_intrinsics_avx2_mm256_set1_epi64x(a) (_mm256_set1_epi64x(a)) + +#define libcrux_intrinsics_avx2_mm_set1_epi16(a) (_mm_set1_epi16(a)) + +#define libcrux_intrinsics_avx2_mm256_set_epi16( \ + x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) \ + (_mm256_set_epi16(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, \ + x13, x14, x15)) + +#define libcrux_intrinsics_avx2_mm256_set_epi8( \ + x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, \ + x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31) \ + (_mm256_set_epi8(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, \ + x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, \ + x26, x27, x28, x29, x30, x31)) + +#define libcrux_intrinsics_avx2_mm_set_epi8( \ + x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) \ + (_mm_set_epi8(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, \ + x14, x15)) + +#define libcrux_intrinsics_avx2_mm256_set_epi32(x0, x1, x2, x3, x4, x5, x6, \ + x7) \ + (_mm256_set_epi32(x0, x1, x2, x3, x4, x5, x6, x7)) + +#define libcrux_intrinsics_avx2_mm256_loadu_si256_i16(a) \ + (_mm256_loadu_si256((const __m256i *)a.ptr)) + +#define libcrux_intrinsics_avx2_mm256_loadu_si256_u8(a) \ + (_mm256_loadu_si256((const __m256i *)a.ptr)) + +#define libcrux_intrinsics_avx2_mm_loadu_si128(a) \ + (_mm_loadu_si128((const __m128i *)a.ptr)) + +#define libcrux_intrinsics_avx2_mm_storeu_bytes_si128(a, b) \ + (_mm_storeu_si128((__m128i *)a.ptr, b)) + +#define libcrux_intrinsics_avx2_mm256_storeu_si256_i16(a, b) \ + (_mm256_storeu_si256((__m256i *)a.ptr, b)) + +#define libcrux_intrinsics_avx2_mm256_storeu_si256_u8(a, b) \ + (_mm256_storeu_si256((__m256i *)a.ptr, b)) + +#define libcrux_intrinsics_avx2_mm_storeu_si128(a, b) \ + (_mm_storeu_si128((__m128i *)a.ptr, b)) + +// Arithmetic: Add, Sub + +#define libcrux_intrinsics_avx2_mm256_add_epi16(a, b) (_mm256_add_epi16(a, b)) + +#define libcrux_intrinsics_avx2_mm256_add_epi32(a, b) (_mm256_add_epi32(a, b)) + +#define libcrux_intrinsics_avx2_mm_add_epi16(a, b) (_mm_add_epi16(a, b)) + +#define libcrux_intrinsics_avx2_mm256_sub_epi16(a, b) (_mm256_sub_epi16(a, b)) + +#define libcrux_intrinsics_avx2_mm_sub_epi16(a, b) (_mm_sub_epi16(a, b)) + +// Arithmetic: Mul low and high, Mul-Add combinations + +#define libcrux_intrinsics_avx2_mm256_mullo_epi16(a, b) \ + (_mm256_mullo_epi16(a, b)) + +#define libcrux_intrinsics_avx2_mm256_mulhi_epi16(a, b) \ + (_mm256_mulhi_epi16(a, b)) + +#define libcrux_intrinsics_avx2_mm256_mul_epu32(a, b) (_mm256_mul_epu32(a, b)) + +#define libcrux_intrinsics_avx2_mm256_mullo_epi32(a, b) \ + (_mm256_mullo_epi32(a, b)) + +#define libcrux_intrinsics_avx2_mm_mullo_epi16(a, b) (_mm_mullo_epi16(a, b)) + +#define libcrux_intrinsics_avx2_mm_mulhi_epi16(a, b) (_mm_mulhi_epi16(a, b)) + +#define libcrux_intrinsics_avx2_mm256_madd_epi16(a, b) (_mm256_madd_epi16(a, b)) + +// Comparison + +#define libcrux_intrinsics_avx2_mm256_cmpgt_epi16(a, b) \ + (_mm256_cmpgt_epi16(a, b)) + +// Bitwise operations + +#define libcrux_intrinsics_avx2_mm256_and_si256(a, b) (_mm256_and_si256(a, b)) + +#define libcrux_intrinsics_avx2_mm256_andnot_si256(a, b) \ + (_mm256_andnot_si256(a, b)) + + +#define libcrux_intrinsics_avx2_mm256_xor_si256(a, b) (_mm256_xor_si256(a, b)) + + +#define libcrux_intrinsics_avx2_mm_movemask_epi8(a) (_mm_movemask_epi8(a)) + + +// Shift operations +#define libcrux_intrinsics_avx2_mm256_srai_epi16(a, b, _) \ + (_mm256_srai_epi16(b, a)) + +#define libcrux_intrinsics_avx2_mm256_srli_epi16(a, b, _) \ + (_mm256_srli_epi16(b, a)) + +#define libcrux_intrinsics_avx2_mm256_slli_epi16(a, b, _) \ + (_mm256_slli_epi16(b, a)) + +#define libcrux_intrinsics_avx2_mm256_slli_epi32(a, b, _) \ + (_mm256_slli_epi32(b, a)) + +#define libcrux_intrinsics_avx2_mm256_slli_epi64_(a, b) \ + (_mm256_slli_epi64(b, a)) + + +#define libcrux_intrinsics_avx2_mm256_slli_epi64(a, b, c) \ + (libcrux_intrinsics_avx2_mm256_slli_epi64_(a, b)) + +#define libcrux_intrinsics_avx2_mm256_srai_epi32(a, b, _) \ + (_mm256_srai_epi32(b, a)) + +#define libcrux_intrinsics_avx2_mm256_srli_epi32(a, b, _) \ + (_mm256_srli_epi32(b, a)) + +#define libcrux_intrinsics_avx2_mm256_sllv_epi32(a, b) (_mm256_sllv_epi32(a, b)) + + +#define libcrux_intrinsics_avx2_mm256_srli_epi64_(a, b) \ + (_mm256_srli_epi64(b, a)) + + +#define libcrux_intrinsics_avx2_mm256_srli_epi64(a, b, c) \ + (libcrux_intrinsics_avx2_mm256_srli_epi64_(a, b)) + +// Shuffle and Vector Interleaving + +#define libcrux_intrinsics_avx2_mm256_unpacklo_epi32(a, b) \ + (_mm256_unpacklo_epi32(a, b)) + + +#define libcrux_intrinsics_avx2_mm256_unpacklo_epi64(a, b) \ + (_mm256_unpacklo_epi64(a, b)) + + +#define libcrux_intrinsics_avx2_mm256_unpackhi_epi32(a, b) \ + (_mm256_unpackhi_epi32(a, b)) + + +#define libcrux_intrinsics_avx2_mm256_unpackhi_epi64(a, b) \ + (_mm256_unpackhi_epi64(a, b)) + + +#define libcrux_intrinsics_avx2_mm256_packs_epi32(a, b) \ + (_mm256_packs_epi32(a, b)) + + +#define libcrux_intrinsics_avx2_mm_packs_epi16(a, b) (_mm_packs_epi16(a, b)) + + +#define libcrux_intrinsics_avx2_mm256_shuffle_epi32(a, b, _) \ + (_mm256_shuffle_epi32(b, a)) + +#define libcrux_intrinsics_avx2_mm256_extracti128_si256(a, b, _) \ + (_mm256_extracti128_si256(b, a)) + +#define libcrux_intrinsics_avx2_mm256_permute4x64_epi64(a, b, _) \ + (_mm256_permute4x64_epi64(b, a)) + +#define libcrux_intrinsics_avx2_mm256_permute2x128_si256(a, b, c, d) \ + (_mm256_permute2x128_si256(b, c, a)) + +#define libcrux_intrinsics_avx2_mm256_inserti128_si256(a, b, c, _) \ + (_mm256_inserti128_si256(b, c, a)) + +#define libcrux_intrinsics_avx2_mm256_blend_epi16(a, b, c, _) \ + (_mm256_blend_epi16(b, c, a)) + +#define libcrux_intrinsics_avx2_mm256_shuffle_epi8(a, b) \ + (_mm256_shuffle_epi8(a, b)) + + +#define libcrux_intrinsics_avx2_mm256_permutevar8x32_epi32(a, b) \ + (_mm256_permutevar8x32_epi32(a, b)) + + +#define libcrux_intrinsics_avx2_mm_shuffle_epi8(a, b) (_mm_shuffle_epi8(a, b)) + + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_intrinsics_avx2_H_DEFINED +#endif diff --git a/libcrux-ml-kem/cg/karamel/lowstar_endianness.h b/libcrux-ml-kem/cg/karamel/lowstar_endianness.h new file mode 100644 index 000000000..1aa2ccd64 --- /dev/null +++ b/libcrux-ml-kem/cg/karamel/lowstar_endianness.h @@ -0,0 +1,231 @@ +/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved. + Licensed under the Apache 2.0 License. */ + +#ifndef __LOWSTAR_ENDIANNESS_H +#define __LOWSTAR_ENDIANNESS_H + +#include +#include + +/******************************************************************************/ +/* Implementing C.fst (part 2: endian-ness macros) */ +/******************************************************************************/ + +/* ... for Linux */ +#if defined(__linux__) || defined(__CYGWIN__) || defined (__USE_SYSTEM_ENDIAN_H__) || defined(__GLIBC__) +# include + +/* ... for OSX */ +#elif defined(__APPLE__) +# include +# define htole64(x) OSSwapHostToLittleInt64(x) +# define le64toh(x) OSSwapLittleToHostInt64(x) +# define htobe64(x) OSSwapHostToBigInt64(x) +# define be64toh(x) OSSwapBigToHostInt64(x) + +# define htole16(x) OSSwapHostToLittleInt16(x) +# define le16toh(x) OSSwapLittleToHostInt16(x) +# define htobe16(x) OSSwapHostToBigInt16(x) +# define be16toh(x) OSSwapBigToHostInt16(x) + +# define htole32(x) OSSwapHostToLittleInt32(x) +# define le32toh(x) OSSwapLittleToHostInt32(x) +# define htobe32(x) OSSwapHostToBigInt32(x) +# define be32toh(x) OSSwapBigToHostInt32(x) + +/* ... for Solaris */ +#elif defined(__sun__) +# include +# define htole64(x) LE_64(x) +# define le64toh(x) LE_64(x) +# define htobe64(x) BE_64(x) +# define be64toh(x) BE_64(x) + +# define htole16(x) LE_16(x) +# define le16toh(x) LE_16(x) +# define htobe16(x) BE_16(x) +# define be16toh(x) BE_16(x) + +# define htole32(x) LE_32(x) +# define le32toh(x) LE_32(x) +# define htobe32(x) BE_32(x) +# define be32toh(x) BE_32(x) + +/* ... for the BSDs */ +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) +# include +#elif defined(__OpenBSD__) +# include + +/* ... for Windows (MSVC)... not targeting XBOX 360! */ +#elif defined(_MSC_VER) + +# include +# define htobe16(x) _byteswap_ushort(x) +# define htole16(x) (x) +# define be16toh(x) _byteswap_ushort(x) +# define le16toh(x) (x) + +# define htobe32(x) _byteswap_ulong(x) +# define htole32(x) (x) +# define be32toh(x) _byteswap_ulong(x) +# define le32toh(x) (x) + +# define htobe64(x) _byteswap_uint64(x) +# define htole64(x) (x) +# define be64toh(x) _byteswap_uint64(x) +# define le64toh(x) (x) + +/* ... for Windows (GCC-like, e.g. mingw or clang) */ +#elif (defined(_WIN32) || defined(_WIN64) || defined(__EMSCRIPTEN__)) && \ + (defined(__GNUC__) || defined(__clang__)) + +# define htobe16(x) __builtin_bswap16(x) +# define htole16(x) (x) +# define be16toh(x) __builtin_bswap16(x) +# define le16toh(x) (x) + +# define htobe32(x) __builtin_bswap32(x) +# define htole32(x) (x) +# define be32toh(x) __builtin_bswap32(x) +# define le32toh(x) (x) + +# define htobe64(x) __builtin_bswap64(x) +# define htole64(x) (x) +# define be64toh(x) __builtin_bswap64(x) +# define le64toh(x) (x) + +/* ... generic big-endian fallback code */ +/* ... AIX doesn't have __BYTE_ORDER__ (with XLC compiler) & is always big-endian */ +#elif (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || defined(_AIX) + +/* byte swapping code inspired by: + * https://github.com/rweather/arduinolibs/blob/master/libraries/Crypto/utility/EndianUtil.h + * */ + +# define htobe32(x) (x) +# define be32toh(x) (x) +# define htole32(x) \ + (__extension__({ \ + uint32_t _temp = (x); \ + ((_temp >> 24) & 0x000000FF) | ((_temp >> 8) & 0x0000FF00) | \ + ((_temp << 8) & 0x00FF0000) | ((_temp << 24) & 0xFF000000); \ + })) +# define le32toh(x) (htole32((x))) + +# define htobe64(x) (x) +# define be64toh(x) (x) +# define htole64(x) \ + (__extension__({ \ + uint64_t __temp = (x); \ + uint32_t __low = htobe32((uint32_t)__temp); \ + uint32_t __high = htobe32((uint32_t)(__temp >> 32)); \ + (((uint64_t)__low) << 32) | __high; \ + })) +# define le64toh(x) (htole64((x))) + +/* ... generic little-endian fallback code */ +#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + +# define htole32(x) (x) +# define le32toh(x) (x) +# define htobe32(x) \ + (__extension__({ \ + uint32_t _temp = (x); \ + ((_temp >> 24) & 0x000000FF) | ((_temp >> 8) & 0x0000FF00) | \ + ((_temp << 8) & 0x00FF0000) | ((_temp << 24) & 0xFF000000); \ + })) +# define be32toh(x) (htobe32((x))) + +# define htole64(x) (x) +# define le64toh(x) (x) +# define htobe64(x) \ + (__extension__({ \ + uint64_t __temp = (x); \ + uint32_t __low = htobe32((uint32_t)__temp); \ + uint32_t __high = htobe32((uint32_t)(__temp >> 32)); \ + (((uint64_t)__low) << 32) | __high; \ + })) +# define be64toh(x) (htobe64((x))) + +/* ... couldn't determine endian-ness of the target platform */ +#else +# error "Please define __BYTE_ORDER__!" + +#endif /* defined(__linux__) || ... */ + +/* Loads and stores. These avoid undefined behavior due to unaligned memory + * accesses, via memcpy. */ + +inline static uint16_t load16(uint8_t *b) { + uint16_t x; + memcpy(&x, b, 2); + return x; +} + +inline static uint32_t load32(uint8_t *b) { + uint32_t x; + memcpy(&x, b, 4); + return x; +} + +inline static uint64_t load64(uint8_t *b) { + uint64_t x; + memcpy(&x, b, 8); + return x; +} + +inline static void store16(uint8_t *b, uint16_t i) { + memcpy(b, &i, 2); +} + +inline static void store32(uint8_t *b, uint32_t i) { + memcpy(b, &i, 4); +} + +inline static void store64(uint8_t *b, uint64_t i) { + memcpy(b, &i, 8); +} + +/* Legacy accessors so that this header can serve as an implementation of + * C.Endianness */ +#define load16_le(b) (le16toh(load16(b))) +#define store16_le(b, i) (store16(b, htole16(i))) +#define load16_be(b) (be16toh(load16(b))) +#define store16_be(b, i) (store16(b, htobe16(i))) + +#define load32_le(b) (le32toh(load32(b))) +#define store32_le(b, i) (store32(b, htole32(i))) +#define load32_be(b) (be32toh(load32(b))) +#define store32_be(b, i) (store32(b, htobe32(i))) + +#define load64_le(b) (le64toh(load64(b))) +#define store64_le(b, i) (store64(b, htole64(i))) +#define load64_be(b) (be64toh(load64(b))) +#define store64_be(b, i) (store64(b, htobe64(i))) + +/* Co-existence of LowStar.Endianness and FStar.Endianness generates name + * conflicts, because of course both insist on having no prefixes. Until a + * prefix is added, or until we truly retire FStar.Endianness, solve this issue + * in an elegant way. */ +#define load16_le0 load16_le +#define store16_le0 store16_le +#define load16_be0 load16_be +#define store16_be0 store16_be + +#define load32_le0 load32_le +#define store32_le0 store32_le +#define load32_be0 load32_be +#define store32_be0 store32_be + +#define load64_le0 load64_le +#define store64_le0 store64_le +#define load64_be0 load64_be +#define store64_be0 store64_be + +#define load128_le0 load128_le +#define store128_le0 store128_le +#define load128_be0 load128_be +#define store128_be0 store128_be + +#endif diff --git a/libcrux-ml-kem/cg/karamel/target.h b/libcrux-ml-kem/cg/karamel/target.h new file mode 100644 index 000000000..d53314766 --- /dev/null +++ b/libcrux-ml-kem/cg/karamel/target.h @@ -0,0 +1,385 @@ +/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved. + Licensed under the Apache 2.0 License. */ + +#ifndef __KRML_TARGET_H +#define __KRML_TARGET_H + +#include +#include +#include +#include +#include +#include +#include + +/* Since KaRaMeL emits the inline keyword unconditionally, we follow the + * guidelines at https://gcc.gnu.org/onlinedocs/gcc/Inline.html and make this + * __inline__ to ensure the code compiles with -std=c90 and earlier. */ +#ifdef __GNUC__ +# define inline __inline__ +#endif + +/******************************************************************************/ +/* Macros that KaRaMeL will generate. */ +/******************************************************************************/ + +/* For "bare" targets that do not have a C stdlib, the user might want to use + * [-add-early-include '"mydefinitions.h"'] and override these. */ +#ifndef KRML_HOST_PRINTF +# define KRML_HOST_PRINTF printf +#endif + +#if \ + ((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \ + (defined(__cplusplus) && __cplusplus > 199711L)) && \ + (!defined(KRML_HOST_EPRINTF)) +# define KRML_HOST_EPRINTF(...) fprintf(stderr, __VA_ARGS__) +#elif !(defined KRML_HOST_EPRINTF) && defined(_MSC_VER) +# define KRML_HOST_EPRINTF(...) fprintf(stderr, __VA_ARGS__) +#endif + +#ifndef KRML_HOST_EXIT +# define KRML_HOST_EXIT exit +#endif + +#ifndef KRML_HOST_MALLOC +# define KRML_HOST_MALLOC malloc +#endif + +#ifndef KRML_HOST_CALLOC +# define KRML_HOST_CALLOC calloc +#endif + +#ifndef KRML_HOST_FREE +# define KRML_HOST_FREE free +#endif + +#ifndef KRML_HOST_IGNORE +# define KRML_HOST_IGNORE(x) (void)(x) +#endif + +#ifndef KRML_MAYBE_UNUSED_VAR +# define KRML_MAYBE_UNUSED_VAR(x) KRML_HOST_IGNORE(x) +#endif + +#ifndef KRML_MAYBE_UNUSED +# if defined(__GNUC__) +# define KRML_MAYBE_UNUSED __attribute__((unused)) +# else +# define KRML_MAYBE_UNUSED +# endif +#endif + +#ifndef KRML_NOINLINE +# if defined(_MSC_VER) +# define KRML_NOINLINE __declspec(noinline) +# elif defined (__GNUC__) +# define KRML_NOINLINE __attribute__((noinline,unused)) +# else +# define KRML_NOINLINE +# warning "The KRML_NOINLINE macro is not defined for this toolchain!" +# warning "The compiler may defeat side-channel resistance with optimizations." +# warning "Please locate target.h and try to fill it out with a suitable definition for this compiler." +# endif +#endif + +#ifndef KRML_PRE_ALIGN +# ifdef _MSC_VER +# define KRML_PRE_ALIGN(X) __declspec(align(X)) +# else +# define KRML_PRE_ALIGN(X) +# endif +#endif + +#ifndef KRML_POST_ALIGN +# ifdef _MSC_VER +# define KRML_POST_ALIGN(X) +# else +# define KRML_POST_ALIGN(X) __attribute__((aligned(X))) +# endif +#endif + +/* MinGW-W64 does not support C11 aligned_alloc, but it supports + * MSVC's _aligned_malloc. + */ +#ifndef KRML_ALIGNED_MALLOC +# ifdef __MINGW32__ +# include <_mingw.h> +# endif +# if ( \ + defined(_MSC_VER) || \ + (defined(__MINGW32__) && defined(__MINGW64_VERSION_MAJOR))) +# define KRML_ALIGNED_MALLOC(X, Y) _aligned_malloc(Y, X) +# else +# define KRML_ALIGNED_MALLOC(X, Y) aligned_alloc(X, Y) +# endif +#endif + +/* Since aligned allocations with MinGW-W64 are done with + * _aligned_malloc (see above), such pointers must be freed with + * _aligned_free. + */ +#ifndef KRML_ALIGNED_FREE +# ifdef __MINGW32__ +# include <_mingw.h> +# endif +# if ( \ + defined(_MSC_VER) || \ + (defined(__MINGW32__) && defined(__MINGW64_VERSION_MAJOR))) +# define KRML_ALIGNED_FREE(X) _aligned_free(X) +# else +# define KRML_ALIGNED_FREE(X) free(X) +# endif +#endif + +#ifndef KRML_HOST_TIME + +# include + +/* Prims_nat not yet in scope */ +inline static int32_t krml_time(void) { + return (int32_t)time(NULL); +} + +# define KRML_HOST_TIME krml_time +#endif + +/* In statement position, exiting is easy. */ +#define KRML_EXIT \ + do { \ + KRML_HOST_PRINTF("Unimplemented function at %s:%d\n", __FILE__, __LINE__); \ + KRML_HOST_EXIT(254); \ + } while (0) + +/* In expression position, use the comma-operator and a malloc to return an + * expression of the right size. KaRaMeL passes t as the parameter to the macro. + */ +#define KRML_EABORT(t, msg) \ + (KRML_HOST_PRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, msg), \ + KRML_HOST_EXIT(255), *((t *)KRML_HOST_MALLOC(sizeof(t)))) + +/* In FStar.Buffer.fst, the size of arrays is uint32_t, but it's a number of + * *elements*. Do an ugly, run-time check (some of which KaRaMeL can eliminate). + */ +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 4)) +# define _KRML_CHECK_SIZE_PRAGMA \ + _Pragma("GCC diagnostic ignored \"-Wtype-limits\"") +#else +# define _KRML_CHECK_SIZE_PRAGMA +#endif + +#define KRML_CHECK_SIZE(size_elt, sz) \ + do { \ + _KRML_CHECK_SIZE_PRAGMA \ + if (((size_t)(sz)) > ((size_t)(SIZE_MAX / (size_elt)))) { \ + KRML_HOST_PRINTF( \ + "Maximum allocatable size exceeded, aborting before overflow at " \ + "%s:%d\n", \ + __FILE__, __LINE__); \ + KRML_HOST_EXIT(253); \ + } \ + } while (0) + +#if defined(_MSC_VER) && _MSC_VER < 1900 +# define KRML_HOST_SNPRINTF(buf, sz, fmt, arg) \ + _snprintf_s(buf, sz, _TRUNCATE, fmt, arg) +#else +# define KRML_HOST_SNPRINTF(buf, sz, fmt, arg) snprintf(buf, sz, fmt, arg) +#endif + +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 4)) +# define KRML_DEPRECATED(x) __attribute__((deprecated(x))) +#elif defined(__GNUC__) +/* deprecated attribute is not defined in GCC < 4.5. */ +# define KRML_DEPRECATED(x) +#elif defined(_MSC_VER) +# define KRML_DEPRECATED(x) __declspec(deprecated(x)) +#endif + +/* Macros for prettier unrolling of loops */ +#define KRML_LOOP1(i, n, x) { \ + x \ + i += n; \ + (void) i; \ +} + +#define KRML_LOOP2(i, n, x) \ + KRML_LOOP1(i, n, x) \ + KRML_LOOP1(i, n, x) + +#define KRML_LOOP3(i, n, x) \ + KRML_LOOP2(i, n, x) \ + KRML_LOOP1(i, n, x) + +#define KRML_LOOP4(i, n, x) \ + KRML_LOOP2(i, n, x) \ + KRML_LOOP2(i, n, x) + +#define KRML_LOOP5(i, n, x) \ + KRML_LOOP4(i, n, x) \ + KRML_LOOP1(i, n, x) + +#define KRML_LOOP6(i, n, x) \ + KRML_LOOP4(i, n, x) \ + KRML_LOOP2(i, n, x) + +#define KRML_LOOP7(i, n, x) \ + KRML_LOOP4(i, n, x) \ + KRML_LOOP3(i, n, x) + +#define KRML_LOOP8(i, n, x) \ + KRML_LOOP4(i, n, x) \ + KRML_LOOP4(i, n, x) + +#define KRML_LOOP9(i, n, x) \ + KRML_LOOP8(i, n, x) \ + KRML_LOOP1(i, n, x) + +#define KRML_LOOP10(i, n, x) \ + KRML_LOOP8(i, n, x) \ + KRML_LOOP2(i, n, x) + +#define KRML_LOOP11(i, n, x) \ + KRML_LOOP8(i, n, x) \ + KRML_LOOP3(i, n, x) + +#define KRML_LOOP12(i, n, x) \ + KRML_LOOP8(i, n, x) \ + KRML_LOOP4(i, n, x) + +#define KRML_LOOP13(i, n, x) \ + KRML_LOOP8(i, n, x) \ + KRML_LOOP5(i, n, x) + +#define KRML_LOOP14(i, n, x) \ + KRML_LOOP8(i, n, x) \ + KRML_LOOP6(i, n, x) + +#define KRML_LOOP15(i, n, x) \ + KRML_LOOP8(i, n, x) \ + KRML_LOOP7(i, n, x) + +#define KRML_LOOP16(i, n, x) \ + KRML_LOOP8(i, n, x) \ + KRML_LOOP8(i, n, x) + +#define KRML_UNROLL_FOR(i, z, n, k, x) \ + do { \ + uint32_t i = z; \ + KRML_LOOP##n(i, k, x) \ + } while (0) + +#define KRML_ACTUAL_FOR(i, z, n, k, x) \ + do { \ + for (uint32_t i = z; i < n; i += k) { \ + x \ + } \ + } while (0) + +#ifndef KRML_UNROLL_MAX +# define KRML_UNROLL_MAX 16 +#endif + +/* 1 is the number of loop iterations, i.e. (n - z)/k as evaluated by krml */ +#if 0 <= KRML_UNROLL_MAX +# define KRML_MAYBE_FOR0(i, z, n, k, x) +#else +# define KRML_MAYBE_FOR0(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 1 <= KRML_UNROLL_MAX +# define KRML_MAYBE_FOR1(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 1, k, x) +#else +# define KRML_MAYBE_FOR1(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 2 <= KRML_UNROLL_MAX +# define KRML_MAYBE_FOR2(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 2, k, x) +#else +# define KRML_MAYBE_FOR2(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 3 <= KRML_UNROLL_MAX +# define KRML_MAYBE_FOR3(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 3, k, x) +#else +# define KRML_MAYBE_FOR3(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 4 <= KRML_UNROLL_MAX +# define KRML_MAYBE_FOR4(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 4, k, x) +#else +# define KRML_MAYBE_FOR4(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 5 <= KRML_UNROLL_MAX +# define KRML_MAYBE_FOR5(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 5, k, x) +#else +# define KRML_MAYBE_FOR5(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 6 <= KRML_UNROLL_MAX +# define KRML_MAYBE_FOR6(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 6, k, x) +#else +# define KRML_MAYBE_FOR6(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 7 <= KRML_UNROLL_MAX +# define KRML_MAYBE_FOR7(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 7, k, x) +#else +# define KRML_MAYBE_FOR7(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 8 <= KRML_UNROLL_MAX +# define KRML_MAYBE_FOR8(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 8, k, x) +#else +# define KRML_MAYBE_FOR8(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 9 <= KRML_UNROLL_MAX +# define KRML_MAYBE_FOR9(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 9, k, x) +#else +# define KRML_MAYBE_FOR9(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 10 <= KRML_UNROLL_MAX +# define KRML_MAYBE_FOR10(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 10, k, x) +#else +# define KRML_MAYBE_FOR10(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 11 <= KRML_UNROLL_MAX +# define KRML_MAYBE_FOR11(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 11, k, x) +#else +# define KRML_MAYBE_FOR11(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 12 <= KRML_UNROLL_MAX +# define KRML_MAYBE_FOR12(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 12, k, x) +#else +# define KRML_MAYBE_FOR12(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 13 <= KRML_UNROLL_MAX +# define KRML_MAYBE_FOR13(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 13, k, x) +#else +# define KRML_MAYBE_FOR13(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 14 <= KRML_UNROLL_MAX +# define KRML_MAYBE_FOR14(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 14, k, x) +#else +# define KRML_MAYBE_FOR14(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 15 <= KRML_UNROLL_MAX +# define KRML_MAYBE_FOR15(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 15, k, x) +#else +# define KRML_MAYBE_FOR15(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 16 <= KRML_UNROLL_MAX +# define KRML_MAYBE_FOR16(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 16, k, x) +#else +# define KRML_MAYBE_FOR16(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif +#endif diff --git a/libcrux-ml-kem/cg/libcrux_core.h b/libcrux-ml-kem/cg/libcrux_core.h new file mode 100644 index 000000000..3722fd4b3 --- /dev/null +++ b/libcrux-ml-kem/cg/libcrux_core.h @@ -0,0 +1,404 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../cg.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 409fe455 + */ + +#ifndef __libcrux_core_H +#define __libcrux_core_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "eurydice_glue.h" + +typedef struct core_ops_range_Range__size_t_s { + size_t start; + size_t end; +} core_ops_range_Range__size_t; + +static inline uint8_t Eurydice_bitand_pv_u8(uint8_t *x, uint8_t y); + +static inline uint8_t Eurydice_shr_pv_u8(uint8_t *x, int32_t y); + +#define core_option_None 0 +#define core_option_Some 1 + +typedef uint8_t core_option_Option__size_t_tags; + +typedef struct core_option_Option__size_t_s { + core_option_Option__size_t_tags tag; + size_t f0; +} core_option_Option__size_t; + +static inline uint16_t core_num__u16_7__wrapping_add(uint16_t x0, uint16_t x1); + +#define CORE_NUM__U32_8__BITS (32U) + +static inline uint64_t core_num__u64_9__from_le_bytes(uint8_t x0[8U]); + +static inline void core_num__u64_9__to_le_bytes(uint64_t x0, uint8_t x1[8U]); + +static inline uint32_t core_num__u8_6__count_ones(uint8_t x0); + +static inline uint8_t core_num__u8_6__wrapping_sub(uint8_t x0, uint8_t x1); + +static inline uint8_t libcrux_ml_kem_constant_time_ops_is_non_zero( + uint8_t value) { + uint16_t value0 = (uint16_t)value; + uint16_t uu____0 = value0; + uint16_t result = (((uint32_t)uu____0 | + (uint32_t)core_num__u16_7__wrapping_add(~value0, 1U)) & + 0xFFFFU) >> + 8U & + 1U; + return (uint8_t)result; +} + +#define LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE ((size_t)32U) + +static inline void +libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( + Eurydice_slice lhs, Eurydice_slice rhs, uint8_t selector, + uint8_t ret[32U]) { + uint8_t mask = core_num__u8_6__wrapping_sub( + libcrux_ml_kem_constant_time_ops_is_non_zero(selector), 1U); + uint8_t out[32U] = {0U}; + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE; + i++) { + size_t i0 = i; + uint8_t uu____0 = + (uint32_t)Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *, uint8_t) & + (uint32_t)mask; + uint8_t *uu____1 = + &Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *, uint8_t); + out[i0] = (uint32_t)uu____0 | ((uint32_t)uu____1[0U] & (uint32_t)~mask); + } + memcpy(ret, out, (size_t)32U * sizeof(uint8_t)); +} + +#define LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT ((size_t)12U) + +#define LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT ((size_t)256U) + +#define LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT \ + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)12U) + +#define LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT \ + (LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT / (size_t)8U) + +#define LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE ((size_t)32U) + +#define LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE ((size_t)32U) + +typedef struct libcrux_ml_kem_utils_extraction_helper_Keypair768_s { + uint8_t fst[1152U]; + uint8_t snd[1184U]; +} libcrux_ml_kem_utils_extraction_helper_Keypair768; + +#define core_result_Ok 0 +#define core_result_Err 1 + +typedef uint8_t + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags; + +typedef struct + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_s { + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags tag; + union { + uint8_t case_Ok[24U]; + core_array_TryFromSliceError case_Err; + } val; +} core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError; + +static inline void +core_result__core__result__Result_T__E___unwrap__uint8_t_24size_t__core_array_TryFromSliceError( + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError self, + uint8_t ret[24U]) { + if (self.tag == core_result_Ok) { + uint8_t f0[24U]; + memcpy(f0, self.val.case_Ok, (size_t)24U * sizeof(uint8_t)); + memcpy(ret, f0, (size_t)24U * sizeof(uint8_t)); + } else { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "unwrap not Ok"); + KRML_HOST_EXIT(255U); + } +} + +typedef struct + core_result_Result__uint8_t_20size_t__core_array_TryFromSliceError_s { + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags tag; + union { + uint8_t case_Ok[20U]; + core_array_TryFromSliceError case_Err; + } val; +} core_result_Result__uint8_t_20size_t__core_array_TryFromSliceError; + +static inline void +core_result__core__result__Result_T__E___unwrap__uint8_t_20size_t__core_array_TryFromSliceError( + core_result_Result__uint8_t_20size_t__core_array_TryFromSliceError self, + uint8_t ret[20U]) { + if (self.tag == core_result_Ok) { + uint8_t f0[20U]; + memcpy(f0, self.val.case_Ok, (size_t)20U * sizeof(uint8_t)); + memcpy(ret, f0, (size_t)20U * sizeof(uint8_t)); + } else { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "unwrap not Ok"); + KRML_HOST_EXIT(255U); + } +} + +typedef struct + core_result_Result__uint8_t_10size_t__core_array_TryFromSliceError_s { + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags tag; + union { + uint8_t case_Ok[10U]; + core_array_TryFromSliceError case_Err; + } val; +} core_result_Result__uint8_t_10size_t__core_array_TryFromSliceError; + +static inline void +core_result__core__result__Result_T__E___unwrap__uint8_t_10size_t__core_array_TryFromSliceError( + core_result_Result__uint8_t_10size_t__core_array_TryFromSliceError self, + uint8_t ret[10U]) { + if (self.tag == core_result_Ok) { + uint8_t f0[10U]; + memcpy(f0, self.val.case_Ok, (size_t)10U * sizeof(uint8_t)); + memcpy(ret, f0, (size_t)10U * sizeof(uint8_t)); + } else { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "unwrap not Ok"); + KRML_HOST_EXIT(255U); + } +} + +typedef struct + K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t__s { + Eurydice_slice fst[4U]; + Eurydice_slice snd[4U]; +} K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_; + +typedef struct libcrux_ml_kem_types_MlKemPublicKey____1184size_t_s { + uint8_t value[1184U]; +} libcrux_ml_kem_types_MlKemPublicKey____1184size_t; + +typedef struct + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t___s { + core_option_Option__size_t_tags tag; + libcrux_ml_kem_types_MlKemPublicKey____1184size_t f0; +} core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__; + +static inline libcrux_ml_kem_types_MlKemPublicKey____1184size_t +libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t( + uint8_t value[1184U]) { + uint8_t uu____0[1184U]; + memcpy(uu____0, value, (size_t)1184U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPublicKey____1184size_t lit; + memcpy(lit.value, uu____0, (size_t)1184U * sizeof(uint8_t)); + return lit; +} + +typedef struct libcrux_ml_kem_types_MlKemPrivateKey____2400size_t_s { + uint8_t value[2400U]; +} libcrux_ml_kem_types_MlKemPrivateKey____2400size_t; + +typedef struct libcrux_ml_kem_mlkem768_MlKem768KeyPair_s { + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t sk; + libcrux_ml_kem_types_MlKemPublicKey____1184size_t pk; +} libcrux_ml_kem_mlkem768_MlKem768KeyPair; + +static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t sk, + libcrux_ml_kem_types_MlKemPublicKey____1184size_t pk) { + return ( + CLITERAL(libcrux_ml_kem_mlkem768_MlKem768KeyPair){.sk = sk, .pk = pk}); +} + +static inline libcrux_ml_kem_types_MlKemPrivateKey____2400size_t +libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t( + uint8_t value[2400U]) { + uint8_t uu____0[2400U]; + memcpy(uu____0, value, (size_t)2400U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t lit; + memcpy(lit.value, uu____0, (size_t)2400U * sizeof(uint8_t)); + return lit; +} + +typedef struct libcrux_ml_kem_mlkem768_MlKem768Ciphertext_s { + uint8_t value[1088U]; +} libcrux_ml_kem_mlkem768_MlKem768Ciphertext; + +typedef struct + K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t__s { + libcrux_ml_kem_mlkem768_MlKem768Ciphertext fst; + uint8_t snd[32U]; +} K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_; + +static inline libcrux_ml_kem_mlkem768_MlKem768Ciphertext +libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( + uint8_t value[1088U]) { + uint8_t uu____0[1088U]; + memcpy(uu____0, value, (size_t)1088U * sizeof(uint8_t)); + libcrux_ml_kem_mlkem768_MlKem768Ciphertext lit; + memcpy(lit.value, uu____0, (size_t)1088U * sizeof(uint8_t)); + return lit; +} + +static inline uint8_t * +libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *self) { + return self->value; +} + +static inline uint8_t +libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t( + Eurydice_slice lhs, Eurydice_slice rhs) { + uint8_t r = 0U; + for (size_t i = (size_t)0U; i < (size_t)1088U; i++) { + size_t i0 = i; + uint8_t uu____0 = + Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *, uint8_t); + r = (uint32_t)r | + ((uint32_t)uu____0 ^ + (uint32_t)Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *, uint8_t)); + } + return libcrux_ml_kem_constant_time_ops_is_non_zero(r); +} + +static inline void libcrux_ml_kem_utils_into_padded_array___33size_t( + Eurydice_slice slice, uint8_t ret[33U]) { + uint8_t out[33U] = {0U}; + uint8_t *uu____0 = out; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)33U, uu____0, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = core_slice___Slice_T___len(slice, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + slice, uint8_t, void *); + memcpy(ret, out, (size_t)33U * sizeof(uint8_t)); +} + +static inline void libcrux_ml_kem_utils_into_padded_array___34size_t( + Eurydice_slice slice, uint8_t ret[34U]) { + uint8_t out[34U] = {0U}; + uint8_t *uu____0 = out; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)34U, uu____0, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = core_slice___Slice_T___len(slice, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + slice, uint8_t, void *); + memcpy(ret, out, (size_t)34U * sizeof(uint8_t)); +} + +static inline Eurydice_slice +libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *self) { + return Eurydice_array_to_slice((size_t)1088U, self->value, uint8_t, + Eurydice_slice); +} + +static inline void libcrux_ml_kem_utils_into_padded_array___1120size_t( + Eurydice_slice slice, uint8_t ret[1120U]) { + uint8_t out[1120U] = {0U}; + uint8_t *uu____0 = out; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)1120U, uu____0, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = core_slice___Slice_T___len(slice, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + slice, uint8_t, void *); + memcpy(ret, out, (size_t)1120U * sizeof(uint8_t)); +} + +static inline void libcrux_ml_kem_utils_into_padded_array___64size_t( + Eurydice_slice slice, uint8_t ret[64U]) { + uint8_t out[64U] = {0U}; + uint8_t *uu____0 = out; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)64U, uu____0, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = core_slice___Slice_T___len(slice, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + slice, uint8_t, void *); + memcpy(ret, out, (size_t)64U * sizeof(uint8_t)); +} + +typedef struct + core_result_Result__int16_t_16size_t__core_array_TryFromSliceError_s { + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags tag; + union { + int16_t case_Ok[16U]; + core_array_TryFromSliceError case_Err; + } val; +} core_result_Result__int16_t_16size_t__core_array_TryFromSliceError; + +static inline void +core_result__core__result__Result_T__E___unwrap__int16_t_16size_t__core_array_TryFromSliceError( + core_result_Result__int16_t_16size_t__core_array_TryFromSliceError self, + int16_t ret[16U]) { + if (self.tag == core_result_Ok) { + int16_t f0[16U]; + memcpy(f0, self.val.case_Ok, (size_t)16U * sizeof(int16_t)); + memcpy(ret, f0, (size_t)16U * sizeof(int16_t)); + } else { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "unwrap not Ok"); + KRML_HOST_EXIT(255U); + } +} + +typedef struct + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError_s { + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError_tags tag; + union { + uint8_t case_Ok[8U]; + core_array_TryFromSliceError case_Err; + } val; +} core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError; + +static inline void +core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError self, + uint8_t ret[8U]) { + if (self.tag == core_result_Ok) { + uint8_t f0[8U]; + memcpy(f0, self.val.case_Ok, (size_t)8U * sizeof(uint8_t)); + memcpy(ret, f0, (size_t)8U * sizeof(uint8_t)); + } else { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "unwrap not Ok"); + KRML_HOST_EXIT(255U); + } +} + +typedef struct K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t_s { + Eurydice_slice fst; + Eurydice_slice snd; +} K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t; + +typedef struct + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t__s { + Eurydice_slice fst[1U]; + Eurydice_slice snd[1U]; +} K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_; + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_core_H_DEFINED +#endif diff --git a/libcrux-ml-kem/cg/libcrux_mlkem768_avx2.h b/libcrux-ml-kem/cg/libcrux_mlkem768_avx2.h new file mode 100644 index 000000000..e65c8602b --- /dev/null +++ b/libcrux-ml-kem/cg/libcrux_mlkem768_avx2.h @@ -0,0 +1,4864 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../cg.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 409fe455 + */ + +#ifndef __libcrux_mlkem768_avx2_H +#define __libcrux_mlkem768_avx2_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "eurydice_glue.h" +#include "libcrux_core.h" +#include "libcrux_mlkem768_portable.h" +#include "libcrux_sha3_avx2.h" +#include "libcrux_sha3_portable.h" + +typedef core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_SIMD256Vector; + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i libcrux_ml_kem_vector_avx2_zero(void) { + return libcrux_intrinsics_avx2_mm256_setzero_si256(); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO( + void) { + return libcrux_ml_kem_vector_avx2_zero(); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_from_i16_array(Eurydice_slice array) { + return libcrux_intrinsics_avx2_mm256_loadu_si256_i16(array); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___from_i16_array( + Eurydice_slice array) { + return libcrux_ml_kem_vector_avx2_from_i16_array(array); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_add(core_core_arch_x86___m256i lhs, + core_core_arch_x86___m256i rhs) { + return libcrux_intrinsics_avx2_mm256_add_epi16(lhs, rhs); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i *rhs) { + return libcrux_ml_kem_vector_avx2_arithmetic_add(lhs, rhs[0U]); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_sub(core_core_arch_x86___m256i lhs, + core_core_arch_x86___m256i rhs) { + return libcrux_intrinsics_avx2_mm256_sub_epi16(lhs, rhs); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( + core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i *rhs) { + return libcrux_ml_kem_vector_avx2_arithmetic_sub(lhs, rhs[0U]); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_multiply_by_constant( + core_core_arch_x86___m256i vector, int16_t constant) { + core_core_arch_x86___m256i uu____0 = vector; + return libcrux_intrinsics_avx2_mm256_mullo_epi16( + uu____0, libcrux_intrinsics_avx2_mm256_set1_epi16(constant)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___multiply_by_constant( + core_core_arch_x86___m256i v, int16_t c) { + return libcrux_ml_kem_vector_avx2_arithmetic_multiply_by_constant(v, c); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_bitwise_and_with_constant( + core_core_arch_x86___m256i vector, int16_t constant) { + core_core_arch_x86___m256i uu____0 = vector; + return libcrux_intrinsics_avx2_mm256_and_si256( + uu____0, libcrux_intrinsics_avx2_mm256_set1_epi16(constant)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___bitwise_and_with_constant( + core_core_arch_x86___m256i vector, int16_t constant) { + return libcrux_ml_kem_vector_avx2_arithmetic_bitwise_and_with_constant( + vector, constant); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_cond_subtract_3329( + core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus = + libcrux_intrinsics_avx2_mm256_set1_epi16( + LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + core_core_arch_x86___m256i v_minus_field_modulus = + libcrux_intrinsics_avx2_mm256_sub_epi16(vector, field_modulus); + core_core_arch_x86___m256i sign_mask = + libcrux_intrinsics_avx2_mm256_srai_epi16( + (int32_t)15, v_minus_field_modulus, core_core_arch_x86___m256i); + core_core_arch_x86___m256i conditional_add_field_modulus = + libcrux_intrinsics_avx2_mm256_and_si256(sign_mask, field_modulus); + return libcrux_intrinsics_avx2_mm256_add_epi16(v_minus_field_modulus, + conditional_add_field_modulus); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___cond_subtract_3329( + core_core_arch_x86___m256i vector) { + return libcrux_ml_kem_vector_avx2_arithmetic_cond_subtract_3329(vector); +} + +#define LIBCRUX_ML_KEM_VECTOR_AVX2_ARITHMETIC_BARRETT_MULTIPLIER \ + ((int16_t)20159) + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_barrett_reduce( + core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i uu____0 = vector; + core_core_arch_x86___m256i t = libcrux_intrinsics_avx2_mm256_mulhi_epi16( + uu____0, libcrux_intrinsics_avx2_mm256_set1_epi16( + LIBCRUX_ML_KEM_VECTOR_AVX2_ARITHMETIC_BARRETT_MULTIPLIER)); + core_core_arch_x86___m256i uu____1 = t; + core_core_arch_x86___m256i t0 = libcrux_intrinsics_avx2_mm256_add_epi16( + uu____1, libcrux_intrinsics_avx2_mm256_set1_epi16((int16_t)512)); + core_core_arch_x86___m256i quotient = + libcrux_intrinsics_avx2_mm256_srai_epi16((int32_t)10, t0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____2 = quotient; + core_core_arch_x86___m256i quotient_times_field_modulus = + libcrux_intrinsics_avx2_mm256_mullo_epi16( + uu____2, libcrux_intrinsics_avx2_mm256_set1_epi16( + LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); + return libcrux_intrinsics_avx2_mm256_sub_epi16(vector, + quotient_times_field_modulus); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( + core_core_arch_x86___m256i vector) { + return libcrux_ml_kem_vector_avx2_arithmetic_barrett_reduce(vector); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constant( + core_core_arch_x86___m256i vector, int16_t constant) { + core_core_arch_x86___m256i constant0 = + libcrux_intrinsics_avx2_mm256_set1_epi16(constant); + core_core_arch_x86___m256i value_low = + libcrux_intrinsics_avx2_mm256_mullo_epi16(vector, constant0); + core_core_arch_x86___m256i uu____0 = value_low; + core_core_arch_x86___m256i k = libcrux_intrinsics_avx2_mm256_mullo_epi16( + uu____0, + libcrux_intrinsics_avx2_mm256_set1_epi16( + (int16_t) + LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R)); + core_core_arch_x86___m256i uu____1 = k; + core_core_arch_x86___m256i k_times_modulus = + libcrux_intrinsics_avx2_mm256_mulhi_epi16( + uu____1, libcrux_intrinsics_avx2_mm256_set1_epi16( + LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); + core_core_arch_x86___m256i value_high = + libcrux_intrinsics_avx2_mm256_mulhi_epi16(vector, constant0); + return libcrux_intrinsics_avx2_mm256_sub_epi16(value_high, k_times_modulus); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( + core_core_arch_x86___m256i vector, int16_t constant) { + return libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constant( + vector, constant); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_compress_compress_message_coefficient( + core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus_halved = + libcrux_intrinsics_avx2_mm256_set1_epi16( + (LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int16_t)1) / + (int16_t)2); + core_core_arch_x86___m256i field_modulus_quartered = + libcrux_intrinsics_avx2_mm256_set1_epi16( + (LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int16_t)1) / + (int16_t)4); + core_core_arch_x86___m256i shifted = + libcrux_intrinsics_avx2_mm256_sub_epi16(field_modulus_halved, vector); + core_core_arch_x86___m256i mask = libcrux_intrinsics_avx2_mm256_srai_epi16( + (int32_t)15, shifted, core_core_arch_x86___m256i); + core_core_arch_x86___m256i shifted_to_positive = + libcrux_intrinsics_avx2_mm256_xor_si256(mask, shifted); + core_core_arch_x86___m256i shifted_to_positive_in_range = + libcrux_intrinsics_avx2_mm256_sub_epi16(shifted_to_positive, + field_modulus_quartered); + return libcrux_intrinsics_avx2_mm256_srli_epi16( + (int32_t)15, shifted_to_positive_in_range, core_core_arch_x86___m256i); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___compress_1( + core_core_arch_x86___m256i vector) { + return libcrux_ml_kem_vector_avx2_compress_compress_message_coefficient( + vector); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32( + core_core_arch_x86___m256i lhs, core_core_arch_x86___m256i rhs) { + core_core_arch_x86___m256i prod02 = + libcrux_intrinsics_avx2_mm256_mul_epu32(lhs, rhs); + core_core_arch_x86___m256i uu____0 = + libcrux_intrinsics_avx2_mm256_shuffle_epi32((int32_t)245, lhs, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i prod13 = libcrux_intrinsics_avx2_mm256_mul_epu32( + uu____0, libcrux_intrinsics_avx2_mm256_shuffle_epi32( + (int32_t)245, rhs, core_core_arch_x86___m256i)); + core_core_arch_x86___m256i uu____1 = + libcrux_intrinsics_avx2_mm256_unpacklo_epi32(prod02, prod13); + return libcrux_intrinsics_avx2_mm256_unpackhi_epi64( + uu____1, libcrux_intrinsics_avx2_mm256_unpackhi_epi32(prod02, prod13)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( + core_core_arch_x86___m256i v, core_core_arch_x86___m256i c) { + core_core_arch_x86___m256i value_low = + libcrux_intrinsics_avx2_mm256_mullo_epi16(v, c); + core_core_arch_x86___m256i uu____0 = value_low; + core_core_arch_x86___m256i k = libcrux_intrinsics_avx2_mm256_mullo_epi16( + uu____0, + libcrux_intrinsics_avx2_mm256_set1_epi16( + (int16_t) + LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R)); + core_core_arch_x86___m256i uu____1 = k; + core_core_arch_x86___m256i k_times_modulus = + libcrux_intrinsics_avx2_mm256_mulhi_epi16( + uu____1, libcrux_intrinsics_avx2_mm256_set1_epi16( + LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); + core_core_arch_x86___m256i value_high = + libcrux_intrinsics_avx2_mm256_mulhi_epi16(v, c); + return libcrux_intrinsics_avx2_mm256_sub_epi16(value_high, k_times_modulus); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_ntt_ntt_layer_1_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, + int16_t zeta2, int16_t zeta3) { + core_core_arch_x86___m256i zetas = libcrux_intrinsics_avx2_mm256_set_epi16( + -zeta3, -zeta3, zeta3, zeta3, -zeta2, -zeta2, zeta2, zeta2, -zeta1, + -zeta1, zeta1, zeta1, -zeta0, -zeta0, zeta0, zeta0); + core_core_arch_x86___m256i rhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( + (int32_t)245, vector, core_core_arch_x86___m256i); + core_core_arch_x86___m256i rhs0 = + libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( + rhs, zetas); + core_core_arch_x86___m256i lhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( + (int32_t)160, vector, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_add_epi16(lhs, rhs0); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_1_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, + int16_t zeta2, int16_t zeta3) { + return libcrux_ml_kem_vector_avx2_ntt_ntt_layer_1_step(vector, zeta0, zeta1, + zeta2, zeta3); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_ntt_ntt_layer_2_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1) { + core_core_arch_x86___m256i zetas = libcrux_intrinsics_avx2_mm256_set_epi16( + -zeta1, -zeta1, -zeta1, -zeta1, zeta1, zeta1, zeta1, zeta1, -zeta0, + -zeta0, -zeta0, -zeta0, zeta0, zeta0, zeta0, zeta0); + core_core_arch_x86___m256i rhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( + (int32_t)238, vector, core_core_arch_x86___m256i); + core_core_arch_x86___m256i rhs0 = + libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( + rhs, zetas); + core_core_arch_x86___m256i lhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( + (int32_t)68, vector, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_add_epi16(lhs, rhs0); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_2_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1) { + return libcrux_ml_kem_vector_avx2_ntt_ntt_layer_2_step(vector, zeta0, zeta1); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m128i +libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_m128i_by_constants( + core_core_arch_x86___m128i v, core_core_arch_x86___m128i c) { + core_core_arch_x86___m128i value_low = + libcrux_intrinsics_avx2_mm_mullo_epi16(v, c); + core_core_arch_x86___m128i uu____0 = value_low; + core_core_arch_x86___m128i k = libcrux_intrinsics_avx2_mm_mullo_epi16( + uu____0, + libcrux_intrinsics_avx2_mm_set1_epi16( + (int16_t) + LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R)); + core_core_arch_x86___m128i uu____1 = k; + core_core_arch_x86___m128i k_times_modulus = + libcrux_intrinsics_avx2_mm_mulhi_epi16( + uu____1, libcrux_intrinsics_avx2_mm_set1_epi16( + LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); + core_core_arch_x86___m128i value_high = + libcrux_intrinsics_avx2_mm_mulhi_epi16(v, c); + return libcrux_intrinsics_avx2_mm_sub_epi16(value_high, k_times_modulus); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_ntt_ntt_layer_3_step( + core_core_arch_x86___m256i vector, int16_t zeta) { + core_core_arch_x86___m128i rhs = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m128i uu____0 = rhs; + core_core_arch_x86___m128i rhs0 = + libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_m128i_by_constants( + uu____0, libcrux_intrinsics_avx2_mm_set1_epi16(zeta)); + core_core_arch_x86___m128i lhs = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m128i lower_coefficients = + libcrux_intrinsics_avx2_mm_add_epi16(lhs, rhs0); + core_core_arch_x86___m128i upper_coefficients = + libcrux_intrinsics_avx2_mm_sub_epi16(lhs, rhs0); + core_core_arch_x86___m256i combined = + libcrux_intrinsics_avx2_mm256_castsi128_si256(lower_coefficients); + core_core_arch_x86___m256i combined0 = + libcrux_intrinsics_avx2_mm256_inserti128_si256( + (int32_t)1, combined, upper_coefficients, core_core_arch_x86___m256i); + return combined0; +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_3_step( + core_core_arch_x86___m256i vector, int16_t zeta) { + return libcrux_ml_kem_vector_avx2_ntt_ntt_layer_3_step(vector, zeta); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_1_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, + int16_t zeta2, int16_t zeta3) { + core_core_arch_x86___m256i lhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( + (int32_t)245, vector, core_core_arch_x86___m256i); + core_core_arch_x86___m256i rhs = libcrux_intrinsics_avx2_mm256_shuffle_epi32( + (int32_t)160, vector, core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____0 = rhs; + core_core_arch_x86___m256i rhs0 = libcrux_intrinsics_avx2_mm256_mullo_epi16( + uu____0, libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)-1, (int16_t)-1, (int16_t)1, (int16_t)1, + (int16_t)-1, (int16_t)-1, (int16_t)1, (int16_t)1, + (int16_t)-1, (int16_t)-1, (int16_t)1, (int16_t)1, + (int16_t)-1, (int16_t)-1, (int16_t)1, (int16_t)1)); + core_core_arch_x86___m256i sum0 = + libcrux_intrinsics_avx2_mm256_add_epi16(lhs, rhs0); + core_core_arch_x86___m256i uu____1 = sum0; + core_core_arch_x86___m256i sum_times_zetas = + libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( + uu____1, libcrux_intrinsics_avx2_mm256_set_epi16( + zeta3, zeta3, (int16_t)0, (int16_t)0, zeta2, zeta2, + (int16_t)0, (int16_t)0, zeta1, zeta1, (int16_t)0, + (int16_t)0, zeta0, zeta0, (int16_t)0, (int16_t)0)); + core_core_arch_x86___m256i sum = + libcrux_ml_kem_vector_avx2_arithmetic_barrett_reduce(sum0); + return libcrux_intrinsics_avx2_mm256_blend_epi16( + (int32_t)204, sum, sum_times_zetas, core_core_arch_x86___m256i); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_1_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1, + int16_t zeta2, int16_t zeta3) { + return libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_1_step( + vector, zeta0, zeta1, zeta2, zeta3); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_2_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1) { + core_core_arch_x86___m256i lhs = + libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)245, vector, core_core_arch_x86___m256i); + core_core_arch_x86___m256i rhs = + libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)160, vector, core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____0 = rhs; + core_core_arch_x86___m256i rhs0 = libcrux_intrinsics_avx2_mm256_mullo_epi16( + uu____0, libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)-1, (int16_t)-1, (int16_t)-1, (int16_t)-1, + (int16_t)1, (int16_t)1, (int16_t)1, (int16_t)1, (int16_t)-1, + (int16_t)-1, (int16_t)-1, (int16_t)-1, (int16_t)1, + (int16_t)1, (int16_t)1, (int16_t)1)); + core_core_arch_x86___m256i sum = + libcrux_intrinsics_avx2_mm256_add_epi16(lhs, rhs0); + core_core_arch_x86___m256i uu____1 = sum; + core_core_arch_x86___m256i sum_times_zetas = + libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_by_constants( + uu____1, libcrux_intrinsics_avx2_mm256_set_epi16( + zeta1, zeta1, zeta1, zeta1, (int16_t)0, (int16_t)0, + (int16_t)0, (int16_t)0, zeta0, zeta0, zeta0, zeta0, + (int16_t)0, (int16_t)0, (int16_t)0, (int16_t)0)); + return libcrux_intrinsics_avx2_mm256_blend_epi16( + (int32_t)240, sum, sum_times_zetas, core_core_arch_x86___m256i); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_2_step( + core_core_arch_x86___m256i vector, int16_t zeta0, int16_t zeta1) { + return libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_2_step(vector, zeta0, + zeta1); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_3_step( + core_core_arch_x86___m256i vector, int16_t zeta) { + core_core_arch_x86___m128i lhs = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m128i rhs = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m128i lower_coefficients = + libcrux_intrinsics_avx2_mm_add_epi16(lhs, rhs); + core_core_arch_x86___m128i upper_coefficients = + libcrux_intrinsics_avx2_mm_sub_epi16(lhs, rhs); + core_core_arch_x86___m128i uu____0 = upper_coefficients; + core_core_arch_x86___m128i upper_coefficients0 = + libcrux_ml_kem_vector_avx2_arithmetic_montgomery_multiply_m128i_by_constants( + uu____0, libcrux_intrinsics_avx2_mm_set1_epi16(zeta)); + core_core_arch_x86___m256i combined = + libcrux_intrinsics_avx2_mm256_castsi128_si256(lower_coefficients); + core_core_arch_x86___m256i combined0 = + libcrux_intrinsics_avx2_mm256_inserti128_si256( + (int32_t)1, combined, upper_coefficients0, + core_core_arch_x86___m256i); + return combined0; +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_3_step( + core_core_arch_x86___m256i vector, int16_t zeta) { + return libcrux_ml_kem_vector_avx2_ntt_inv_ntt_layer_3_step(vector, zeta); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_montgomery_reduce_i32s( + core_core_arch_x86___m256i v) { + core_core_arch_x86___m256i uu____0 = v; + core_core_arch_x86___m256i k = libcrux_intrinsics_avx2_mm256_mullo_epi16( + uu____0, + libcrux_intrinsics_avx2_mm256_set1_epi32( + (int32_t) + LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R)); + core_core_arch_x86___m256i uu____1 = k; + core_core_arch_x86___m256i k_times_modulus = + libcrux_intrinsics_avx2_mm256_mulhi_epi16( + uu____1, libcrux_intrinsics_avx2_mm256_set1_epi32( + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS)); + core_core_arch_x86___m256i value_high = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)16, v, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i result = + libcrux_intrinsics_avx2_mm256_sub_epi16(value_high, k_times_modulus); + core_core_arch_x86___m256i result0 = libcrux_intrinsics_avx2_mm256_slli_epi32( + (int32_t)16, result, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_srai_epi32((int32_t)16, result0, + core_core_arch_x86___m256i); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_ntt_ntt_multiply(core_core_arch_x86___m256i lhs, + core_core_arch_x86___m256i rhs, + int16_t zeta0, int16_t zeta1, + int16_t zeta2, int16_t zeta3) { + core_core_arch_x86___m256i shuffle_with = + libcrux_intrinsics_avx2_mm256_set_epi8( + (int8_t)15, (int8_t)14, (int8_t)11, (int8_t)10, (int8_t)7, (int8_t)6, + (int8_t)3, (int8_t)2, (int8_t)13, (int8_t)12, (int8_t)9, (int8_t)8, + (int8_t)5, (int8_t)4, (int8_t)1, (int8_t)0, (int8_t)15, (int8_t)14, + (int8_t)11, (int8_t)10, (int8_t)7, (int8_t)6, (int8_t)3, (int8_t)2, + (int8_t)13, (int8_t)12, (int8_t)9, (int8_t)8, (int8_t)5, (int8_t)4, + (int8_t)1, (int8_t)0); + core_core_arch_x86___m256i lhs_shuffled = + libcrux_intrinsics_avx2_mm256_shuffle_epi8(lhs, shuffle_with); + core_core_arch_x86___m256i lhs_shuffled0 = + libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, lhs_shuffled, core_core_arch_x86___m256i); + core_core_arch_x86___m128i lhs_evens = + libcrux_intrinsics_avx2_mm256_castsi256_si128(lhs_shuffled0); + core_core_arch_x86___m256i lhs_evens0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(lhs_evens); + core_core_arch_x86___m128i lhs_odds = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, lhs_shuffled0, core_core_arch_x86___m128i); + core_core_arch_x86___m256i lhs_odds0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(lhs_odds); + core_core_arch_x86___m256i rhs_shuffled = + libcrux_intrinsics_avx2_mm256_shuffle_epi8(rhs, shuffle_with); + core_core_arch_x86___m256i rhs_shuffled0 = + libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, rhs_shuffled, core_core_arch_x86___m256i); + core_core_arch_x86___m128i rhs_evens = + libcrux_intrinsics_avx2_mm256_castsi256_si128(rhs_shuffled0); + core_core_arch_x86___m256i rhs_evens0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(rhs_evens); + core_core_arch_x86___m128i rhs_odds = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, rhs_shuffled0, core_core_arch_x86___m128i); + core_core_arch_x86___m256i rhs_odds0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(rhs_odds); + core_core_arch_x86___m256i left = + libcrux_intrinsics_avx2_mm256_mullo_epi32(lhs_evens0, rhs_evens0); + core_core_arch_x86___m256i right = + libcrux_intrinsics_avx2_mm256_mullo_epi32(lhs_odds0, rhs_odds0); + core_core_arch_x86___m256i right0 = + libcrux_ml_kem_vector_avx2_arithmetic_montgomery_reduce_i32s(right); + core_core_arch_x86___m256i uu____0 = right0; + core_core_arch_x86___m256i right1 = libcrux_intrinsics_avx2_mm256_mullo_epi32( + uu____0, + libcrux_intrinsics_avx2_mm256_set_epi32( + -(int32_t)zeta3, (int32_t)zeta3, -(int32_t)zeta2, (int32_t)zeta2, + -(int32_t)zeta1, (int32_t)zeta1, -(int32_t)zeta0, (int32_t)zeta0)); + core_core_arch_x86___m256i products_left = + libcrux_intrinsics_avx2_mm256_add_epi32(left, right1); + core_core_arch_x86___m256i products_left0 = + libcrux_ml_kem_vector_avx2_arithmetic_montgomery_reduce_i32s( + products_left); + core_core_arch_x86___m256i uu____1 = rhs; + core_core_arch_x86___m256i rhs_adjacent_swapped = + libcrux_intrinsics_avx2_mm256_shuffle_epi8( + uu____1, libcrux_intrinsics_avx2_mm256_set_epi8( + (int8_t)13, (int8_t)12, (int8_t)15, (int8_t)14, + (int8_t)9, (int8_t)8, (int8_t)11, (int8_t)10, (int8_t)5, + (int8_t)4, (int8_t)7, (int8_t)6, (int8_t)1, (int8_t)0, + (int8_t)3, (int8_t)2, (int8_t)13, (int8_t)12, (int8_t)15, + (int8_t)14, (int8_t)9, (int8_t)8, (int8_t)11, (int8_t)10, + (int8_t)5, (int8_t)4, (int8_t)7, (int8_t)6, (int8_t)1, + (int8_t)0, (int8_t)3, (int8_t)2)); + core_core_arch_x86___m256i products_right = + libcrux_intrinsics_avx2_mm256_madd_epi16(lhs, rhs_adjacent_swapped); + core_core_arch_x86___m256i products_right0 = + libcrux_ml_kem_vector_avx2_arithmetic_montgomery_reduce_i32s( + products_right); + core_core_arch_x86___m256i products_right1 = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)16, products_right0, + core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_blend_epi16((int32_t)170, products_left0, + products_right1, + core_core_arch_x86___m256i); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_multiply( + core_core_arch_x86___m256i *lhs, core_core_arch_x86___m256i *rhs, + int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3) { + return libcrux_ml_kem_vector_avx2_ntt_ntt_multiply(lhs[0U], rhs[0U], zeta0, + zeta1, zeta2, zeta3); +} + +__attribute__((target("avx2"))) +static inline void libcrux_ml_kem_vector_avx2_serialize_serialize_1( + core_core_arch_x86___m256i vector, uint8_t ret[2U]) { + core_core_arch_x86___m256i lsb_to_msb = + libcrux_intrinsics_avx2_mm256_slli_epi16((int32_t)15, vector, + core_core_arch_x86___m256i); + core_core_arch_x86___m128i low_msbs = + libcrux_intrinsics_avx2_mm256_castsi256_si128(lsb_to_msb); + core_core_arch_x86___m128i high_msbs = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, lsb_to_msb, core_core_arch_x86___m128i); + core_core_arch_x86___m128i msbs = + libcrux_intrinsics_avx2_mm_packs_epi16(low_msbs, high_msbs); + int32_t bits_packed = libcrux_intrinsics_avx2_mm_movemask_epi8(msbs); + uint8_t serialized[2U] = {0U}; + serialized[0U] = (uint8_t)bits_packed; + serialized[1U] = (uint8_t)(bits_packed >> 8U); + memcpy(ret, serialized, (size_t)2U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_1( + core_core_arch_x86___m256i vector, uint8_t ret[2U]) { + uint8_t ret0[2U]; + libcrux_ml_kem_vector_avx2_serialize_serialize_1(vector, ret0); + memcpy(ret, ret0, (size_t)2U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_serialize_deserialize_1(Eurydice_slice bytes) { + int16_t uu____0 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____1 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____2 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____3 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____4 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____5 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____6 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____7 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____8 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____9 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____10 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____11 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____12 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____13 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____14 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + core_core_arch_x86___m256i coefficients = + libcrux_intrinsics_avx2_mm256_set_epi16( + uu____0, uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, + uu____7, uu____8, uu____9, uu____10, uu____11, uu____12, uu____13, + uu____14, + (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, + uint8_t)); + core_core_arch_x86___m256i shift_lsb_to_msb = + libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 8U, (int16_t)1 << 9U, (int16_t)1 << 10U, + (int16_t)1 << 11U, (int16_t)1 << 12U, (int16_t)1 << 13U, + (int16_t)1 << 14U, (int16_t)1 << 15U, (int16_t)1 << 8U, + (int16_t)1 << 9U, (int16_t)1 << 10U, (int16_t)1 << 11U, + (int16_t)1 << 12U, (int16_t)1 << 13U, (int16_t)1 << 14U, + (int16_t)1 << 15U); + core_core_arch_x86___m256i coefficients_in_msb = + libcrux_intrinsics_avx2_mm256_mullo_epi16(coefficients, shift_lsb_to_msb); + return libcrux_intrinsics_avx2_mm256_srli_epi16( + (int32_t)15, coefficients_in_msb, core_core_arch_x86___m256i); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_1( + Eurydice_slice bytes) { + return libcrux_ml_kem_vector_avx2_serialize_deserialize_1(bytes); +} + +__attribute__((target("avx2"))) +static inline void libcrux_ml_kem_vector_avx2_serialize_serialize_4( + core_core_arch_x86___m256i vector, uint8_t ret[8U]) { + uint8_t serialized[16U] = {0U}; + core_core_arch_x86___m256i uu____0 = vector; + core_core_arch_x86___m256i adjacent_2_combined = + libcrux_intrinsics_avx2_mm256_madd_epi16( + uu____0, + libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 4U, (int16_t)1, (int16_t)1 << 4U, (int16_t)1, + (int16_t)1 << 4U, (int16_t)1, (int16_t)1 << 4U, (int16_t)1, + (int16_t)1 << 4U, (int16_t)1, (int16_t)1 << 4U, (int16_t)1, + (int16_t)1 << 4U, (int16_t)1, (int16_t)1 << 4U, (int16_t)1)); + core_core_arch_x86___m256i uu____1 = adjacent_2_combined; + core_core_arch_x86___m256i adjacent_8_combined = + libcrux_intrinsics_avx2_mm256_shuffle_epi8( + uu____1, + libcrux_intrinsics_avx2_mm256_set_epi8( + (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, + (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, + (int8_t)-1, (int8_t)-1, (int8_t)12, (int8_t)8, (int8_t)4, + (int8_t)0, (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, + (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, + (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)12, (int8_t)8, + (int8_t)4, (int8_t)0)); + core_core_arch_x86___m256i uu____2 = adjacent_8_combined; + core_core_arch_x86___m256i combined = + libcrux_intrinsics_avx2_mm256_permutevar8x32_epi32( + uu____2, libcrux_intrinsics_avx2_mm256_set_epi32( + (int32_t)0, (int32_t)0, (int32_t)0, (int32_t)0, + (int32_t)0, (int32_t)0, (int32_t)4, (int32_t)0)); + core_core_arch_x86___m128i combined0 = + libcrux_intrinsics_avx2_mm256_castsi256_si128(combined); + libcrux_intrinsics_avx2_mm_storeu_bytes_si128( + Eurydice_array_to_slice((size_t)16U, serialized, uint8_t, Eurydice_slice), + combined0); + uint8_t ret0[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_array_to_subslice((size_t)16U, serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, uint8_t[8U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + dst, ret0); + memcpy(ret, ret0, (size_t)8U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_4( + core_core_arch_x86___m256i vector, uint8_t ret[8U]) { + uint8_t ret0[8U]; + libcrux_ml_kem_vector_avx2_serialize_serialize_4(vector, ret0); + memcpy(ret, ret0, (size_t)8U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_serialize_deserialize_4(Eurydice_slice bytes) { + int16_t uu____0 = (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____1 = (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____2 = (int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____3 = (int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____4 = (int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____5 = (int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____6 = (int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____7 = (int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____8 = (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____9 = (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____10 = (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____11 = (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____12 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____13 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t uu____14 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + core_core_arch_x86___m256i coefficients = + libcrux_intrinsics_avx2_mm256_set_epi16( + uu____0, uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, + uu____7, uu____8, uu____9, uu____10, uu____11, uu____12, uu____13, + uu____14, + (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, + uint8_t)); + core_core_arch_x86___m256i shift_lsbs_to_msbs = + libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, + (int16_t)1 << 4U, (int16_t)1 << 0U, (int16_t)1 << 4U, + (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, + (int16_t)1 << 4U, (int16_t)1 << 0U, (int16_t)1 << 4U, + (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, + (int16_t)1 << 4U); + core_core_arch_x86___m256i coefficients_in_msb = + libcrux_intrinsics_avx2_mm256_mullo_epi16(coefficients, + shift_lsbs_to_msbs); + core_core_arch_x86___m256i coefficients_in_lsb = + libcrux_intrinsics_avx2_mm256_srli_epi16((int32_t)4, coefficients_in_msb, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____15 = coefficients_in_lsb; + return libcrux_intrinsics_avx2_mm256_and_si256( + uu____15, libcrux_intrinsics_avx2_mm256_set1_epi16(((int16_t)1 << 4U) - + (int16_t)1)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_4( + Eurydice_slice bytes) { + return libcrux_ml_kem_vector_avx2_serialize_deserialize_4(bytes); +} + +__attribute__((target("avx2"))) +static inline void libcrux_ml_kem_vector_avx2_serialize_serialize_5( + core_core_arch_x86___m256i vector, uint8_t ret[10U]) { + uint8_t serialized[32U] = {0U}; + core_core_arch_x86___m256i uu____0 = vector; + core_core_arch_x86___m256i adjacent_2_combined = + libcrux_intrinsics_avx2_mm256_madd_epi16( + uu____0, + libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 5U, (int16_t)1, (int16_t)1 << 5U, (int16_t)1, + (int16_t)1 << 5U, (int16_t)1, (int16_t)1 << 5U, (int16_t)1, + (int16_t)1 << 5U, (int16_t)1, (int16_t)1 << 5U, (int16_t)1, + (int16_t)1 << 5U, (int16_t)1, (int16_t)1 << 5U, (int16_t)1)); + core_core_arch_x86___m256i uu____1 = adjacent_2_combined; + core_core_arch_x86___m256i adjacent_4_combined = + libcrux_intrinsics_avx2_mm256_sllv_epi32( + uu____1, libcrux_intrinsics_avx2_mm256_set_epi32( + (int32_t)0, (int32_t)22, (int32_t)0, (int32_t)22, + (int32_t)0, (int32_t)22, (int32_t)0, (int32_t)22)); + core_core_arch_x86___m256i adjacent_4_combined0 = + libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)22, adjacent_4_combined, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i adjacent_8_combined = + libcrux_intrinsics_avx2_mm256_shuffle_epi32( + (int32_t)8, adjacent_4_combined0, core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____2 = adjacent_8_combined; + core_core_arch_x86___m256i adjacent_8_combined0 = + libcrux_intrinsics_avx2_mm256_sllv_epi32( + uu____2, libcrux_intrinsics_avx2_mm256_set_epi32( + (int32_t)0, (int32_t)0, (int32_t)0, (int32_t)12, + (int32_t)0, (int32_t)0, (int32_t)0, (int32_t)12)); + core_core_arch_x86___m256i adjacent_8_combined1 = + libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)12, adjacent_8_combined0, core_core_arch_x86___m256i); + core_core_arch_x86___m128i lower_8 = + libcrux_intrinsics_avx2_mm256_castsi256_si128(adjacent_8_combined1); + libcrux_intrinsics_avx2_mm_storeu_bytes_si128( + Eurydice_array_to_subslice((size_t)32U, serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + lower_8); + core_core_arch_x86___m128i upper_8 = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, adjacent_8_combined1, core_core_arch_x86___m128i); + libcrux_intrinsics_avx2_mm_storeu_bytes_si128( + Eurydice_array_to_subslice((size_t)32U, serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)5U, .end = (size_t)21U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + upper_8); + uint8_t ret0[10U]; + core_result_Result__uint8_t_10size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_array_to_subslice((size_t)32U, serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)10U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, uint8_t[10U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_10size_t__core_array_TryFromSliceError( + dst, ret0); + memcpy(ret, ret0, (size_t)10U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_5( + core_core_arch_x86___m256i vector, uint8_t ret[10U]) { + uint8_t ret0[10U]; + libcrux_ml_kem_vector_avx2_serialize_serialize_5(vector, ret0); + memcpy(ret, ret0, (size_t)10U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_serialize_deserialize_5(Eurydice_slice bytes) { + uint8_t uu____0 = + Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____1 = + Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____2 = + Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____3 = + Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____4 = + Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____5 = + Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____6 = + Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____7 = + Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____8 = + Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____9 = + Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____10 = + Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____11 = + Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____12 = + Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____13 = + Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + uint8_t uu____14 = + Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + core_core_arch_x86___m128i coefficients = libcrux_intrinsics_avx2_mm_set_epi8( + uu____0, uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, uu____7, + uu____8, uu____9, uu____10, uu____11, uu____12, uu____13, uu____14, + Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t)); + core_core_arch_x86___m256i coefficients_loaded = + libcrux_intrinsics_avx2_mm256_castsi128_si256(coefficients); + core_core_arch_x86___m256i coefficients_loaded0 = + libcrux_intrinsics_avx2_mm256_inserti128_si256( + (int32_t)1, coefficients_loaded, coefficients, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____15 = coefficients_loaded0; + core_core_arch_x86___m256i coefficients0 = + libcrux_intrinsics_avx2_mm256_shuffle_epi8( + uu____15, + libcrux_intrinsics_avx2_mm256_set_epi8( + (int8_t)15, (int8_t)14, (int8_t)15, (int8_t)14, (int8_t)13, + (int8_t)12, (int8_t)13, (int8_t)12, (int8_t)11, (int8_t)10, + (int8_t)11, (int8_t)10, (int8_t)9, (int8_t)8, (int8_t)9, + (int8_t)8, (int8_t)7, (int8_t)6, (int8_t)7, (int8_t)6, (int8_t)5, + (int8_t)4, (int8_t)5, (int8_t)4, (int8_t)3, (int8_t)2, (int8_t)3, + (int8_t)2, (int8_t)1, (int8_t)0, (int8_t)1, (int8_t)0)); + core_core_arch_x86___m256i uu____16 = coefficients0; + core_core_arch_x86___m256i coefficients1 = + libcrux_intrinsics_avx2_mm256_mullo_epi16( + uu____16, libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 0U, (int16_t)1 << 5U, (int16_t)1 << 2U, + (int16_t)1 << 7U, (int16_t)1 << 4U, (int16_t)1 << 9U, + (int16_t)1 << 6U, (int16_t)1 << 11U, (int16_t)1 << 0U, + (int16_t)1 << 5U, (int16_t)1 << 2U, (int16_t)1 << 7U, + (int16_t)1 << 4U, (int16_t)1 << 9U, (int16_t)1 << 6U, + (int16_t)1 << 11U)); + return libcrux_intrinsics_avx2_mm256_srli_epi16((int32_t)11, coefficients1, + core_core_arch_x86___m256i); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_5( + Eurydice_slice bytes) { + return libcrux_ml_kem_vector_avx2_serialize_deserialize_5(bytes); +} + +__attribute__((target("avx2"))) +static inline void libcrux_ml_kem_vector_avx2_serialize_serialize_10( + core_core_arch_x86___m256i vector, uint8_t ret[20U]) { + uint8_t serialized[32U] = {0U}; + core_core_arch_x86___m256i uu____0 = vector; + core_core_arch_x86___m256i adjacent_2_combined = + libcrux_intrinsics_avx2_mm256_madd_epi16( + uu____0, + libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 10U, (int16_t)1, (int16_t)1 << 10U, (int16_t)1, + (int16_t)1 << 10U, (int16_t)1, (int16_t)1 << 10U, (int16_t)1, + (int16_t)1 << 10U, (int16_t)1, (int16_t)1 << 10U, (int16_t)1, + (int16_t)1 << 10U, (int16_t)1, (int16_t)1 << 10U, (int16_t)1)); + core_core_arch_x86___m256i uu____1 = adjacent_2_combined; + core_core_arch_x86___m256i adjacent_4_combined = + libcrux_intrinsics_avx2_mm256_sllv_epi32( + uu____1, libcrux_intrinsics_avx2_mm256_set_epi32( + (int32_t)0, (int32_t)12, (int32_t)0, (int32_t)12, + (int32_t)0, (int32_t)12, (int32_t)0, (int32_t)12)); + core_core_arch_x86___m256i adjacent_4_combined0 = + libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)12, adjacent_4_combined, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____2 = adjacent_4_combined0; + core_core_arch_x86___m256i adjacent_8_combined = + libcrux_intrinsics_avx2_mm256_shuffle_epi8( + uu____2, libcrux_intrinsics_avx2_mm256_set_epi8( + (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, + (int8_t)-1, (int8_t)-1, (int8_t)12, (int8_t)11, + (int8_t)10, (int8_t)9, (int8_t)8, (int8_t)4, (int8_t)3, + (int8_t)2, (int8_t)1, (int8_t)0, (int8_t)-1, (int8_t)-1, + (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, + (int8_t)12, (int8_t)11, (int8_t)10, (int8_t)9, (int8_t)8, + (int8_t)4, (int8_t)3, (int8_t)2, (int8_t)1, (int8_t)0)); + core_core_arch_x86___m128i lower_8 = + libcrux_intrinsics_avx2_mm256_castsi256_si128(adjacent_8_combined); + libcrux_intrinsics_avx2_mm_storeu_bytes_si128( + Eurydice_array_to_subslice((size_t)32U, serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + lower_8); + core_core_arch_x86___m128i upper_8 = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, adjacent_8_combined, core_core_arch_x86___m128i); + libcrux_intrinsics_avx2_mm_storeu_bytes_si128( + Eurydice_array_to_subslice((size_t)32U, serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)10U, .end = (size_t)26U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + upper_8); + uint8_t ret0[20U]; + core_result_Result__uint8_t_20size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_array_to_subslice((size_t)32U, serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)20U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, uint8_t[20U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_20size_t__core_array_TryFromSliceError( + dst, ret0); + memcpy(ret, ret0, (size_t)20U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_10( + core_core_arch_x86___m256i vector, uint8_t ret[20U]) { + uint8_t ret0[20U]; + libcrux_ml_kem_vector_avx2_serialize_serialize_10(vector, ret0); + memcpy(ret, ret0, (size_t)20U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_serialize_deserialize_10(Eurydice_slice bytes) { + core_core_arch_x86___m256i shift_lsbs_to_msbs = + libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 0U, (int16_t)1 << 2U, (int16_t)1 << 4U, + (int16_t)1 << 6U, (int16_t)1 << 0U, (int16_t)1 << 2U, + (int16_t)1 << 4U, (int16_t)1 << 6U, (int16_t)1 << 0U, + (int16_t)1 << 2U, (int16_t)1 << 4U, (int16_t)1 << 6U, + (int16_t)1 << 0U, (int16_t)1 << 2U, (int16_t)1 << 4U, + (int16_t)1 << 6U); + core_core_arch_x86___m128i lower_coefficients = + libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_slice_subslice( + bytes, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m128i uu____0 = lower_coefficients; + core_core_arch_x86___m128i lower_coefficients0 = + libcrux_intrinsics_avx2_mm_shuffle_epi8( + uu____0, + libcrux_intrinsics_avx2_mm_set_epi8(9U, 8U, 8U, 7U, 7U, 6U, 6U, 5U, + 4U, 3U, 3U, 2U, 2U, 1U, 1U, 0U)); + core_core_arch_x86___m128i upper_coefficients = + libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_slice_subslice( + bytes, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)4U, + .end = (size_t)20U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m128i uu____1 = upper_coefficients; + core_core_arch_x86___m128i upper_coefficients0 = + libcrux_intrinsics_avx2_mm_shuffle_epi8( + uu____1, libcrux_intrinsics_avx2_mm_set_epi8(15U, 14U, 14U, 13U, 13U, + 12U, 12U, 11U, 10U, 9U, + 9U, 8U, 8U, 7U, 7U, 6U)); + core_core_arch_x86___m256i coefficients = + libcrux_intrinsics_avx2_mm256_castsi128_si256(lower_coefficients0); + core_core_arch_x86___m256i coefficients0 = + libcrux_intrinsics_avx2_mm256_inserti128_si256( + (int32_t)1, coefficients, upper_coefficients0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i coefficients1 = + libcrux_intrinsics_avx2_mm256_mullo_epi16(coefficients0, + shift_lsbs_to_msbs); + core_core_arch_x86___m256i coefficients2 = + libcrux_intrinsics_avx2_mm256_srli_epi16((int32_t)6, coefficients1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____2 = coefficients2; + core_core_arch_x86___m256i coefficients3 = + libcrux_intrinsics_avx2_mm256_and_si256( + uu____2, libcrux_intrinsics_avx2_mm256_set1_epi16( + ((int16_t)1 << 10U) - (int16_t)1)); + return coefficients3; +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_10( + Eurydice_slice bytes) { + return libcrux_ml_kem_vector_avx2_serialize_deserialize_10(bytes); +} + +__attribute__((target("avx2"))) +static inline void libcrux_ml_kem_vector_avx2_to_i16_array( + core_core_arch_x86___m256i v, int16_t ret[16U]) { + int16_t output[16U] = {0U}; + libcrux_intrinsics_avx2_mm256_storeu_si256_i16( + Eurydice_array_to_slice((size_t)16U, output, int16_t, Eurydice_slice), v); + memcpy(ret, output, (size_t)16U * sizeof(int16_t)); +} + +typedef struct libcrux_ml_kem_vector_avx2_portable_PortableVector_s { + int16_t elements[16U]; +} libcrux_ml_kem_vector_avx2_portable_PortableVector; + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_vector_avx2_portable_PortableVector +libcrux_ml_kem_vector_avx2_portable_from_i16_array(int16_t array[16U]) { + int16_t uu____0[16U]; + memcpy(uu____0, array, (size_t)16U * sizeof(int16_t)); + libcrux_ml_kem_vector_avx2_portable_PortableVector lit; + memcpy(lit.elements, uu____0, (size_t)16U * sizeof(int16_t)); + return lit; +} + +__attribute__((target("avx2"))) +static inline void libcrux_ml_kem_vector_avx2_portable_serialize_11( + libcrux_ml_kem_vector_avx2_portable_PortableVector v, uint8_t ret[22U]) { + uint8_t result[22U] = {0U}; + result[0U] = (uint8_t)v.elements[0U]; + result[1U] = (uint32_t)(uint8_t)(v.elements[1U] & (int16_t)31) << 3U | + (uint32_t)(uint8_t)(v.elements[0U] >> 8U); + result[2U] = (uint32_t)(uint8_t)(v.elements[2U] & (int16_t)3) << 6U | + (uint32_t)(uint8_t)(v.elements[1U] >> 5U); + result[3U] = (uint8_t)(v.elements[2U] >> 2U & (int16_t)255); + result[4U] = (uint32_t)(uint8_t)(v.elements[3U] & (int16_t)127) << 1U | + (uint32_t)(uint8_t)(v.elements[2U] >> 10U); + result[5U] = (uint32_t)(uint8_t)(v.elements[4U] & (int16_t)15) << 4U | + (uint32_t)(uint8_t)(v.elements[3U] >> 7U); + result[6U] = (uint32_t)(uint8_t)(v.elements[5U] & (int16_t)1) << 7U | + (uint32_t)(uint8_t)(v.elements[4U] >> 4U); + result[7U] = (uint8_t)(v.elements[5U] >> 1U & (int16_t)255); + result[8U] = (uint32_t)(uint8_t)(v.elements[6U] & (int16_t)63) << 2U | + (uint32_t)(uint8_t)(v.elements[5U] >> 9U); + result[9U] = (uint32_t)(uint8_t)(v.elements[7U] & (int16_t)7) << 5U | + (uint32_t)(uint8_t)(v.elements[6U] >> 6U); + result[10U] = (uint8_t)(v.elements[7U] >> 3U); + result[11U] = (uint8_t)v.elements[(size_t)8U + (size_t)0U]; + result[12U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] & (int16_t)31) + << 3U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)0U] >> 8U); + result[13U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] & (int16_t)3) + << 6U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] >> 5U); + result[14U] = + (uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 2U & (int16_t)255); + result[15U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)3U] & (int16_t)127) + << 1U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 10U); + result[16U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)4U] & (int16_t)15) + << 4U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)3U] >> 7U); + result[17U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] & (int16_t)1) + << 7U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)4U] >> 4U); + result[18U] = + (uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 1U & (int16_t)255); + result[19U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] & (int16_t)63) + << 2U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 9U); + result[20U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)7U] & (int16_t)7) + << 5U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] >> 6U); + result[21U] = (uint8_t)(v.elements[(size_t)8U + (size_t)7U] >> 3U); + memcpy(ret, result, (size_t)22U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline void libcrux_ml_kem_vector_avx2_serialize_serialize_11( + core_core_arch_x86___m256i vector, uint8_t ret[22U]) { + int16_t array[16U]; + libcrux_ml_kem_vector_avx2_to_i16_array(vector, array); + int16_t uu____0[16U]; + memcpy(uu____0, array, (size_t)16U * sizeof(int16_t)); + libcrux_ml_kem_vector_avx2_portable_PortableVector input = + libcrux_ml_kem_vector_avx2_portable_from_i16_array(uu____0); + uint8_t ret0[22U]; + libcrux_ml_kem_vector_avx2_portable_serialize_11(input, ret0); + memcpy(ret, ret0, (size_t)22U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_11( + core_core_arch_x86___m256i vector, uint8_t ret[22U]) { + uint8_t ret0[22U]; + libcrux_ml_kem_vector_avx2_serialize_serialize_11(vector, ret0); + memcpy(ret, ret0, (size_t)22U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_vector_avx2_portable_PortableVector +libcrux_ml_kem_vector_avx2_portable_zero(void) { + libcrux_ml_kem_vector_avx2_portable_PortableVector lit; + lit.elements[0U] = (int16_t)0; + lit.elements[1U] = (int16_t)0; + lit.elements[2U] = (int16_t)0; + lit.elements[3U] = (int16_t)0; + lit.elements[4U] = (int16_t)0; + lit.elements[5U] = (int16_t)0; + lit.elements[6U] = (int16_t)0; + lit.elements[7U] = (int16_t)0; + lit.elements[8U] = (int16_t)0; + lit.elements[9U] = (int16_t)0; + lit.elements[10U] = (int16_t)0; + lit.elements[11U] = (int16_t)0; + lit.elements[12U] = (int16_t)0; + lit.elements[13U] = (int16_t)0; + lit.elements[14U] = (int16_t)0; + lit.elements[15U] = (int16_t)0; + return lit; +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_vector_avx2_portable_PortableVector +libcrux_ml_kem_vector_avx2_portable_deserialize_11(Eurydice_slice bytes) { + libcrux_ml_kem_vector_avx2_portable_PortableVector result = + libcrux_ml_kem_vector_avx2_portable_zero(); + int16_t uu____0 = ((int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)7) + << 8U; + uint8_t *uu____1 = + &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); + result.elements[0U] = uu____0 | (int16_t)uu____1[0U]; + int16_t uu____2 = ((int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)63) + << 5U; + uint8_t *uu____3 = + &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + result.elements[1U] = uu____2 | (int16_t)uu____3[0U] >> 3U; + int16_t uu____4 = ((int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)1) + << 10U; + int16_t uu____5 = + uu____4 | (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, + uint8_t *, uint8_t) + << 2U; + uint8_t *uu____6 = + &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + result.elements[2U] = uu____5 | (int16_t)uu____6[0U] >> 6U; + int16_t uu____7 = ((int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)15) + << 7U; + uint8_t *uu____8 = + &Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); + result.elements[3U] = uu____7 | (int16_t)uu____8[0U] >> 1U; + int16_t uu____9 = ((int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)127) + << 4U; + uint8_t *uu____10 = + &Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); + result.elements[4U] = uu____9 | (int16_t)uu____10[0U] >> 4U; + int16_t uu____11 = ((int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)3) + << 9U; + int16_t uu____12 = + uu____11 | (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, + uint8_t *, uint8_t) + << 1U; + uint8_t *uu____13 = + &Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); + result.elements[5U] = uu____12 | (int16_t)uu____13[0U] >> 7U; + int16_t uu____14 = ((int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)31) + << 6U; + uint8_t *uu____15 = + &Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t); + result.elements[6U] = uu____14 | (int16_t)uu____15[0U] >> 2U; + int16_t uu____16 = (int16_t)Eurydice_slice_index(bytes, (size_t)10U, uint8_t, + uint8_t *, uint8_t) + << 3U; + uint8_t *uu____17 = + &Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *, uint8_t); + result.elements[7U] = uu____16 | (int16_t)uu____17[0U] >> 5U; + int16_t uu____18 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)1U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)7) + << 8U; + uint8_t *uu____19 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)0U, + uint8_t, uint8_t *, uint8_t); + result.elements[8U] = uu____18 | (int16_t)uu____19[0U]; + int16_t uu____20 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)2U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)63) + << 5U; + uint8_t *uu____21 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)1U, + uint8_t, uint8_t *, uint8_t); + result.elements[9U] = uu____20 | (int16_t)uu____21[0U] >> 3U; + int16_t uu____22 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)4U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)1) + << 10U; + int16_t uu____23 = + uu____22 | (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)3U, + uint8_t, uint8_t *, uint8_t) + << 2U; + uint8_t *uu____24 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)2U, + uint8_t, uint8_t *, uint8_t); + result.elements[10U] = uu____23 | (int16_t)uu____24[0U] >> 6U; + int16_t uu____25 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)5U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)15) + << 7U; + uint8_t *uu____26 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)4U, + uint8_t, uint8_t *, uint8_t); + result.elements[11U] = uu____25 | (int16_t)uu____26[0U] >> 1U; + int16_t uu____27 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)6U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)127) + << 4U; + uint8_t *uu____28 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)5U, + uint8_t, uint8_t *, uint8_t); + result.elements[12U] = uu____27 | (int16_t)uu____28[0U] >> 4U; + int16_t uu____29 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)8U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)3) + << 9U; + int16_t uu____30 = + uu____29 | (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)7U, + uint8_t, uint8_t *, uint8_t) + << 1U; + uint8_t *uu____31 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)6U, + uint8_t, uint8_t *, uint8_t); + result.elements[13U] = uu____30 | (int16_t)uu____31[0U] >> 7U; + int16_t uu____32 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)9U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)31) + << 6U; + uint8_t *uu____33 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)8U, + uint8_t, uint8_t *, uint8_t); + result.elements[14U] = uu____32 | (int16_t)uu____33[0U] >> 2U; + int16_t uu____34 = + (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)10U, uint8_t, + uint8_t *, uint8_t) + << 3U; + uint8_t *uu____35 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)9U, + uint8_t, uint8_t *, uint8_t); + result.elements[15U] = uu____34 | (int16_t)uu____35[0U] >> 5U; + return result; +} + +__attribute__((target("avx2"))) +static inline void libcrux_ml_kem_vector_avx2_portable_to_i16_array( + libcrux_ml_kem_vector_avx2_portable_PortableVector v, int16_t ret[16U]) { + memcpy(ret, v.elements, (size_t)16U * sizeof(int16_t)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_serialize_deserialize_11(Eurydice_slice bytes) { + libcrux_ml_kem_vector_avx2_portable_PortableVector output = + libcrux_ml_kem_vector_avx2_portable_deserialize_11(bytes); + int16_t ret[16U]; + libcrux_ml_kem_vector_avx2_portable_to_i16_array(output, ret); + return libcrux_ml_kem_vector_avx2_from_i16_array( + Eurydice_array_to_slice((size_t)16U, ret, int16_t, Eurydice_slice)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_11( + Eurydice_slice bytes) { + return libcrux_ml_kem_vector_avx2_serialize_deserialize_11(bytes); +} + +__attribute__((target("avx2"))) +static inline void libcrux_ml_kem_vector_avx2_serialize_serialize_12( + core_core_arch_x86___m256i vector, uint8_t ret[24U]) { + uint8_t serialized[32U] = {0U}; + core_core_arch_x86___m256i uu____0 = vector; + core_core_arch_x86___m256i adjacent_2_combined = + libcrux_intrinsics_avx2_mm256_madd_epi16( + uu____0, + libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 12U, (int16_t)1, (int16_t)1 << 12U, (int16_t)1, + (int16_t)1 << 12U, (int16_t)1, (int16_t)1 << 12U, (int16_t)1, + (int16_t)1 << 12U, (int16_t)1, (int16_t)1 << 12U, (int16_t)1, + (int16_t)1 << 12U, (int16_t)1, (int16_t)1 << 12U, (int16_t)1)); + core_core_arch_x86___m256i uu____1 = adjacent_2_combined; + core_core_arch_x86___m256i adjacent_4_combined = + libcrux_intrinsics_avx2_mm256_sllv_epi32( + uu____1, libcrux_intrinsics_avx2_mm256_set_epi32( + (int32_t)0, (int32_t)8, (int32_t)0, (int32_t)8, + (int32_t)0, (int32_t)8, (int32_t)0, (int32_t)8)); + core_core_arch_x86___m256i adjacent_4_combined0 = + libcrux_intrinsics_avx2_mm256_srli_epi64((int32_t)8, adjacent_4_combined, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____2 = adjacent_4_combined0; + core_core_arch_x86___m256i adjacent_8_combined = + libcrux_intrinsics_avx2_mm256_shuffle_epi8( + uu____2, libcrux_intrinsics_avx2_mm256_set_epi8( + (int8_t)-1, (int8_t)-1, (int8_t)-1, (int8_t)-1, + (int8_t)13, (int8_t)12, (int8_t)11, (int8_t)10, + (int8_t)9, (int8_t)8, (int8_t)5, (int8_t)4, (int8_t)3, + (int8_t)2, (int8_t)1, (int8_t)0, (int8_t)-1, (int8_t)-1, + (int8_t)-1, (int8_t)-1, (int8_t)13, (int8_t)12, + (int8_t)11, (int8_t)10, (int8_t)9, (int8_t)8, (int8_t)5, + (int8_t)4, (int8_t)3, (int8_t)2, (int8_t)1, (int8_t)0)); + core_core_arch_x86___m128i lower_8 = + libcrux_intrinsics_avx2_mm256_castsi256_si128(adjacent_8_combined); + core_core_arch_x86___m128i upper_8 = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, adjacent_8_combined, core_core_arch_x86___m128i); + libcrux_intrinsics_avx2_mm_storeu_bytes_si128( + Eurydice_array_to_subslice((size_t)32U, serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + lower_8); + libcrux_intrinsics_avx2_mm_storeu_bytes_si128( + Eurydice_array_to_subslice((size_t)32U, serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)12U, .end = (size_t)28U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + upper_8); + uint8_t ret0[24U]; + core_result_Result__uint8_t_24size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_array_to_subslice((size_t)32U, serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, uint8_t[24U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_24size_t__core_array_TryFromSliceError( + dst, ret0); + memcpy(ret, ret0, (size_t)24U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_12( + core_core_arch_x86___m256i vector, uint8_t ret[24U]) { + uint8_t ret0[24U]; + libcrux_ml_kem_vector_avx2_serialize_serialize_12(vector, ret0); + memcpy(ret, ret0, (size_t)24U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_serialize_deserialize_12(Eurydice_slice bytes) { + core_core_arch_x86___m256i shift_lsbs_to_msbs = + libcrux_intrinsics_avx2_mm256_set_epi16( + (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, + (int16_t)1 << 4U, (int16_t)1 << 0U, (int16_t)1 << 4U, + (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, + (int16_t)1 << 4U, (int16_t)1 << 0U, (int16_t)1 << 4U, + (int16_t)1 << 0U, (int16_t)1 << 4U, (int16_t)1 << 0U, + (int16_t)1 << 4U); + core_core_arch_x86___m128i lower_coefficients = + libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_slice_subslice( + bytes, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m128i uu____0 = lower_coefficients; + core_core_arch_x86___m128i lower_coefficients0 = + libcrux_intrinsics_avx2_mm_shuffle_epi8( + uu____0, + libcrux_intrinsics_avx2_mm_set_epi8(11U, 10U, 10U, 9U, 8U, 7U, 7U, 6U, + 5U, 4U, 4U, 3U, 2U, 1U, 1U, 0U)); + core_core_arch_x86___m128i upper_coefficients = + libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_slice_subslice( + bytes, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m128i uu____1 = upper_coefficients; + core_core_arch_x86___m128i upper_coefficients0 = + libcrux_intrinsics_avx2_mm_shuffle_epi8( + uu____1, libcrux_intrinsics_avx2_mm_set_epi8(15U, 14U, 14U, 13U, 12U, + 11U, 11U, 10U, 9U, 8U, + 8U, 7U, 6U, 5U, 5U, 4U)); + core_core_arch_x86___m256i coefficients = + libcrux_intrinsics_avx2_mm256_castsi128_si256(lower_coefficients0); + core_core_arch_x86___m256i coefficients0 = + libcrux_intrinsics_avx2_mm256_inserti128_si256( + (int32_t)1, coefficients, upper_coefficients0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i coefficients1 = + libcrux_intrinsics_avx2_mm256_mullo_epi16(coefficients0, + shift_lsbs_to_msbs); + core_core_arch_x86___m256i coefficients2 = + libcrux_intrinsics_avx2_mm256_srli_epi16((int32_t)4, coefficients1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____2 = coefficients2; + core_core_arch_x86___m256i coefficients3 = + libcrux_intrinsics_avx2_mm256_and_si256( + uu____2, libcrux_intrinsics_avx2_mm256_set1_epi16( + ((int16_t)1 << 12U) - (int16_t)1)); + return coefficients3; +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_12( + Eurydice_slice bytes) { + return libcrux_ml_kem_vector_avx2_serialize_deserialize_12(bytes); +} + +__attribute__((target("avx2"))) +static inline size_t libcrux_ml_kem_vector_avx2_sampling_rejection_sample( + Eurydice_slice input, Eurydice_slice output) { + core_core_arch_x86___m256i field_modulus = + libcrux_intrinsics_avx2_mm256_set1_epi16( + LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + core_core_arch_x86___m256i potential_coefficients = + libcrux_ml_kem_vector_avx2_serialize_deserialize_12(input); + core_core_arch_x86___m256i compare_with_field_modulus = + libcrux_intrinsics_avx2_mm256_cmpgt_epi16(field_modulus, + potential_coefficients); + uint8_t good[2U]; + libcrux_ml_kem_vector_avx2_serialize_serialize_1(compare_with_field_modulus, + good); + uint8_t lower_shuffles[16U]; + memcpy(lower_shuffles, + libcrux_ml_kem_vector_rej_sample_table_REJECTION_SAMPLE_SHUFFLE_TABLE[( + size_t)good[0U]], + (size_t)16U * sizeof(uint8_t)); + core_core_arch_x86___m128i lower_shuffles0 = + libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_array_to_slice( + (size_t)16U, lower_shuffles, uint8_t, Eurydice_slice)); + core_core_arch_x86___m128i lower_coefficients = + libcrux_intrinsics_avx2_mm256_castsi256_si128(potential_coefficients); + core_core_arch_x86___m128i lower_coefficients0 = + libcrux_intrinsics_avx2_mm_shuffle_epi8(lower_coefficients, + lower_shuffles0); + libcrux_intrinsics_avx2_mm_storeu_si128(output, lower_coefficients0); + size_t sampled_count = (size_t)core_num__u8_6__count_ones(good[0U]); + uint8_t upper_shuffles[16U]; + memcpy(upper_shuffles, + libcrux_ml_kem_vector_rej_sample_table_REJECTION_SAMPLE_SHUFFLE_TABLE[( + size_t)good[1U]], + (size_t)16U * sizeof(uint8_t)); + core_core_arch_x86___m128i upper_shuffles0 = + libcrux_intrinsics_avx2_mm_loadu_si128(Eurydice_array_to_slice( + (size_t)16U, upper_shuffles, uint8_t, Eurydice_slice)); + core_core_arch_x86___m128i upper_coefficients = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, potential_coefficients, core_core_arch_x86___m128i); + core_core_arch_x86___m128i upper_coefficients0 = + libcrux_intrinsics_avx2_mm_shuffle_epi8(upper_coefficients, + upper_shuffles0); + libcrux_intrinsics_avx2_mm_storeu_si128( + Eurydice_slice_subslice( + output, + (CLITERAL(core_ops_range_Range__size_t){ + .start = sampled_count, .end = sampled_count + (size_t)8U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice), + upper_coefficients0); + size_t uu____0 = sampled_count; + return uu____0 + (size_t)core_num__u8_6__count_ones(good[1U]); +} + +__attribute__((target("avx2"))) +static inline size_t +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( + Eurydice_slice input, Eurydice_slice output) { + return libcrux_ml_kem_vector_avx2_sampling_rejection_sample(input, output); +} + +typedef struct + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_s { + core_core_arch_x86___m256i coefficients[16U]; +} libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector; + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector( + void) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + lit; + lit.coefficients[0U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[1U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[2U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[3U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[4U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[5U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[6U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[7U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[8U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[9U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[10U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[11U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[12U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[13U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[14U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + lit.coefficients[15U] = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(); + return lit; +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_ind_cpa_deserialize_then_decompress_u_closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_10size_t( + size_t _) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_compress_decompress_ciphertext_coefficient___10int32_t( + core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus = + libcrux_intrinsics_avx2_mm256_set1_epi32( + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + core_core_arch_x86___m256i two_pow_coefficient_bits = + libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)1 + << (uint32_t)(int32_t)10); + core_core_arch_x86___m128i coefficients_low = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m256i coefficients_low0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); + core_core_arch_x86___m256i decompressed_low = + libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_low0, + field_modulus); + core_core_arch_x86___m256i decompressed_low0 = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_low, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_low1 = + libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_low0, + two_pow_coefficient_bits); + core_core_arch_x86___m256i decompressed_low2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)10, decompressed_low1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_low3 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_low2, + core_core_arch_x86___m256i); + core_core_arch_x86___m128i coefficients_high = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m256i coefficients_high0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); + core_core_arch_x86___m256i decompressed_high = + libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_high0, + field_modulus); + core_core_arch_x86___m256i decompressed_high0 = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_high, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_high1 = + libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_high0, + two_pow_coefficient_bits); + core_core_arch_x86___m256i decompressed_high2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)10, decompressed_high1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_high3 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_high2, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed = + libcrux_intrinsics_avx2_mm256_packs_epi32(decompressed_low3, + decompressed_high3); + return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, compressed, core_core_arch_x86___m256i); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___decompress_ciphertext_coefficient___10int32_t( + core_core_arch_x86___m256i vector) { + return libcrux_ml_kem_vector_avx2_compress_decompress_ciphertext_coefficient___10int32_t( + vector); +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_serialize_deserialize_then_decompress_10__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)20U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * (size_t)20U, .end = i0 * (size_t)20U + (size_t)20U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_core_arch_x86___m256i coefficient = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_10( + bytes); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___decompress_ciphertext_coefficient___10int32_t( + coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_compress_decompress_ciphertext_coefficient___11int32_t( + core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus = + libcrux_intrinsics_avx2_mm256_set1_epi32( + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + core_core_arch_x86___m256i two_pow_coefficient_bits = + libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)1 + << (uint32_t)(int32_t)11); + core_core_arch_x86___m128i coefficients_low = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m256i coefficients_low0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); + core_core_arch_x86___m256i decompressed_low = + libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_low0, + field_modulus); + core_core_arch_x86___m256i decompressed_low0 = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_low, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_low1 = + libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_low0, + two_pow_coefficient_bits); + core_core_arch_x86___m256i decompressed_low2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)11, decompressed_low1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_low3 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_low2, + core_core_arch_x86___m256i); + core_core_arch_x86___m128i coefficients_high = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m256i coefficients_high0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); + core_core_arch_x86___m256i decompressed_high = + libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_high0, + field_modulus); + core_core_arch_x86___m256i decompressed_high0 = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_high, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_high1 = + libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_high0, + two_pow_coefficient_bits); + core_core_arch_x86___m256i decompressed_high2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)11, decompressed_high1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_high3 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_high2, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed = + libcrux_intrinsics_avx2_mm256_packs_epi32(decompressed_low3, + decompressed_high3); + return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, compressed, core_core_arch_x86___m256i); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___decompress_ciphertext_coefficient___11int32_t( + core_core_arch_x86___m256i vector) { + return libcrux_ml_kem_vector_avx2_compress_decompress_ciphertext_coefficient___11int32_t( + vector); +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_serialize_deserialize_then_decompress_11__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)22U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * (size_t)22U, .end = i0 * (size_t)22U + (size_t)22U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_core_arch_x86___m256i coefficient = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_11( + bytes); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___decompress_ciphertext_coefficient___11int32_t( + coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0; + uu____0 = + libcrux_ml_kem_serialize_deserialize_then_decompress_10__libcrux_ml_kem_vector_avx2_SIMD256Vector( + serialized); + return uu____0; +} + +typedef struct + K___libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector_s { + core_core_arch_x86___m256i fst; + core_core_arch_x86___m256i snd; +} K___libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector; + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_traits_montgomery_multiply_fe__libcrux_ml_kem_vector_avx2_SIMD256Vector( + core_core_arch_x86___m256i v, int16_t fer) { + return libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( + v, fer); +} + +__attribute__((target("avx2"))) +static inline K___libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_ntt_ntt_layer_int_vec_step__libcrux_ml_kem_vector_avx2_SIMD256Vector( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b, + int16_t zeta_r) { + core_core_arch_x86___m256i t = + libcrux_ml_kem_vector_traits_montgomery_multiply_fe__libcrux_ml_kem_vector_avx2_SIMD256Vector( + b, zeta_r); + b = libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( + a, &t); + a = libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + a, &t); + return (CLITERAL( + K___libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector){ + .fst = a, .snd = b}); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + size_t layer, size_t _initial_coefficient_bound) { + size_t step = (size_t)1U << (uint32_t)layer; + for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { + size_t round = i0; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + size_t offset = round * step * (size_t)2U; + size_t offset_vec = offset / (size_t)16U; + size_t step_vec = step / (size_t)16U; + for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { + size_t j = i; + K___libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + libcrux_ml_kem_ntt_ntt_layer_int_vec_step__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re->coefficients[j], re->coefficients[j + step_vec], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R + [zeta_i[0U]]); + core_core_arch_x86___m256i x = uu____0.fst; + core_core_arch_x86___m256i y = uu____0.snd; + re->coefficients[j] = x; + re->coefficients[j + step_vec] = y; + } + } +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_ntt_ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + size_t _layer, size_t _initial_coefficient_bound) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_3_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + re->coefficients[round] = uu____0;); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_ntt_ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + size_t _layer, size_t _initial_coefficient_bound) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_2_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)1U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] + (size_t)1U;); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_ntt_ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + size_t _layer, size_t _initial_coefficient_bound) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_layer_1_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)3U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] + (size_t)3U;); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *self) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( + self->coefficients[i0]); + self->coefficients[i0] = uu____0; + } +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_ntt_ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + size_t zeta_i = (size_t)0U; + libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)7U, (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)6U, (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)5U, (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)4U, (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)3U, (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)2U, (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)1U, (size_t)3328U); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_ind_cpa_deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_10size_t( + uint8_t *ciphertext, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + u_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + u_as_ntt[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len( + Eurydice_array_to_slice((size_t)1088U, ciphertext, uint8_t, + Eurydice_slice), + uint8_t, size_t) / + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U); + i++) { + size_t i0 = i; + Eurydice_slice u_bytes = Eurydice_array_to_subslice( + (size_t)1088U, ciphertext, + (CLITERAL(core_ops_range_Range__size_t){ + .start = + i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U), + .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U) + + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( + u_bytes); + u_as_ntt[i0] = uu____0; + libcrux_ml_kem_ntt_ntt_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t( + &u_as_ntt[i0]); + } + memcpy( + ret, u_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_compress_decompress_ciphertext_coefficient___4int32_t( + core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus = + libcrux_intrinsics_avx2_mm256_set1_epi32( + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + core_core_arch_x86___m256i two_pow_coefficient_bits = + libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)1 + << (uint32_t)(int32_t)4); + core_core_arch_x86___m128i coefficients_low = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m256i coefficients_low0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); + core_core_arch_x86___m256i decompressed_low = + libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_low0, + field_modulus); + core_core_arch_x86___m256i decompressed_low0 = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_low, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_low1 = + libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_low0, + two_pow_coefficient_bits); + core_core_arch_x86___m256i decompressed_low2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)4, decompressed_low1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_low3 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_low2, + core_core_arch_x86___m256i); + core_core_arch_x86___m128i coefficients_high = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m256i coefficients_high0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); + core_core_arch_x86___m256i decompressed_high = + libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_high0, + field_modulus); + core_core_arch_x86___m256i decompressed_high0 = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_high, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_high1 = + libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_high0, + two_pow_coefficient_bits); + core_core_arch_x86___m256i decompressed_high2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)4, decompressed_high1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_high3 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_high2, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed = + libcrux_intrinsics_avx2_mm256_packs_epi32(decompressed_low3, + decompressed_high3); + return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, compressed, core_core_arch_x86___m256i); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___decompress_ciphertext_coefficient___4int32_t( + core_core_arch_x86___m256i vector) { + return libcrux_ml_kem_vector_avx2_compress_decompress_ciphertext_coefficient___4int32_t( + vector); +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_serialize_deserialize_then_decompress_4__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)8U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * (size_t)8U, .end = i0 * (size_t)8U + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_core_arch_x86___m256i coefficient = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_4( + bytes); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___decompress_ciphertext_coefficient___4int32_t( + coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_compress_decompress_ciphertext_coefficient___5int32_t( + core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus = + libcrux_intrinsics_avx2_mm256_set1_epi32( + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + core_core_arch_x86___m256i two_pow_coefficient_bits = + libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)1 + << (uint32_t)(int32_t)5); + core_core_arch_x86___m128i coefficients_low = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m256i coefficients_low0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); + core_core_arch_x86___m256i decompressed_low = + libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_low0, + field_modulus); + core_core_arch_x86___m256i decompressed_low0 = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_low, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_low1 = + libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_low0, + two_pow_coefficient_bits); + core_core_arch_x86___m256i decompressed_low2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)5, decompressed_low1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_low3 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_low2, + core_core_arch_x86___m256i); + core_core_arch_x86___m128i coefficients_high = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m256i coefficients_high0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); + core_core_arch_x86___m256i decompressed_high = + libcrux_intrinsics_avx2_mm256_mullo_epi32(coefficients_high0, + field_modulus); + core_core_arch_x86___m256i decompressed_high0 = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)1, decompressed_high, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_high1 = + libcrux_intrinsics_avx2_mm256_add_epi32(decompressed_high0, + two_pow_coefficient_bits); + core_core_arch_x86___m256i decompressed_high2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)5, decompressed_high1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i decompressed_high3 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)1, decompressed_high2, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed = + libcrux_intrinsics_avx2_mm256_packs_epi32(decompressed_low3, + decompressed_high3); + return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, compressed, core_core_arch_x86___m256i); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___decompress_ciphertext_coefficient___5int32_t( + core_core_arch_x86___m256i vector) { + return libcrux_ml_kem_vector_avx2_compress_decompress_ciphertext_coefficient___5int32_t( + vector); +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_serialize_deserialize_then_decompress_5__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)10U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * (size_t)10U, .end = i0 * (size_t)10U + (size_t)10U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_5( + bytes); + re.coefficients[i0] = uu____0; + core_core_arch_x86___m256i uu____1 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___decompress_ciphertext_coefficient___5int32_t( + re.coefficients[i0]); + re.coefficients[i0] = uu____1; + } + return re; +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0; + uu____0 = + libcrux_ml_kem_serialize_deserialize_then_decompress_4__libcrux_ml_kem_vector_avx2_SIMD256Vector( + serialized); + return uu____0; +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_ind_cpa_deserialize_secret_key_closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + size_t _) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_serialize_deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * (size_t)24U, .end = i0 * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_12( + bytes); + re.coefficients[i0] = uu____0; + } + return re; +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_ind_cpa_deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + Eurydice_slice secret_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + secret_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + secret_as_ntt[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice secret_bytes = Eurydice_slice_subslice( + secret_key, + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + libcrux_ml_kem_serialize_deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + secret_bytes); + secret_as_ntt[i0] = uu____0; + } + memcpy( + ret, secret_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *rhs) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + out = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ntt_multiply( + &self->coefficients[i0], &rhs->coefficients[i0], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0 + + (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0 + + (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0 + + (size_t)3U]); + out.coefficients[i0] = uu____0; + } + return out; +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *rhs) { + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice((size_t)16U, self->coefficients, + core_core_arch_x86___m256i, Eurydice_slice), + core_core_arch_x86___m256i, size_t); + i++) { + size_t i0 = i; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + self->coefficients[i0], &rhs->coefficients[i0]); + self->coefficients[i0] = uu____0; + } +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + size_t _layer) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_1_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)3U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] - (size_t)3U;); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + size_t _layer) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_2_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)1U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] - (size_t)1U;); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + size_t _layer) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___inv_ntt_layer_3_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + re->coefficients[round] = uu____0;); +} + +__attribute__((target("avx2"))) +static inline K___libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_invert_ntt_inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b, + int16_t zeta_r) { + core_core_arch_x86___m256i a_minus_b = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( + b, &a); + a = libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + a, &b)); + b = libcrux_ml_kem_vector_traits_montgomery_multiply_fe__libcrux_ml_kem_vector_avx2_SIMD256Vector( + a_minus_b, zeta_r); + return (CLITERAL( + K___libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector){ + .fst = a, .snd = b}); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + size_t layer) { + size_t step = (size_t)1U << (uint32_t)layer; + for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { + size_t round = i0; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + size_t offset = round * step * (size_t)2U; + size_t offset_vec = + offset / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; + size_t step_vec = + step / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; + for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { + size_t j = i; + K___libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + libcrux_ml_kem_invert_ntt_inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re->coefficients[j], re->coefficients[j + step_vec], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R + [zeta_i[0U]]); + core_core_arch_x86___m256i x = uu____0.fst; + core_core_arch_x86___m256i y = uu____0.snd; + re->coefficients[j] = x; + re->coefficients[j + step_vec] = y; + } + } +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_invert_ntt_invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + size_t zeta_i = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)1U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)2U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)3U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)4U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)5U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)6U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)7U); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re); +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___subtract_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + b) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i coefficient_normal_form = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( + b.coefficients[i0], (int16_t)1441); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( + self->coefficients[i0], &coefficient_normal_form)); + b.coefficients[i0] = uu____0; + } + return b; +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_matrix_compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *v, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *secret_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *u_as_ntt) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &secret_as_ntt[i0], &u_as_ntt[i0]); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + &result, &product);); + libcrux_ml_kem_invert_ntt_invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + &result); + result = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___subtract_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + v, result); + return result; +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_arithmetic_shift_right___15int32_t( + core_core_arch_x86___m256i vector) { + return libcrux_intrinsics_avx2_mm256_srai_epi16((int32_t)15, vector, + core_core_arch_x86___m256i); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___shift_right___15int32_t( + core_core_arch_x86___m256i vector) { + return libcrux_ml_kem_vector_avx2_arithmetic_shift_right___15int32_t(vector); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( + core_core_arch_x86___m256i a) { + core_core_arch_x86___m256i t = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___shift_right___15int32_t( + a); + core_core_arch_x86___m256i fm = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___bitwise_and_with_constant( + t, LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + return libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + a, &fm); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_serialize_compress_then_serialize_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re, + uint8_t ret[32U]) { + uint8_t serialized[32U] = {0U}; + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t i0 = i; + core_core_arch_x86___m256i coefficient = + libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re.coefficients[i0]); + core_core_arch_x86___m256i coefficient_compressed = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___compress_1( + coefficient); + uint8_t bytes[2U]; + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_1( + coefficient_compressed, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)32U, serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)2U * i0, .end = (size_t)2U * i0 + (size_t)2U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)2U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *);); + memcpy(ret, serialized, (size_t)32U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_ind_cpa_decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_960size_t_10size_t_4size_t( + Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + u_as_ntt[3U]; + libcrux_ml_kem_ind_cpa_deserialize_then_decompress_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_10size_t( + ciphertext, u_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + v = libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t( + Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, + (size_t)960U, uint8_t, size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + secret_as_ntt[3U]; + libcrux_ml_kem_ind_cpa_deserialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + secret_key, secret_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + message = + libcrux_ml_kem_matrix_compute_message__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + &v, secret_as_ntt, u_as_ntt); + uint8_t ret0[32U]; + libcrux_ml_kem_serialize_compress_then_serialize_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( + message, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_hash_functions_avx2___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__avx2__Simd256Hash___G___3size_t( + Eurydice_slice input, uint8_t ret[64U]) { + uint8_t digest[64U] = {0U}; + libcrux_sha3_portable_sha512( + Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_hash_functions_avx2___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__avx2__Simd256Hash___PRF___3size_t_32size_t( + Eurydice_slice input, uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152size_t_3size_t( + size_t _i) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * (size_t)24U, .end = i0 * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_core_arch_x86___m256i coefficient = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_12( + bytes); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___cond_subtract_3329( + coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_serialize_deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152size_t_3size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + deserialized_pk[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + deserialized_pk[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_matrix_sample_matrix_A_closure_closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + size_t _j) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_matrix_sample_matrix_A_closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + size_t _i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret0[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + ret0[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + memcpy( + ret, ret0, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +typedef libcrux_sha3_avx2_x4_incremental_KeccakState4 + libcrux_ml_kem_hash_functions_avx2_Simd256Hash; + +__attribute__((target("avx2"))) +static inline libcrux_sha3_avx2_x4_incremental_KeccakState4 +libcrux_ml_kem_hash_functions_avx2___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__avx2__Simd256Hash___shake128_init_absorb___3size_t( + uint8_t input[3U][34U]) { + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + state = libcrux_sha3_avx2_x4_incremental_shake128_init(); + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *uu____0 = &state; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)34U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)34U, input[2U], uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( + uu____0, uu____1, uu____2, uu____3, + Eurydice_array_to_slice((size_t)34U, input[0U], uint8_t, Eurydice_slice)); + return state; +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_hash_functions_avx2___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__avx2__Simd256Hash___shake128_squeeze_three_blocks___3size_t( + libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, + uint8_t ret[3U][504U]) { + uint8_t out[3U][504U] = {{0U}}; + uint8_t out0[504U] = {0U}; + uint8_t out1[504U] = {0U}; + uint8_t out2[504U] = {0U}; + uint8_t out3[504U] = {0U}; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *uu____0 = self; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)504U, out0, uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)504U, out1, uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)504U, out2, uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( + uu____0, uu____1, uu____2, uu____3, + Eurydice_array_to_slice((size_t)504U, out3, uint8_t, Eurydice_slice)); + uint8_t uu____4[504U]; + memcpy(uu____4, out0, (size_t)504U * sizeof(uint8_t)); + memcpy(out[0U], uu____4, (size_t)504U * sizeof(uint8_t)); + uint8_t uu____5[504U]; + memcpy(uu____5, out1, (size_t)504U * sizeof(uint8_t)); + memcpy(out[1U], uu____5, (size_t)504U * sizeof(uint8_t)); + uint8_t uu____6[504U]; + memcpy(uu____6, out2, (size_t)504U * sizeof(uint8_t)); + memcpy(out[2U], uu____6, (size_t)504U * sizeof(uint8_t)); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[504U])); +} + +__attribute__((target("avx2"))) +static inline bool +libcrux_ml_kem_sampling_sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_504size_t( + uint8_t randomness[3U][504U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)504U, randomness[i1], + (CLITERAL(core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + (CLITERAL(core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); + return done; +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_hash_functions_avx2___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__avx2__Simd256Hash___shake128_squeeze_block___3size_t( + libcrux_sha3_avx2_x4_incremental_KeccakState4 *self, + uint8_t ret[3U][168U]) { + uint8_t out[3U][168U] = {{0U}}; + uint8_t out0[168U] = {0U}; + uint8_t out1[168U] = {0U}; + uint8_t out2[168U] = {0U}; + uint8_t out3[168U] = {0U}; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *uu____0 = self; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)168U, out0, uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)168U, out1, uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)168U, out2, uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( + uu____0, uu____1, uu____2, uu____3, + Eurydice_array_to_slice((size_t)168U, out3, uint8_t, Eurydice_slice)); + uint8_t uu____4[168U]; + memcpy(uu____4, out0, (size_t)168U * sizeof(uint8_t)); + memcpy(out[0U], uu____4, (size_t)168U * sizeof(uint8_t)); + uint8_t uu____5[168U]; + memcpy(uu____5, out1, (size_t)168U * sizeof(uint8_t)); + memcpy(out[1U], uu____5, (size_t)168U * sizeof(uint8_t)); + uint8_t uu____6[168U]; + memcpy(uu____6, out2, (size_t)168U * sizeof(uint8_t)); + memcpy(out[2U], uu____6, (size_t)168U * sizeof(uint8_t)); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[168U])); +} + +__attribute__((target("avx2"))) +static inline bool +libcrux_ml_kem_sampling_sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_168size_t( + uint8_t randomness[3U][168U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)168U, randomness[i1], + (CLITERAL(core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + (CLITERAL(core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); + return done; +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_slice a) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___from_i16_array( + Eurydice_slice_subslice( + a, + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * (size_t)16U, + .end = (i0 + (size_t)1U) * (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + result.coefficients[i0] = uu____0; + } + return result; +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_sampling_sample_from_xof_closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + int16_t s[272U]) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_array_to_subslice((size_t)272U, s, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)256U}), + int16_t, core_ops_range_Range__size_t, + Eurydice_slice)); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_sampling_sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + uint8_t seeds[3U][34U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[3U]) { + size_t sampled_coefficients[3U] = {0U}; + int16_t out[3U][272U] = {{0U}}; + uint8_t uu____0[3U][34U]; + memcpy(uu____0, seeds, (size_t)3U * sizeof(uint8_t[34U])); + libcrux_sha3_avx2_x4_incremental_KeccakState4 xof_state = + libcrux_ml_kem_hash_functions_avx2___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__avx2__Simd256Hash___shake128_init_absorb___3size_t( + uu____0); + uint8_t randomness0[3U][504U]; + libcrux_ml_kem_hash_functions_avx2___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__avx2__Simd256Hash___shake128_squeeze_three_blocks___3size_t( + &xof_state, randomness0); + uint8_t uu____1[3U][504U]; + memcpy(uu____1, randomness0, (size_t)3U * sizeof(uint8_t[504U])); + bool done = + libcrux_ml_kem_sampling_sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_504size_t( + uu____1, sampled_coefficients, out); + while (true) { + if (done) { + break; + } else { + uint8_t randomness[3U][168U]; + libcrux_ml_kem_hash_functions_avx2___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__avx2__Simd256Hash___shake128_squeeze_block___3size_t( + &xof_state, randomness); + uint8_t uu____2[3U][168U]; + memcpy(uu____2, randomness, (size_t)3U * sizeof(uint8_t[168U])); + done = + libcrux_ml_kem_sampling_sample_from_uniform_distribution_next__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_168size_t( + uu____2, sampled_coefficients, out); + } + } + int16_t uu____3[3U][272U]; + memcpy(uu____3, out, (size_t)3U * sizeof(int16_t[272U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret0[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + ret0[i] = + libcrux_ml_kem_sampling_sample_from_xof_closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + uu____3[i]);); + memcpy( + ret, ret0, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_matrix_sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + uint8_t seed[34U], bool transpose, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[3U][3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + A_transpose[3U][3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + libcrux_ml_kem_matrix_sample_matrix_A_closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + i, A_transpose[i]);); + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + uint8_t uu____0[34U]; + memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); + uint8_t seeds[3U][34U]; KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t j = i; + seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); + uint8_t uu____1[3U][34U]; + memcpy(uu____1, seeds, (size_t)3U * sizeof(uint8_t[34U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + sampled[3U]; + libcrux_ml_kem_sampling_sample_from_xof__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + uu____1, sampled); + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, sampled, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + sample = sampled[j]; + if (transpose) { + A_transpose[j][i1] = sample; + } else { + A_transpose[i1][j] = sample; + } + }); + memcpy( + ret, A_transpose, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [3U])); +} + +typedef struct + K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t_s { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + fst[3U]; + uint8_t snd; +} K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t; + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( + size_t _i) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_hash_functions_avx2___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__avx2__Simd256Hash___PRFxN___3size_t_128size_t( + uint8_t (*input)[33U], uint8_t ret[3U][128U]) { + uint8_t out[3U][128U] = {{0U}}; + uint8_t out0[128U] = {0U}; + uint8_t out1[128U] = {0U}; + uint8_t out2[128U] = {0U}; + uint8_t out3[128U] = {0U}; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)33U, input[1U], uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)33U, input[2U], uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)33U, input[0U], uint8_t, Eurydice_slice); + Eurydice_slice uu____4 = + Eurydice_array_to_slice((size_t)128U, out0, uint8_t, Eurydice_slice); + Eurydice_slice uu____5 = + Eurydice_array_to_slice((size_t)128U, out1, uint8_t, Eurydice_slice); + Eurydice_slice uu____6 = + Eurydice_array_to_slice((size_t)128U, out2, uint8_t, Eurydice_slice); + libcrux_sha3_avx2_x4_shake256( + uu____0, uu____1, uu____2, uu____3, uu____4, uu____5, uu____6, + Eurydice_array_to_slice((size_t)128U, out3, uint8_t, Eurydice_slice)); + uint8_t uu____7[128U]; + memcpy(uu____7, out0, (size_t)128U * sizeof(uint8_t)); + memcpy(out[0U], uu____7, (size_t)128U * sizeof(uint8_t)); + uint8_t uu____8[128U]; + memcpy(uu____8, out1, (size_t)128U * sizeof(uint8_t)); + memcpy(out[1U], uu____8, (size_t)128U * sizeof(uint8_t)); + uint8_t uu____9[128U]; + memcpy(uu____9, out2, (size_t)128U * sizeof(uint8_t)); + memcpy(out[2U], uu____9, (size_t)128U * sizeof(uint8_t)); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[128U])); +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_sampling_sample_from_binomial_distribution_2__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_slice randomness) { + int16_t sampled_i16s[256U] = {0U}; + for (size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)4U; + i0++) { + size_t chunk_number = i0; + Eurydice_slice byte_chunk = Eurydice_slice_subslice( + randomness, + (CLITERAL(core_ops_range_Range__size_t){ + .start = chunk_number * (size_t)4U, + .end = chunk_number * (size_t)4U + (size_t)4U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint32_t uu____0 = (uint32_t)Eurydice_slice_index( + byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); + uint32_t uu____1 = + uu____0 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, + uint8_t, uint8_t *, uint8_t) + << 8U; + uint32_t uu____2 = + uu____1 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, + uint8_t, uint8_t *, uint8_t) + << 16U; + uint32_t random_bits_as_u32 = + uu____2 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)3U, + uint8_t, uint8_t *, uint8_t) + << 24U; + uint32_t even_bits = random_bits_as_u32 & 1431655765U; + uint32_t odd_bits = random_bits_as_u32 >> 1U & 1431655765U; + uint32_t coin_toss_outcomes = even_bits + odd_bits; + for (uint32_t i = 0U; i < CORE_NUM__U32_8__BITS / 4U; i++) { + uint32_t outcome_set = i; + uint32_t outcome_set0 = outcome_set * 4U; + int16_t outcome_1 = + (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 3U); + int16_t outcome_2 = + (int16_t)(coin_toss_outcomes >> (uint32_t)(outcome_set0 + 2U) & 3U); + size_t offset = (size_t)(outcome_set0 >> 2U); + sampled_i16s[(size_t)8U * chunk_number + offset] = outcome_1 - outcome_2; + } + } + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t, + Eurydice_slice)); +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_sampling_sample_from_binomial_distribution_3__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_slice randomness) { + int16_t sampled_i16s[256U] = {0U}; + for (size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)3U; + i0++) { + size_t chunk_number = i0; + Eurydice_slice byte_chunk = Eurydice_slice_subslice( + randomness, + (CLITERAL(core_ops_range_Range__size_t){ + .start = chunk_number * (size_t)3U, + .end = chunk_number * (size_t)3U + (size_t)3U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint32_t uu____0 = (uint32_t)Eurydice_slice_index( + byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); + uint32_t uu____1 = + uu____0 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, + uint8_t, uint8_t *, uint8_t) + << 8U; + uint32_t random_bits_as_u24 = + uu____1 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, + uint8_t, uint8_t *, uint8_t) + << 16U; + uint32_t first_bits = random_bits_as_u24 & 2396745U; + uint32_t second_bits = random_bits_as_u24 >> 1U & 2396745U; + uint32_t third_bits = random_bits_as_u24 >> 2U & 2396745U; + uint32_t coin_toss_outcomes = first_bits + second_bits + third_bits; + for (int32_t i = (int32_t)0; i < (int32_t)24 / (int32_t)6; i++) { + int32_t outcome_set = i; + int32_t outcome_set0 = outcome_set * (int32_t)6; + int16_t outcome_1 = + (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 7U); + int16_t outcome_2 = (int16_t)(coin_toss_outcomes >> + (uint32_t)(outcome_set0 + (int32_t)3) & + 7U); + size_t offset = (size_t)(outcome_set0 / (int32_t)6); + sampled_i16s[(size_t)4U * chunk_number + offset] = outcome_1 - outcome_2; + } + } + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___from_i16_array__libcrux_ml_kem_vector_avx2_SIMD256Vector( + Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t, + Eurydice_slice)); +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + Eurydice_slice randomness) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0; + uu____0 = + libcrux_ml_kem_sampling_sample_from_binomial_distribution_2__libcrux_ml_kem_vector_avx2_SIMD256Vector( + randomness); + return uu____0; +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_ntt_ntt_at_layer_7__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + size_t step = LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT / (size_t)2U; + for (size_t i = (size_t)0U; i < step; i++) { + size_t j = i; + core_core_arch_x86___m256i t = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___multiply_by_constant( + re->coefficients[j + step], (int16_t)-1600); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( + re->coefficients[j], &t); + re->coefficients[j + step] = uu____0; + core_core_arch_x86___m256i uu____1 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + re->coefficients[j], &t); + re->coefficients[j] = uu____1; + } +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_ntt_ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re) { + libcrux_ml_kem_ntt_ntt_at_layer_7__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re); + size_t zeta_i = (size_t)1U; + libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)6U, (size_t)3U); + libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)5U, (size_t)3U); + libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)4U, (size_t)3U); + libcrux_ml_kem_ntt_ntt_at_layer_3__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)3U, (size_t)3U); + libcrux_ml_kem_ntt_ntt_at_layer_2__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)2U, (size_t)3U); + libcrux_ml_kem_ntt_ntt_at_layer_1__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &zeta_i, re, (size_t)1U, (size_t)3U); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___poly_barrett_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re); +} + +__attribute__((target("avx2"))) +static inline K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t +libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + re_as_ntt[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[3U][33U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[3U][128U]; + libcrux_ml_kem_hash_functions_avx2___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__avx2__Simd256Hash___PRFxN___3size_t_128size_t( + prf_inputs, prf_outputs); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____1 = + libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + re_as_ntt[i0] = uu____1; + libcrux_ml_kem_ntt_ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &re_as_ntt[i0]);); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____2[3U]; + memcpy( + uu____2, re_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t + lit; + memcpy( + lit.fst, uu____2, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + lit.snd = domain_separator; + return lit; +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_ind_cpa_sample_ring_element_cbd_closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_128size_t_2size_t( + size_t _i) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +__attribute__((target("avx2"))) +static inline K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t +libcrux_ml_kem_ind_cpa_sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_128size_t_2size_t( + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_1[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + error_1[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[3U][33U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[3U][128U]; + libcrux_ml_kem_hash_functions_avx2___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__avx2__Simd256Hash___PRFxN___3size_t_128size_t( + prf_inputs, prf_outputs); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____1 = + libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + error_1[i0] = uu____1;); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____2[3U]; + memcpy( + uu____2, error_1, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t + lit; + memcpy( + lit.fst, uu____2, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + lit.snd = domain_separator; + return lit; +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_hash_functions_avx2___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__avx2__Simd256Hash___PRF___3size_t_128size_t( + Eurydice_slice input, uint8_t ret[128U]) { + uint8_t digest[128U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_matrix_compute_vector_u_closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + size_t _i) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *error) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t j = i; + core_core_arch_x86___m256i coefficient_normal_form = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( + self->coefficients[j], (int16_t)1441); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + coefficient_normal_form, &error->coefficients[j])); + self->coefficients[j] = uu____0; + } +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_matrix_compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( + *a_as_ntt)[3U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *error_1, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + result[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, a_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [3U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [3U], + size_t); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *row = a_as_ntt[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *a_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + a_element, &r_as_ntt[j]); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + &result[i1], &product); + } + libcrux_ml_kem_invert_ntt_invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + &result[i1]); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &result[i1], &error_1[i1]); + } + memcpy( + ret, result, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_traits_decompress_1__libcrux_ml_kem_vector_avx2_SIMD256Vector( + core_core_arch_x86___m256i v) { + return libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___bitwise_and_with_constant( + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___sub( + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___ZERO(), + &v), + (int16_t)1665); +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_serialize_deserialize_then_decompress_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( + uint8_t serialized[32U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t i0 = i; + core_core_arch_x86___m256i coefficient_compressed = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___deserialize_1( + Eurydice_array_to_subslice( + (size_t)32U, serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)2U * i0, + .end = (size_t)2U * i0 + (size_t)2U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_traits_decompress_1__libcrux_ml_kem_vector_avx2_SIMD256Vector( + coefficient_compressed); + re.coefficients[i0] = uu____0;); + return re; +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_message_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *message, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i coefficient_normal_form = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( + result.coefficients[i0], (int16_t)1441); + core_core_arch_x86___m256i tmp = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + self->coefficients[i0], &message->coefficients[i0]); + core_core_arch_x86___m256i tmp0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + coefficient_normal_form, &tmp); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( + tmp0); + result.coefficients[i0] = uu____0; + } + return result; +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_matrix_compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *t_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *error_2, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *message) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &t_as_ntt[i0], &r_as_ntt[i0]); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + &result, &product);); + libcrux_ml_kem_invert_ntt_invert_ntt_montgomery__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + &result); + result = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_message_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + error_2, message, result); + return result; +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_compress_compress_ciphertext_coefficient___10int32_t( + core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus_halved = + libcrux_intrinsics_avx2_mm256_set1_epi32( + ((int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int32_t)1) / + (int32_t)2); + core_core_arch_x86___m256i compression_factor = + libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)10321340); + core_core_arch_x86___m256i coefficient_bits_mask = + libcrux_intrinsics_avx2_mm256_set1_epi32( + ((int32_t)1 << (uint32_t)(int32_t)10) - (int32_t)1); + core_core_arch_x86___m128i coefficients_low = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m256i coefficients_low0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); + core_core_arch_x86___m256i compressed_low = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)10, coefficients_low0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_low0 = + libcrux_intrinsics_avx2_mm256_add_epi32(compressed_low, + field_modulus_halved); + core_core_arch_x86___m256i compressed_low1 = + libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_low0, + compression_factor); + core_core_arch_x86___m256i compressed_low2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_low1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_low3 = + libcrux_intrinsics_avx2_mm256_and_si256(compressed_low2, + coefficient_bits_mask); + core_core_arch_x86___m128i coefficients_high = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m256i coefficients_high0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); + core_core_arch_x86___m256i compressed_high = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)10, coefficients_high0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_high0 = + libcrux_intrinsics_avx2_mm256_add_epi32(compressed_high, + field_modulus_halved); + core_core_arch_x86___m256i compressed_high1 = + libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_high0, + compression_factor); + core_core_arch_x86___m256i compressed_high2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_high1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_high3 = + libcrux_intrinsics_avx2_mm256_and_si256(compressed_high2, + coefficient_bits_mask); + core_core_arch_x86___m256i compressed = + libcrux_intrinsics_avx2_mm256_packs_epi32(compressed_low3, + compressed_high3); + return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, compressed, core_core_arch_x86___m256i); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___compress___10int32_t( + core_core_arch_x86___m256i vector) { + return libcrux_ml_kem_vector_avx2_compress_compress_ciphertext_coefficient___10int32_t( + vector); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_serialize_compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + uint8_t ret[320U]) { + uint8_t serialized[320U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i coefficient = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___compress___10int32_t( + libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re->coefficients[i0])); + uint8_t bytes[20U]; + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_10( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)320U, serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)20U * i0, .end = (size_t)20U * i0 + (size_t)20U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_compress_compress_ciphertext_coefficient___11int32_t( + core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus_halved = + libcrux_intrinsics_avx2_mm256_set1_epi32( + ((int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int32_t)1) / + (int32_t)2); + core_core_arch_x86___m256i compression_factor = + libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)10321340); + core_core_arch_x86___m256i coefficient_bits_mask = + libcrux_intrinsics_avx2_mm256_set1_epi32( + ((int32_t)1 << (uint32_t)(int32_t)11) - (int32_t)1); + core_core_arch_x86___m128i coefficients_low = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m256i coefficients_low0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); + core_core_arch_x86___m256i compressed_low = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)11, coefficients_low0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_low0 = + libcrux_intrinsics_avx2_mm256_add_epi32(compressed_low, + field_modulus_halved); + core_core_arch_x86___m256i compressed_low1 = + libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_low0, + compression_factor); + core_core_arch_x86___m256i compressed_low2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_low1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_low3 = + libcrux_intrinsics_avx2_mm256_and_si256(compressed_low2, + coefficient_bits_mask); + core_core_arch_x86___m128i coefficients_high = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m256i coefficients_high0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); + core_core_arch_x86___m256i compressed_high = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)11, coefficients_high0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_high0 = + libcrux_intrinsics_avx2_mm256_add_epi32(compressed_high, + field_modulus_halved); + core_core_arch_x86___m256i compressed_high1 = + libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_high0, + compression_factor); + core_core_arch_x86___m256i compressed_high2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_high1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_high3 = + libcrux_intrinsics_avx2_mm256_and_si256(compressed_high2, + coefficient_bits_mask); + core_core_arch_x86___m256i compressed = + libcrux_intrinsics_avx2_mm256_packs_epi32(compressed_low3, + compressed_high3); + return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, compressed, core_core_arch_x86___m256i); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___compress___11int32_t( + core_core_arch_x86___m256i vector) { + return libcrux_ml_kem_vector_avx2_compress_compress_ciphertext_coefficient___11int32_t( + vector); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_serialize_compress_then_serialize_11__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + uint8_t ret[320U]) { + uint8_t serialized[320U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i coefficient = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___compress___11int32_t( + libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re->coefficients[i0])); + uint8_t bytes[22U]; + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_11( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)320U, serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)22U * i0, .end = (size_t)22U * i0 + (size_t)22U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_serialize_compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + uint8_t ret[320U]) { + uint8_t uu____0[320U]; + libcrux_ml_kem_serialize_compress_then_serialize_10__libcrux_ml_kem_vector_avx2_SIMD256Vector_320size_t( + re, uu____0); + memcpy(ret, uu____0, (size_t)320U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_ind_cpa_compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_960size_t_10size_t_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + input[3U], + Eurydice_slice out) { + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, input, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = input[i0]; + Eurydice_slice uu____0 = Eurydice_slice_subslice( + out, + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * ((size_t)960U / (size_t)3U), + .end = (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret[320U]; + libcrux_ml_kem_serialize_compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_10size_t_320size_t( + &re, ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_compress_compress_ciphertext_coefficient___4int32_t( + core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus_halved = + libcrux_intrinsics_avx2_mm256_set1_epi32( + ((int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int32_t)1) / + (int32_t)2); + core_core_arch_x86___m256i compression_factor = + libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)10321340); + core_core_arch_x86___m256i coefficient_bits_mask = + libcrux_intrinsics_avx2_mm256_set1_epi32( + ((int32_t)1 << (uint32_t)(int32_t)4) - (int32_t)1); + core_core_arch_x86___m128i coefficients_low = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m256i coefficients_low0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); + core_core_arch_x86___m256i compressed_low = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)4, coefficients_low0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_low0 = + libcrux_intrinsics_avx2_mm256_add_epi32(compressed_low, + field_modulus_halved); + core_core_arch_x86___m256i compressed_low1 = + libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_low0, + compression_factor); + core_core_arch_x86___m256i compressed_low2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_low1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_low3 = + libcrux_intrinsics_avx2_mm256_and_si256(compressed_low2, + coefficient_bits_mask); + core_core_arch_x86___m128i coefficients_high = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m256i coefficients_high0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); + core_core_arch_x86___m256i compressed_high = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)4, coefficients_high0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_high0 = + libcrux_intrinsics_avx2_mm256_add_epi32(compressed_high, + field_modulus_halved); + core_core_arch_x86___m256i compressed_high1 = + libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_high0, + compression_factor); + core_core_arch_x86___m256i compressed_high2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_high1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_high3 = + libcrux_intrinsics_avx2_mm256_and_si256(compressed_high2, + coefficient_bits_mask); + core_core_arch_x86___m256i compressed = + libcrux_intrinsics_avx2_mm256_packs_epi32(compressed_low3, + compressed_high3); + return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, compressed, core_core_arch_x86___m256i); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___compress___4int32_t( + core_core_arch_x86___m256i vector) { + return libcrux_ml_kem_vector_avx2_compress_compress_ciphertext_coefficient___4int32_t( + vector); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_serialize_compress_then_serialize_4__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re, + Eurydice_slice serialized) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i coefficient = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___compress___4int32_t( + libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re.coefficients[i0])); + uint8_t bytes[8U]; + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_4( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_slice_subslice( + serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)8U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2_compress_compress_ciphertext_coefficient___5int32_t( + core_core_arch_x86___m256i vector) { + core_core_arch_x86___m256i field_modulus_halved = + libcrux_intrinsics_avx2_mm256_set1_epi32( + ((int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS - (int32_t)1) / + (int32_t)2); + core_core_arch_x86___m256i compression_factor = + libcrux_intrinsics_avx2_mm256_set1_epi32((int32_t)10321340); + core_core_arch_x86___m256i coefficient_bits_mask = + libcrux_intrinsics_avx2_mm256_set1_epi32( + ((int32_t)1 << (uint32_t)(int32_t)5) - (int32_t)1); + core_core_arch_x86___m128i coefficients_low = + libcrux_intrinsics_avx2_mm256_castsi256_si128(vector); + core_core_arch_x86___m256i coefficients_low0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_low); + core_core_arch_x86___m256i compressed_low = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)5, coefficients_low0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_low0 = + libcrux_intrinsics_avx2_mm256_add_epi32(compressed_low, + field_modulus_halved); + core_core_arch_x86___m256i compressed_low1 = + libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_low0, + compression_factor); + core_core_arch_x86___m256i compressed_low2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_low1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_low3 = + libcrux_intrinsics_avx2_mm256_and_si256(compressed_low2, + coefficient_bits_mask); + core_core_arch_x86___m128i coefficients_high = + libcrux_intrinsics_avx2_mm256_extracti128_si256( + (int32_t)1, vector, core_core_arch_x86___m128i); + core_core_arch_x86___m256i coefficients_high0 = + libcrux_intrinsics_avx2_mm256_cvtepi16_epi32(coefficients_high); + core_core_arch_x86___m256i compressed_high = + libcrux_intrinsics_avx2_mm256_slli_epi32((int32_t)5, coefficients_high0, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_high0 = + libcrux_intrinsics_avx2_mm256_add_epi32(compressed_high, + field_modulus_halved); + core_core_arch_x86___m256i compressed_high1 = + libcrux_ml_kem_vector_avx2_compress_mulhi_mm256_epi32(compressed_high0, + compression_factor); + core_core_arch_x86___m256i compressed_high2 = + libcrux_intrinsics_avx2_mm256_srli_epi32((int32_t)3, compressed_high1, + core_core_arch_x86___m256i); + core_core_arch_x86___m256i compressed_high3 = + libcrux_intrinsics_avx2_mm256_and_si256(compressed_high2, + coefficient_bits_mask); + core_core_arch_x86___m256i compressed = + libcrux_intrinsics_avx2_mm256_packs_epi32(compressed_low3, + compressed_high3); + return libcrux_intrinsics_avx2_mm256_permute4x64_epi64( + (int32_t)216, compressed, core_core_arch_x86___m256i); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___compress___5int32_t( + core_core_arch_x86___m256i vector) { + return libcrux_ml_kem_vector_avx2_compress_compress_ciphertext_coefficient___5int32_t( + vector); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_serialize_compress_then_serialize_5__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re, + Eurydice_slice serialized) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i coefficients = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___compress___5int32_t( + libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re.coefficients[i0])); + uint8_t bytes[10U]; + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_5( + coefficients, bytes); + Eurydice_slice uu____0 = Eurydice_slice_subslice( + serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)10U * i0, .end = (size_t)10U * i0 + (size_t)10U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)10U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_128size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re, + Eurydice_slice out) { + libcrux_ml_kem_serialize_compress_then_serialize_4__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re, out); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_ind_cpa_encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, + uint8_t ret[1088U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + t_as_ntt[3U]; + libcrux_ml_kem_serialize_deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1152size_t_3size_t( + Eurydice_slice_subslice_to(public_key, (size_t)1152U, uint8_t, size_t, + Eurydice_slice), + t_as_ntt); + Eurydice_slice seed = Eurydice_slice_subslice_from( + public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + A_transpose[3U][3U]; + uint8_t ret0[34U]; + libcrux_ml_kem_utils_into_padded_array___34size_t(seed, ret0); + libcrux_ml_kem_matrix_sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + ret0, false, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_utils_into_padded_array___33size_t(randomness, prf_input); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t + uu____1 = + libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( + uu____0, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + r_as_ntt[3U]; + memcpy( + r_as_ntt, uu____1.fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t domain_separator0 = uu____1.snd; + uint8_t uu____2[33U]; + memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); + K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t + uu____3 = + libcrux_ml_kem_ind_cpa_sample_ring_element_cbd__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_128size_t_2size_t( + uu____2, domain_separator0); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_1[3U]; + memcpy( + error_1, uu____3.fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t domain_separator = uu____3.snd; + prf_input[32U] = domain_separator; + uint8_t prf_output[128U]; + libcrux_ml_kem_hash_functions_avx2___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__avx2__Simd256Hash___PRF___3size_t_128size_t( + Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), + prf_output); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_2 = + libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_avx2_SIMD256Vector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + u[3U]; + libcrux_ml_kem_matrix_compute_vector_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + A_transpose, r_as_ntt, error_1, u); + uint8_t uu____4[32U]; + memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + message_as_ring_element = + libcrux_ml_kem_serialize_deserialize_then_decompress_message__libcrux_ml_kem_vector_avx2_SIMD256Vector( + uu____4); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + v = libcrux_ml_kem_matrix_compute_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); + uint8_t ciphertext[1088U] = {0U}; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____5[3U]; + memcpy( + uu____5, u, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + libcrux_ml_kem_ind_cpa_compress_then_serialize_u__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_960size_t_10size_t_320size_t( + uu____5, Eurydice_array_to_subslice( + (size_t)1088U, ciphertext, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)960U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____6 = v; + libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_avx2_SIMD256Vector_4size_t_128size_t( + uu____6, + Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, (size_t)960U, + uint8_t, size_t, Eurydice_slice)); + memcpy(ret, ciphertext, (size_t)1088U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t, + Eurydice_slice), + (size_t)1152U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice secret_key0 = uu____0.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + secret_key0, (size_t)1184U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key = uu____1.fst; + Eurydice_slice secret_key = uu____1.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = + core_slice___Slice_T___split_at( + secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; + Eurydice_slice implicit_rejection_value = uu____2.snd; + uint8_t decrypted[32U]; + libcrux_ml_kem_ind_cpa_decrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1088size_t_960size_t_10size_t_4size_t( + ind_cpa_secret_key, ciphertext->value, decrypted); + uint8_t to_hash0[64U]; + libcrux_ml_kem_utils_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), + to_hash0); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from( + (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice), + ind_cpa_public_key_hash, uint8_t, void *); + uint8_t hashed[64U]; + libcrux_ml_kem_hash_functions_avx2___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__avx2__Simd256Hash___G___3size_t( + Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____3.fst; + Eurydice_slice pseudorandomness = uu____3.snd; + uint8_t to_hash[1120U]; + libcrux_ml_kem_utils_into_padded_array___1120size_t(implicit_rejection_value, + to_hash); + Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( + ciphertext), + uint8_t, void *); + uint8_t implicit_rejection_shared_secret[32U]; + libcrux_ml_kem_hash_functions_avx2___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__avx2__Simd256Hash___PRF___3size_t_32size_t( + Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t, Eurydice_slice), + implicit_rejection_shared_secret); + Eurydice_slice uu____5 = ind_cpa_public_key; + uint8_t uu____6[32U]; + memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); + uint8_t expected_ciphertext[1088U]; + libcrux_ml_kem_ind_cpa_encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____5, uu____6, pseudorandomness, expected_ciphertext); + Eurydice_slice uu____7 = + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( + ciphertext); + uint8_t selector = + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t( + uu____7, Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, + uint8_t, Eurydice_slice)); + Eurydice_slice uu____8 = shared_secret; + uint8_t ret0[32U]; + libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( + uu____8, + Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, + uint8_t, Eurydice_slice), + selector, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline void libcrux_ml_kem_mlkem768_avx2_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_instantiations_avx2_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_hash_functions_avx2___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__avx2__Simd256Hash___H___3size_t( + Eurydice_slice input, uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_sha256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { + uint8_t to_hash[64U]; + libcrux_ml_kem_utils_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), + to_hash); + Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( + (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + size_t, Eurydice_slice); + uint8_t ret[32U]; + libcrux_ml_kem_hash_functions_avx2___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__avx2__Simd256Hash___H___3size_t( + Eurydice_array_to_slice( + (size_t)1184U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( + public_key), + uint8_t, Eurydice_slice), + ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + uint8_t hashed[64U]; + libcrux_ml_kem_hash_functions_avx2___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__avx2__Simd256Hash___G___3size_t( + Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; + Eurydice_slice uu____2 = Eurydice_array_to_slice( + (size_t)1184U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( + public_key), + uint8_t, Eurydice_slice); + uint8_t uu____3[32U]; + memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); + uint8_t ciphertext[1088U]; + libcrux_ml_kem_ind_cpa_encrypt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____2, uu____3, pseudorandomness, ciphertext); + uint8_t shared_secret_array[32U] = {0U}; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, + Eurydice_slice), + shared_secret, uint8_t, void *); + uint8_t uu____4[1088U]; + memcpy(uu____4, ciphertext, (size_t)1088U * sizeof(uint8_t)); + libcrux_ml_kem_mlkem768_MlKem768Ciphertext uu____5 = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( + uu____4); + uint8_t uu____6[32U]; + memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); + K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ lit; + lit.fst = uu____5; + memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); + return lit; +} + +__attribute__((target("avx2"))) +static inline K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); +} + +__attribute__((target("avx2"))) +static inline K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem768_avx2_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_avx2_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_matrix_compute_As_plus_e_closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + size_t _i) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_traits_to_standard_domain__libcrux_ml_kem_vector_avx2_SIMD256Vector( + core_core_arch_x86___m256i v) { + return libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___montgomery_multiply_by_constant( + v, LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_standard_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *error) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t j = i; + core_core_arch_x86___m256i coefficient_normal_form = + libcrux_ml_kem_vector_traits_to_standard_domain__libcrux_ml_kem_vector_avx2_SIMD256Vector( + self->coefficients[j]); + core_core_arch_x86___m256i uu____0 = + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___barrett_reduce( + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___add( + coefficient_normal_form, &error->coefficients[j])); + self->coefficients[j] = uu____0; + } +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_matrix_compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector ( + *matrix_A)[3U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *s_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *error_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + result[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + result[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, matrix_A, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [3U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + [3U], + size_t); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *row = matrix_A[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *matrix_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + product = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_avx2_SIMD256Vector( + matrix_element, &s_as_ntt[j]); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + &result[i1], &product); + } + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_standard_error_reduce__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &result[i1], &error_as_ntt[i1]); + } + memcpy( + ret, result, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_serialize_serialize_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + *re, + uint8_t ret[384U]) { + uint8_t serialized[384U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + core_core_arch_x86___m256i coefficient = + libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_avx2_SIMD256Vector( + re->coefficients[i0]); + uint8_t bytes[24U]; + libcrux_ml_kem_vector_avx2___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__avx2__SIMD256Vector___serialize_12( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)384U, serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)24U * i0, .end = (size_t)24U * i0 + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)24U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, serialized, (size_t)384U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_ind_cpa_serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + key[3U], + uint8_t ret[1152U]) { + uint8_t out[1152U] = {0U}; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector, + size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + re = key[i0]; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)1152U, out, + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = (i0 + (size_t)1U) * + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret0[384U]; + libcrux_ml_kem_serialize_serialize_uncompressed_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + &re, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, out, (size_t)1152U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_ind_cpa_serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + t_as_ntt[3U], + Eurydice_slice seed_for_a, uint8_t ret[1184U]) { + uint8_t public_key_serialized[1184U] = {0U}; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)1184U, public_key_serialized, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)1152U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____1[3U]; + memcpy( + uu____1, t_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t ret0[1152U]; + libcrux_ml_kem_ind_cpa_serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t( + uu____1, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)1152U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from((size_t)1184U, public_key_serialized, + (size_t)1152U, uint8_t, size_t, + Eurydice_slice), + seed_for_a, uint8_t, void *); + memcpy(ret, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_utils_extraction_helper_Keypair768 +libcrux_ml_kem_ind_cpa_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( + Eurydice_slice key_generation_seed) { + uint8_t hashed[64U]; + libcrux_ml_kem_hash_functions_avx2___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__avx2__Simd256Hash___G___3size_t( + key_generation_seed, hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + (size_t)32U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice seed_for_A = uu____0.fst; + Eurydice_slice seed_for_secret_and_error = uu____0.snd; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + A_transpose[3U][3U]; + uint8_t ret[34U]; + libcrux_ml_kem_utils_into_padded_array___34size_t(seed_for_A, ret); + libcrux_ml_kem_matrix_sample_matrix_A__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t( + ret, true, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_utils_into_padded_array___33size_t(seed_for_secret_and_error, + prf_input); + uint8_t uu____1[33U]; + memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); + K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t__uint8_t + uu____2 = + libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( + uu____1, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + secret_as_ntt[3U]; + memcpy( + secret_as_ntt, uu____2.fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t domain_separator = uu____2.snd; + uint8_t uu____3[33U]; + memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + error_as_ntt[3U]; + memcpy( + error_as_ntt, + libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2size_t_128size_t( + uu____3, domain_separator) + .fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + t_as_ntt[3U]; + libcrux_ml_kem_matrix_compute_As_plus_e__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t( + A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____4[3U]; + memcpy( + uu____4, t_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t public_key_serialized[1184U]; + libcrux_ml_kem_ind_cpa_serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( + uu____4, seed_for_A, public_key_serialized); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____5[3U]; + memcpy( + uu____5, secret_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t secret_key_serialized[1152U]; + libcrux_ml_kem_ind_cpa_serialize_secret_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t( + uu____5, secret_key_serialized); + uint8_t uu____6[1152U]; + memcpy(uu____6, secret_key_serialized, (size_t)1152U * sizeof(uint8_t)); + uint8_t uu____7[1184U]; + memcpy(uu____7, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); + libcrux_ml_kem_utils_extraction_helper_Keypair768 lit; + memcpy(lit.fst, uu____6, (size_t)1152U * sizeof(uint8_t)); + memcpy(lit.snd, uu____7, (size_t)1184U * sizeof(uint8_t)); + return lit; +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_ind_cca_serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t( + Eurydice_slice private_key, Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { + uint8_t out[2400U] = {0U}; + size_t pointer = (size_t)0U; + uint8_t *uu____0 = out; + size_t uu____1 = pointer; + size_t uu____2 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)2400U, uu____0, + (CLITERAL(core_ops_range_Range__size_t){ + .start = uu____1, + .end = uu____2 + + core_slice___Slice_T___len(private_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + private_key, uint8_t, void *); + pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); + uint8_t *uu____3 = out; + size_t uu____4 = pointer; + size_t uu____5 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)2400U, uu____3, + (CLITERAL(core_ops_range_Range__size_t){ + .start = uu____4, + .end = uu____5 + + core_slice___Slice_T___len(public_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + public_key, uint8_t, void *); + pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); + Eurydice_slice uu____6 = Eurydice_array_to_subslice( + (size_t)2400U, out, + (CLITERAL(core_ops_range_Range__size_t){ + .start = pointer, + .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret0[32U]; + libcrux_ml_kem_hash_functions_avx2___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__avx2__Simd256Hash___H___3size_t( + public_key, ret0); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; + uint8_t *uu____7 = out; + size_t uu____8 = pointer; + size_t uu____9 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)2400U, uu____7, + (CLITERAL(core_ops_range_Range__size_t){ + .start = uu____8, + .end = uu____9 + core_slice___Slice_T___len( + implicit_rejection_value, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + implicit_rejection_value, uint8_t, void *); + memcpy(ret, out, (size_t)2400U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]) { + Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( + (size_t)64U, randomness, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( + (size_t)64U, randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, + size_t, Eurydice_slice); + libcrux_ml_kem_utils_extraction_helper_Keypair768 uu____0 = + libcrux_ml_kem_ind_cpa_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( + ind_cpa_keypair_randomness); + uint8_t ind_cpa_private_key[1152U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof(uint8_t)); + uint8_t public_key[1184U]; + memcpy(public_key, uu____0.snd, (size_t)1184U * sizeof(uint8_t)); + Eurydice_slice uu____1 = Eurydice_array_to_slice( + (size_t)1152U, ind_cpa_private_key, uint8_t, Eurydice_slice); + uint8_t secret_key_serialized[2400U]; + libcrux_ml_kem_ind_cca_serialize_kem_secret_key__libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_2400size_t( + uu____1, + Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t, + Eurydice_slice), + implicit_rejection_value, secret_key_serialized); + uint8_t uu____2[2400U]; + memcpy(uu____2, secret_key_serialized, (size_t)2400U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t private_key = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t( + uu____2); + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t uu____3 = private_key; + uint8_t uu____4[1184U]; + memcpy(uu____4, public_key, (size_t)1184U * sizeof(uint8_t)); + return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( + uu____3, + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t( + uu____4)); +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_avx2_SIMD256Vector_libcrux_ml_kem_hash_functions_avx2_Simd256Hash_3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uu____0); +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_mlkem768_avx2_generate_key_pair(uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_avx2_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uu____0); +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector +libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_closure__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184size_t_3size_t( + size_t _i) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector(); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_ml_kem_serialize_deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184size_t_3size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + deserialized_pk[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + deserialized_pk[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_avx2_SIMD256Vector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0 = + libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_avx2_SIMD256Vector( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); +} + +__attribute__((target("avx2"))) +static inline bool +libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( + uint8_t *public_key) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + deserialized_pk[3U]; + libcrux_ml_kem_serialize_deserialize_ring_elements_reduced__libcrux_ml_kem_vector_avx2_SIMD256Vector_1184size_t_3size_t( + Eurydice_array_to_subslice_to((size_t)1184U, public_key, (size_t)1152U, + uint8_t, size_t, Eurydice_slice), + deserialized_pk); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector + uu____0[3U]; + memcpy( + uu____0, deserialized_pk, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_avx2_SIMD256Vector)); + uint8_t public_key_serialized[1184U]; + libcrux_ml_kem_ind_cpa_serialize_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( + uu____0, + Eurydice_array_to_subslice_from((size_t)1184U, public_key, (size_t)1152U, + uint8_t, size_t, Eurydice_slice), + public_key_serialized); + return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( + (size_t)1184U, public_key, public_key_serialized, uint8_t, uint8_t, bool); +} + +__attribute__((target("avx2"))) +static inline bool +libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( + uint8_t *public_key) { + return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_avx2_SIMD256Vector_3size_t_1152size_t_1184size_t( + public_key); +} + +__attribute__((target("avx2"))) +static inline core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ +libcrux_ml_kem_mlkem768_avx2_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key) { + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ + uu____0; + if (libcrux_ml_kem_ind_cca_instantiations_avx2_validate_public_key___3size_t_1152size_t_1184size_t( + public_key.value)) { + uu____0 = (CLITERAL( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ + .tag = core_option_Some, .f0 = public_key}); + } else { + uu____0 = (CLITERAL( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ + .tag = core_option_None}); + } + return uu____0; +} + +__attribute__((target("avx2"))) +static inline libcrux_ml_kem_vector_avx2_portable_PortableVector +libcrux_ml_kem_vector_avx2_portable___core__clone__Clone_for_libcrux_ml_kem__vector__avx2__portable__PortableVector___clone( + libcrux_ml_kem_vector_avx2_portable_PortableVector *self) { + return self[0U]; +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_ml_kem_vector_avx2___core__clone__Clone_for_libcrux_ml_kem__vector__avx2__SIMD256Vector__1__clone( + core_core_arch_x86___m256i *self) { + return self[0U]; +} + +typedef int16_t libcrux_ml_kem_vector_avx2_portable_FieldElement; + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem768_avx2_H_DEFINED +#endif diff --git a/libcrux-ml-kem/cg/libcrux_mlkem768_portable.h b/libcrux-ml-kem/cg/libcrux_mlkem768_portable.h new file mode 100644 index 000000000..ba79f1774 --- /dev/null +++ b/libcrux-ml-kem/cg/libcrux_mlkem768_portable.h @@ -0,0 +1,5050 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../cg.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 409fe455 + */ + +#ifndef __libcrux_mlkem768_portable_H +#define __libcrux_mlkem768_portable_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "eurydice_glue.h" +#include "libcrux_core.h" +#include "libcrux_sha3_portable.h" + +#define LIBCRUX_ML_KEM_HASH_FUNCTIONS_BLOCK_SIZE ((size_t)168U) + +#define LIBCRUX_ML_KEM_HASH_FUNCTIONS_THREE_BLOCKS \ + (LIBCRUX_ML_KEM_HASH_FUNCTIONS_BLOCK_SIZE * (size_t)3U) + +typedef struct libcrux_ml_kem_hash_functions_neon_Simd128Hash_s { + libcrux_sha3_neon_x2_incremental_KeccakState2 shake128_state[2U]; +} libcrux_ml_kem_hash_functions_neon_Simd128Hash; + +#define LIBCRUX_ML_KEM_IND_CCA_ENCAPS_SEED_SIZE \ + (LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) + +#define LIBCRUX_ML_KEM_IND_CCA_KEY_GENERATION_SEED_SIZE \ + (LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE + \ + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) + +typedef uint8_t libcrux_ml_kem_ind_cca_MlKemSharedSecret[32U]; + +static const int16_t libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[128U] = + {(int16_t)-1044, (int16_t)-758, (int16_t)-359, (int16_t)-1517, + (int16_t)1493, (int16_t)1422, (int16_t)287, (int16_t)202, + (int16_t)-171, (int16_t)622, (int16_t)1577, (int16_t)182, + (int16_t)962, (int16_t)-1202, (int16_t)-1474, (int16_t)1468, + (int16_t)573, (int16_t)-1325, (int16_t)264, (int16_t)383, + (int16_t)-829, (int16_t)1458, (int16_t)-1602, (int16_t)-130, + (int16_t)-681, (int16_t)1017, (int16_t)732, (int16_t)608, + (int16_t)-1542, (int16_t)411, (int16_t)-205, (int16_t)-1571, + (int16_t)1223, (int16_t)652, (int16_t)-552, (int16_t)1015, + (int16_t)-1293, (int16_t)1491, (int16_t)-282, (int16_t)-1544, + (int16_t)516, (int16_t)-8, (int16_t)-320, (int16_t)-666, + (int16_t)-1618, (int16_t)-1162, (int16_t)126, (int16_t)1469, + (int16_t)-853, (int16_t)-90, (int16_t)-271, (int16_t)830, + (int16_t)107, (int16_t)-1421, (int16_t)-247, (int16_t)-951, + (int16_t)-398, (int16_t)961, (int16_t)-1508, (int16_t)-725, + (int16_t)448, (int16_t)-1065, (int16_t)677, (int16_t)-1275, + (int16_t)-1103, (int16_t)430, (int16_t)555, (int16_t)843, + (int16_t)-1251, (int16_t)871, (int16_t)1550, (int16_t)105, + (int16_t)422, (int16_t)587, (int16_t)177, (int16_t)-235, + (int16_t)-291, (int16_t)-460, (int16_t)1574, (int16_t)1653, + (int16_t)-246, (int16_t)778, (int16_t)1159, (int16_t)-147, + (int16_t)-777, (int16_t)1483, (int16_t)-602, (int16_t)1119, + (int16_t)-1590, (int16_t)644, (int16_t)-872, (int16_t)349, + (int16_t)418, (int16_t)329, (int16_t)-156, (int16_t)-75, + (int16_t)817, (int16_t)1097, (int16_t)603, (int16_t)610, + (int16_t)1322, (int16_t)-1285, (int16_t)-1465, (int16_t)384, + (int16_t)-1215, (int16_t)-136, (int16_t)1218, (int16_t)-1335, + (int16_t)-874, (int16_t)220, (int16_t)-1187, (int16_t)-1659, + (int16_t)-1185, (int16_t)-1530, (int16_t)-1278, (int16_t)794, + (int16_t)-1510, (int16_t)-854, (int16_t)-870, (int16_t)478, + (int16_t)-108, (int16_t)-308, (int16_t)996, (int16_t)991, + (int16_t)958, (int16_t)-1460, (int16_t)1522, (int16_t)1628}; + +#define LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR ((size_t)16U) + +#define LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT \ + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / \ + LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR) + +#define LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS ((int16_t)3329) + +#define LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS \ + ((int16_t)1353) + +#define LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R \ + (62209U) + +static const uint8_t + libcrux_ml_kem_vector_rej_sample_table_REJECTION_SAMPLE_SHUFFLE_TABLE + [256U][16U] = {{255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, + 255U, 255U, 255U}, + {12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, + 255U, 255U, 255U}, + {10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, + 13U, 255U, 255U}, + {14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, + 255U, 255U, 255U}, + {10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, + 15U, 255U, 255U}, + {12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, + 15U, 255U, 255U}, + {10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, + 15U, 255U, 255U}, + {8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, + 15U, 255U, 255U}, + {6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, + 15U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, + 15U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, + 15U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, + 13U, 14U, 15U}}; + +typedef struct libcrux_ml_kem_vector_portable_PortableVector_s { + int16_t elements[16U]; +} libcrux_ml_kem_vector_portable_PortableVector; + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_zero(void) { + libcrux_ml_kem_vector_portable_PortableVector lit; + lit.elements[0U] = (int16_t)0; + lit.elements[1U] = (int16_t)0; + lit.elements[2U] = (int16_t)0; + lit.elements[3U] = (int16_t)0; + lit.elements[4U] = (int16_t)0; + lit.elements[5U] = (int16_t)0; + lit.elements[6U] = (int16_t)0; + lit.elements[7U] = (int16_t)0; + lit.elements[8U] = (int16_t)0; + lit.elements[9U] = (int16_t)0; + lit.elements[10U] = (int16_t)0; + lit.elements[11U] = (int16_t)0; + lit.elements[12U] = (int16_t)0; + lit.elements[13U] = (int16_t)0; + lit.elements[14U] = (int16_t)0; + lit.elements[15U] = (int16_t)0; + return lit; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO( + void) { + return libcrux_ml_kem_vector_zero(); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_from_i16_array(Eurydice_slice array) { + libcrux_ml_kem_vector_portable_PortableVector lit; + int16_t ret[16U]; + core_result_Result__int16_t_16size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_slice_subslice(array, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)16U}), + int16_t, core_ops_range_Range__size_t, + Eurydice_slice), + Eurydice_slice, int16_t[16U], void *); + core_result__core__result__Result_T__E___unwrap__int16_t_16size_t__core_array_TryFromSliceError( + dst, ret); + memcpy(lit.elements, ret, (size_t)16U * sizeof(int16_t)); + return lit; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___from_i16_array( + Eurydice_slice array) { + return libcrux_ml_kem_vector_from_i16_array(array); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_add(libcrux_ml_kem_vector_portable_PortableVector lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + size_t uu____0 = i0; + lhs.elements[uu____0] = lhs.elements[uu____0] + rhs->elements[i0]; + } + return lhs; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add( + libcrux_ml_kem_vector_portable_PortableVector lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs) { + return libcrux_ml_kem_vector_add(lhs, rhs); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_sub(libcrux_ml_kem_vector_portable_PortableVector lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + size_t uu____0 = i0; + lhs.elements[uu____0] = lhs.elements[uu____0] - rhs->elements[i0]; + } + return lhs; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___sub( + libcrux_ml_kem_vector_portable_PortableVector lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs) { + return libcrux_ml_kem_vector_sub(lhs, rhs); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_multiply_by_constant( + libcrux_ml_kem_vector_portable_PortableVector v, int16_t c) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + size_t uu____0 = i0; + v.elements[uu____0] = v.elements[uu____0] * c; + } + return v; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___multiply_by_constant( + libcrux_ml_kem_vector_portable_PortableVector v, int16_t c) { + return libcrux_ml_kem_vector_multiply_by_constant(v, c); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_bitwise_and_with_constant( + libcrux_ml_kem_vector_portable_PortableVector v, int16_t c) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + size_t uu____0 = i0; + v.elements[uu____0] = v.elements[uu____0] & c; + } + return v; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___bitwise_and_with_constant( + libcrux_ml_kem_vector_portable_PortableVector v, int16_t c) { + return libcrux_ml_kem_vector_bitwise_and_with_constant(v, c); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_cond_subtract_3329( + libcrux_ml_kem_vector_portable_PortableVector v) { + core_ops_range_Range__size_t iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR}), + core_ops_range_Range__size_t, core_ops_range_Range__size_t); + while (true) { + core_option_Option__size_t uu____0 = + core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, core_option_Option__size_t); + if (!(uu____0.tag == core_option_None)) { + size_t i = uu____0.f0; + if (v.elements[i] >= (int16_t)3329) { + size_t uu____1 = i; + v.elements[uu____1] = v.elements[uu____1] - (int16_t)3329; + } + continue; + } + return v; + } +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___cond_subtract_3329( + libcrux_ml_kem_vector_portable_PortableVector v) { + return libcrux_ml_kem_vector_cond_subtract_3329(v); +} + +#define LIBCRUX_ML_KEM_VECTOR_BARRETT_MULTIPLIER ((int32_t)20159) + +#define LIBCRUX_ML_KEM_VECTOR_BARRETT_SHIFT ((int32_t)26) + +#define LIBCRUX_ML_KEM_VECTOR_BARRETT_R \ + ((int32_t)1 << (uint32_t)LIBCRUX_ML_KEM_VECTOR_BARRETT_SHIFT) + +static inline int16_t libcrux_ml_kem_vector_barrett_reduce_element( + int16_t value) { + int32_t t = (int32_t)value * LIBCRUX_ML_KEM_VECTOR_BARRETT_MULTIPLIER + + (LIBCRUX_ML_KEM_VECTOR_BARRETT_R >> 1U); + int16_t quotient = + (int16_t)(t >> (uint32_t)LIBCRUX_ML_KEM_VECTOR_BARRETT_SHIFT); + return value - quotient * LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_barrett_reduce( + libcrux_ml_kem_vector_portable_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + int16_t uu____0 = + libcrux_ml_kem_vector_barrett_reduce_element(v.elements[i0]); + v.elements[i0] = uu____0; + } + return v; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce( + libcrux_ml_kem_vector_portable_PortableVector v) { + return libcrux_ml_kem_vector_barrett_reduce(v); +} + +#define LIBCRUX_ML_KEM_VECTOR_MONTGOMERY_SHIFT (16U) + +#define LIBCRUX_ML_KEM_VECTOR_MONTGOMERY_R \ + ((int32_t)1 << (uint32_t)LIBCRUX_ML_KEM_VECTOR_MONTGOMERY_SHIFT) + +static inline int16_t libcrux_ml_kem_vector_montgomery_reduce_element( + int32_t value) { + int32_t k = + (int32_t)(int16_t)value * + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R; + int32_t k_times_modulus = + (int32_t)(int16_t)k * (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + int16_t c = (int16_t)(k_times_modulus >> + (uint32_t)LIBCRUX_ML_KEM_VECTOR_MONTGOMERY_SHIFT); + int16_t value_high = + (int16_t)(value >> (uint32_t)LIBCRUX_ML_KEM_VECTOR_MONTGOMERY_SHIFT); + return value_high - c; +} + +static inline int16_t libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + int16_t fe, int16_t fer) { + return libcrux_ml_kem_vector_montgomery_reduce_element((int32_t)fe * + (int32_t)fer); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_montgomery_multiply_by_constant( + libcrux_ml_kem_vector_portable_PortableVector v, int16_t c) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + int16_t uu____0 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[i0], c); + v.elements[i0] = uu____0; + } + return v; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___montgomery_multiply_by_constant( + libcrux_ml_kem_vector_portable_PortableVector v, int16_t r) { + return libcrux_ml_kem_vector_montgomery_multiply_by_constant(v, r); +} + +static inline uint8_t libcrux_ml_kem_vector_compress_message_coefficient( + uint16_t fe) { + int16_t shifted = (int16_t)1664 - (int16_t)fe; + int16_t mask = shifted >> 15U; + int16_t shifted_to_positive = mask ^ shifted; + int16_t shifted_positive_in_range = shifted_to_positive - (int16_t)832; + return (uint8_t)(shifted_positive_in_range >> 15U & (int16_t)1); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_compress_1( + libcrux_ml_kem_vector_portable_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + uint8_t uu____0 = libcrux_ml_kem_vector_compress_message_coefficient( + (uint16_t)v.elements[i0]); + v.elements[i0] = (int16_t)uu____0; + } + return v; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___compress_1( + libcrux_ml_kem_vector_portable_PortableVector v) { + return libcrux_ml_kem_vector_compress_1(v); +} + +static inline uint32_t libcrux_ml_kem_vector_get_n_least_significant_bits( + uint8_t n, uint32_t value) { + return value & ((1U << (uint32_t)n) - 1U); +} + +static inline int16_t libcrux_ml_kem_vector_compress_ciphertext_coefficient( + uint8_t coefficient_bits, uint16_t fe) { + uint64_t compressed = (uint64_t)fe << (uint32_t)coefficient_bits; + compressed = compressed + 1664ULL; + compressed = compressed * 10321340ULL; + compressed = compressed >> 35U; + return (int16_t)libcrux_ml_kem_vector_get_n_least_significant_bits( + coefficient_bits, (uint32_t)compressed); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_ntt_layer_1_step( + libcrux_ml_kem_vector_portable_PortableVector v, int16_t zeta0, + int16_t zeta1, int16_t zeta2, int16_t zeta3) { + int16_t t = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[2U], zeta0); + v.elements[2U] = v.elements[0U] - t; + v.elements[0U] = v.elements[0U] + t; + int16_t t0 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[3U], zeta0); + v.elements[3U] = v.elements[1U] - t0; + v.elements[1U] = v.elements[1U] + t0; + int16_t t1 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[6U], zeta1); + v.elements[6U] = v.elements[4U] - t1; + v.elements[4U] = v.elements[4U] + t1; + int16_t t2 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[7U], zeta1); + v.elements[7U] = v.elements[5U] - t2; + v.elements[5U] = v.elements[5U] + t2; + int16_t t3 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[(size_t)8U + (size_t)2U], zeta2); + v.elements[(size_t)8U + (size_t)2U] = + v.elements[(size_t)8U + (size_t)0U] - t3; + v.elements[(size_t)8U + (size_t)0U] = + v.elements[(size_t)8U + (size_t)0U] + t3; + int16_t t4 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[(size_t)8U + (size_t)3U], zeta2); + v.elements[(size_t)8U + (size_t)3U] = + v.elements[(size_t)8U + (size_t)1U] - t4; + v.elements[(size_t)8U + (size_t)1U] = + v.elements[(size_t)8U + (size_t)1U] + t4; + int16_t t5 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[(size_t)8U + (size_t)6U], zeta3); + v.elements[(size_t)8U + (size_t)6U] = + v.elements[(size_t)8U + (size_t)4U] - t5; + v.elements[(size_t)8U + (size_t)4U] = + v.elements[(size_t)8U + (size_t)4U] + t5; + int16_t t6 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[(size_t)8U + (size_t)7U], zeta3); + v.elements[(size_t)8U + (size_t)7U] = + v.elements[(size_t)8U + (size_t)5U] - t6; + v.elements[(size_t)8U + (size_t)5U] = + v.elements[(size_t)8U + (size_t)5U] + t6; + return v; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_layer_1_step( + libcrux_ml_kem_vector_portable_PortableVector a, int16_t zeta0, + int16_t zeta1, int16_t zeta2, int16_t zeta3) { + return libcrux_ml_kem_vector_ntt_layer_1_step(a, zeta0, zeta1, zeta2, zeta3); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_ntt_layer_2_step( + libcrux_ml_kem_vector_portable_PortableVector v, int16_t zeta0, + int16_t zeta1) { + int16_t t = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[4U], zeta0); + v.elements[4U] = v.elements[0U] - t; + v.elements[0U] = v.elements[0U] + t; + int16_t t0 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[5U], zeta0); + v.elements[5U] = v.elements[1U] - t0; + v.elements[1U] = v.elements[1U] + t0; + int16_t t1 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[6U], zeta0); + v.elements[6U] = v.elements[2U] - t1; + v.elements[2U] = v.elements[2U] + t1; + int16_t t2 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[7U], zeta0); + v.elements[7U] = v.elements[3U] - t2; + v.elements[3U] = v.elements[3U] + t2; + int16_t t3 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[(size_t)8U + (size_t)4U], zeta1); + v.elements[(size_t)8U + (size_t)4U] = + v.elements[(size_t)8U + (size_t)0U] - t3; + v.elements[(size_t)8U + (size_t)0U] = + v.elements[(size_t)8U + (size_t)0U] + t3; + int16_t t4 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[(size_t)8U + (size_t)5U], zeta1); + v.elements[(size_t)8U + (size_t)5U] = + v.elements[(size_t)8U + (size_t)1U] - t4; + v.elements[(size_t)8U + (size_t)1U] = + v.elements[(size_t)8U + (size_t)1U] + t4; + int16_t t5 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[(size_t)8U + (size_t)6U], zeta1); + v.elements[(size_t)8U + (size_t)6U] = + v.elements[(size_t)8U + (size_t)2U] - t5; + v.elements[(size_t)8U + (size_t)2U] = + v.elements[(size_t)8U + (size_t)2U] + t5; + int16_t t6 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[(size_t)8U + (size_t)7U], zeta1); + v.elements[(size_t)8U + (size_t)7U] = + v.elements[(size_t)8U + (size_t)3U] - t6; + v.elements[(size_t)8U + (size_t)3U] = + v.elements[(size_t)8U + (size_t)3U] + t6; + return v; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_layer_2_step( + libcrux_ml_kem_vector_portable_PortableVector a, int16_t zeta0, + int16_t zeta1) { + return libcrux_ml_kem_vector_ntt_layer_2_step(a, zeta0, zeta1); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_ntt_layer_3_step( + libcrux_ml_kem_vector_portable_PortableVector v, int16_t zeta) { + int16_t t = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[8U], zeta); + v.elements[8U] = v.elements[0U] - t; + v.elements[0U] = v.elements[0U] + t; + int16_t t0 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(v.elements[9U], zeta); + v.elements[9U] = v.elements[1U] - t0; + v.elements[1U] = v.elements[1U] + t0; + int16_t t1 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[10U], zeta); + v.elements[10U] = v.elements[2U] - t1; + v.elements[2U] = v.elements[2U] + t1; + int16_t t2 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[11U], zeta); + v.elements[11U] = v.elements[3U] - t2; + v.elements[3U] = v.elements[3U] + t2; + int16_t t3 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[12U], zeta); + v.elements[12U] = v.elements[4U] - t3; + v.elements[4U] = v.elements[4U] + t3; + int16_t t4 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[13U], zeta); + v.elements[13U] = v.elements[5U] - t4; + v.elements[5U] = v.elements[5U] + t4; + int16_t t5 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[14U], zeta); + v.elements[14U] = v.elements[6U] - t5; + v.elements[6U] = v.elements[6U] + t5; + int16_t t6 = libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer( + v.elements[15U], zeta); + v.elements[15U] = v.elements[7U] - t6; + v.elements[7U] = v.elements[7U] + t6; + return v; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_layer_3_step( + libcrux_ml_kem_vector_portable_PortableVector a, int16_t zeta) { + return libcrux_ml_kem_vector_ntt_layer_3_step(a, zeta); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_inv_ntt_layer_1_step( + libcrux_ml_kem_vector_portable_PortableVector v, int16_t zeta0, + int16_t zeta1, int16_t zeta2, int16_t zeta3) { + int16_t a_minus_b = v.elements[2U] - v.elements[0U]; + int16_t uu____0 = libcrux_ml_kem_vector_barrett_reduce_element( + v.elements[0U] + v.elements[2U]); + v.elements[0U] = uu____0; + int16_t uu____1 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b, zeta0); + v.elements[2U] = uu____1; + int16_t a_minus_b0 = v.elements[3U] - v.elements[1U]; + int16_t uu____2 = libcrux_ml_kem_vector_barrett_reduce_element( + v.elements[1U] + v.elements[3U]); + v.elements[1U] = uu____2; + int16_t uu____3 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b0, zeta0); + v.elements[3U] = uu____3; + int16_t a_minus_b1 = v.elements[6U] - v.elements[4U]; + int16_t uu____4 = libcrux_ml_kem_vector_barrett_reduce_element( + v.elements[4U] + v.elements[6U]); + v.elements[4U] = uu____4; + int16_t uu____5 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b1, zeta1); + v.elements[6U] = uu____5; + int16_t a_minus_b2 = v.elements[7U] - v.elements[5U]; + int16_t uu____6 = libcrux_ml_kem_vector_barrett_reduce_element( + v.elements[5U] + v.elements[7U]); + v.elements[5U] = uu____6; + int16_t uu____7 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b2, zeta1); + v.elements[7U] = uu____7; + int16_t a_minus_b3 = + v.elements[(size_t)8U + (size_t)2U] - v.elements[(size_t)8U + (size_t)0U]; + int16_t uu____8 = libcrux_ml_kem_vector_barrett_reduce_element( + v.elements[(size_t)8U + (size_t)0U] + + v.elements[(size_t)8U + (size_t)2U]); + v.elements[(size_t)8U + (size_t)0U] = uu____8; + int16_t uu____9 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b3, zeta2); + v.elements[(size_t)8U + (size_t)2U] = uu____9; + int16_t a_minus_b4 = + v.elements[(size_t)8U + (size_t)3U] - v.elements[(size_t)8U + (size_t)1U]; + int16_t uu____10 = libcrux_ml_kem_vector_barrett_reduce_element( + v.elements[(size_t)8U + (size_t)1U] + + v.elements[(size_t)8U + (size_t)3U]); + v.elements[(size_t)8U + (size_t)1U] = uu____10; + int16_t uu____11 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b4, zeta2); + v.elements[(size_t)8U + (size_t)3U] = uu____11; + int16_t a_minus_b5 = + v.elements[(size_t)8U + (size_t)6U] - v.elements[(size_t)8U + (size_t)4U]; + int16_t uu____12 = libcrux_ml_kem_vector_barrett_reduce_element( + v.elements[(size_t)8U + (size_t)4U] + + v.elements[(size_t)8U + (size_t)6U]); + v.elements[(size_t)8U + (size_t)4U] = uu____12; + int16_t uu____13 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b5, zeta3); + v.elements[(size_t)8U + (size_t)6U] = uu____13; + int16_t a_minus_b6 = + v.elements[(size_t)8U + (size_t)7U] - v.elements[(size_t)8U + (size_t)5U]; + int16_t uu____14 = libcrux_ml_kem_vector_barrett_reduce_element( + v.elements[(size_t)8U + (size_t)5U] + + v.elements[(size_t)8U + (size_t)7U]); + v.elements[(size_t)8U + (size_t)5U] = uu____14; + int16_t uu____15 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b6, zeta3); + v.elements[(size_t)8U + (size_t)7U] = uu____15; + return v; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___inv_ntt_layer_1_step( + libcrux_ml_kem_vector_portable_PortableVector a, int16_t zeta0, + int16_t zeta1, int16_t zeta2, int16_t zeta3) { + return libcrux_ml_kem_vector_inv_ntt_layer_1_step(a, zeta0, zeta1, zeta2, + zeta3); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_inv_ntt_layer_2_step( + libcrux_ml_kem_vector_portable_PortableVector v, int16_t zeta0, + int16_t zeta1) { + int16_t a_minus_b = v.elements[4U] - v.elements[0U]; + v.elements[0U] = v.elements[0U] + v.elements[4U]; + int16_t uu____0 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b, zeta0); + v.elements[4U] = uu____0; + int16_t a_minus_b0 = v.elements[5U] - v.elements[1U]; + v.elements[1U] = v.elements[1U] + v.elements[5U]; + int16_t uu____1 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b0, zeta0); + v.elements[5U] = uu____1; + int16_t a_minus_b1 = v.elements[6U] - v.elements[2U]; + v.elements[2U] = v.elements[2U] + v.elements[6U]; + int16_t uu____2 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b1, zeta0); + v.elements[6U] = uu____2; + int16_t a_minus_b2 = v.elements[7U] - v.elements[3U]; + v.elements[3U] = v.elements[3U] + v.elements[7U]; + int16_t uu____3 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b2, zeta0); + v.elements[7U] = uu____3; + int16_t a_minus_b3 = + v.elements[(size_t)8U + (size_t)4U] - v.elements[(size_t)8U + (size_t)0U]; + v.elements[(size_t)8U + (size_t)0U] = + v.elements[(size_t)8U + (size_t)0U] + v.elements[(size_t)8U + (size_t)4U]; + int16_t uu____4 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b3, zeta1); + v.elements[(size_t)8U + (size_t)4U] = uu____4; + int16_t a_minus_b4 = + v.elements[(size_t)8U + (size_t)5U] - v.elements[(size_t)8U + (size_t)1U]; + v.elements[(size_t)8U + (size_t)1U] = + v.elements[(size_t)8U + (size_t)1U] + v.elements[(size_t)8U + (size_t)5U]; + int16_t uu____5 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b4, zeta1); + v.elements[(size_t)8U + (size_t)5U] = uu____5; + int16_t a_minus_b5 = + v.elements[(size_t)8U + (size_t)6U] - v.elements[(size_t)8U + (size_t)2U]; + v.elements[(size_t)8U + (size_t)2U] = + v.elements[(size_t)8U + (size_t)2U] + v.elements[(size_t)8U + (size_t)6U]; + int16_t uu____6 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b5, zeta1); + v.elements[(size_t)8U + (size_t)6U] = uu____6; + int16_t a_minus_b6 = + v.elements[(size_t)8U + (size_t)7U] - v.elements[(size_t)8U + (size_t)3U]; + v.elements[(size_t)8U + (size_t)3U] = + v.elements[(size_t)8U + (size_t)3U] + v.elements[(size_t)8U + (size_t)7U]; + int16_t uu____7 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b6, zeta1); + v.elements[(size_t)8U + (size_t)7U] = uu____7; + return v; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___inv_ntt_layer_2_step( + libcrux_ml_kem_vector_portable_PortableVector a, int16_t zeta0, + int16_t zeta1) { + return libcrux_ml_kem_vector_inv_ntt_layer_2_step(a, zeta0, zeta1); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_inv_ntt_layer_3_step( + libcrux_ml_kem_vector_portable_PortableVector v, int16_t zeta) { + int16_t a_minus_b = v.elements[8U] - v.elements[0U]; + v.elements[0U] = v.elements[0U] + v.elements[8U]; + int16_t uu____0 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b, zeta); + v.elements[8U] = uu____0; + int16_t a_minus_b0 = v.elements[9U] - v.elements[1U]; + v.elements[1U] = v.elements[1U] + v.elements[9U]; + int16_t uu____1 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b0, zeta); + v.elements[9U] = uu____1; + int16_t a_minus_b1 = v.elements[10U] - v.elements[2U]; + v.elements[2U] = v.elements[2U] + v.elements[10U]; + int16_t uu____2 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b1, zeta); + v.elements[10U] = uu____2; + int16_t a_minus_b2 = v.elements[11U] - v.elements[3U]; + v.elements[3U] = v.elements[3U] + v.elements[11U]; + int16_t uu____3 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b2, zeta); + v.elements[11U] = uu____3; + int16_t a_minus_b3 = v.elements[12U] - v.elements[4U]; + v.elements[4U] = v.elements[4U] + v.elements[12U]; + int16_t uu____4 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b3, zeta); + v.elements[12U] = uu____4; + int16_t a_minus_b4 = v.elements[13U] - v.elements[5U]; + v.elements[5U] = v.elements[5U] + v.elements[13U]; + int16_t uu____5 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b4, zeta); + v.elements[13U] = uu____5; + int16_t a_minus_b5 = v.elements[14U] - v.elements[6U]; + v.elements[6U] = v.elements[6U] + v.elements[14U]; + int16_t uu____6 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b5, zeta); + v.elements[14U] = uu____6; + int16_t a_minus_b6 = v.elements[15U] - v.elements[7U]; + v.elements[7U] = v.elements[7U] + v.elements[15U]; + int16_t uu____7 = + libcrux_ml_kem_vector_montgomery_multiply_fe_by_fer(a_minus_b6, zeta); + v.elements[15U] = uu____7; + return v; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___inv_ntt_layer_3_step( + libcrux_ml_kem_vector_portable_PortableVector a, int16_t zeta) { + return libcrux_ml_kem_vector_inv_ntt_layer_3_step(a, zeta); +} + +typedef struct K___int16_t_int16_t_s { + int16_t fst; + int16_t snd; +} K___int16_t_int16_t; + +static inline K___int16_t_int16_t libcrux_ml_kem_vector_ntt_multiply_binomials( + K___int16_t_int16_t _, K___int16_t_int16_t _0, int16_t zeta) { + int16_t a0 = _.fst; + int16_t a1 = _.snd; + int16_t b0 = _0.fst; + int16_t b1 = _0.snd; + int32_t uu____0 = (int32_t)a0 * (int32_t)b0; + int16_t uu____1 = libcrux_ml_kem_vector_montgomery_reduce_element( + uu____0 + (int32_t)libcrux_ml_kem_vector_montgomery_reduce_element( + (int32_t)a1 * (int32_t)b1) * + (int32_t)zeta); + return (CLITERAL(K___int16_t_int16_t){ + .fst = uu____1, + .snd = libcrux_ml_kem_vector_montgomery_reduce_element( + (int32_t)a0 * (int32_t)b1 + (int32_t)a1 * (int32_t)b0)}); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_ntt_multiply( + libcrux_ml_kem_vector_portable_PortableVector *lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs, int16_t zeta0, + int16_t zeta1, int16_t zeta2, int16_t zeta3) { + libcrux_ml_kem_vector_portable_PortableVector out = + libcrux_ml_kem_vector_zero(); + K___int16_t_int16_t lit0; + lit0.fst = lhs->elements[0U]; + lit0.snd = lhs->elements[1U]; + K___int16_t_int16_t lit1; + lit1.fst = rhs->elements[0U]; + lit1.snd = rhs->elements[1U]; + K___int16_t_int16_t product = + libcrux_ml_kem_vector_ntt_multiply_binomials(lit0, lit1, zeta0); + out.elements[0U] = product.fst; + out.elements[1U] = product.snd; + K___int16_t_int16_t lit2; + lit2.fst = lhs->elements[2U]; + lit2.snd = lhs->elements[3U]; + K___int16_t_int16_t lit3; + lit3.fst = rhs->elements[2U]; + lit3.snd = rhs->elements[3U]; + K___int16_t_int16_t product0 = + libcrux_ml_kem_vector_ntt_multiply_binomials(lit2, lit3, -zeta0); + out.elements[2U] = product0.fst; + out.elements[3U] = product0.snd; + K___int16_t_int16_t lit4; + lit4.fst = lhs->elements[4U]; + lit4.snd = lhs->elements[5U]; + K___int16_t_int16_t lit5; + lit5.fst = rhs->elements[4U]; + lit5.snd = rhs->elements[5U]; + K___int16_t_int16_t product1 = + libcrux_ml_kem_vector_ntt_multiply_binomials(lit4, lit5, zeta1); + out.elements[4U] = product1.fst; + out.elements[5U] = product1.snd; + K___int16_t_int16_t lit6; + lit6.fst = lhs->elements[6U]; + lit6.snd = lhs->elements[7U]; + K___int16_t_int16_t lit7; + lit7.fst = rhs->elements[6U]; + lit7.snd = rhs->elements[7U]; + K___int16_t_int16_t product2 = + libcrux_ml_kem_vector_ntt_multiply_binomials(lit6, lit7, -zeta1); + out.elements[6U] = product2.fst; + out.elements[7U] = product2.snd; + K___int16_t_int16_t lit8; + lit8.fst = lhs->elements[(size_t)8U + (size_t)0U]; + lit8.snd = lhs->elements[(size_t)8U + (size_t)1U]; + K___int16_t_int16_t lit9; + lit9.fst = rhs->elements[(size_t)8U + (size_t)0U]; + lit9.snd = rhs->elements[(size_t)8U + (size_t)1U]; + K___int16_t_int16_t product3 = + libcrux_ml_kem_vector_ntt_multiply_binomials(lit8, lit9, zeta2); + out.elements[(size_t)8U + (size_t)0U] = product3.fst; + out.elements[(size_t)8U + (size_t)1U] = product3.snd; + K___int16_t_int16_t lit10; + lit10.fst = lhs->elements[(size_t)8U + (size_t)2U]; + lit10.snd = lhs->elements[(size_t)8U + (size_t)3U]; + K___int16_t_int16_t lit11; + lit11.fst = rhs->elements[(size_t)8U + (size_t)2U]; + lit11.snd = rhs->elements[(size_t)8U + (size_t)3U]; + K___int16_t_int16_t product4 = + libcrux_ml_kem_vector_ntt_multiply_binomials(lit10, lit11, -zeta2); + out.elements[(size_t)8U + (size_t)2U] = product4.fst; + out.elements[(size_t)8U + (size_t)3U] = product4.snd; + K___int16_t_int16_t lit12; + lit12.fst = lhs->elements[(size_t)8U + (size_t)4U]; + lit12.snd = lhs->elements[(size_t)8U + (size_t)5U]; + K___int16_t_int16_t lit13; + lit13.fst = rhs->elements[(size_t)8U + (size_t)4U]; + lit13.snd = rhs->elements[(size_t)8U + (size_t)5U]; + K___int16_t_int16_t product5 = + libcrux_ml_kem_vector_ntt_multiply_binomials(lit12, lit13, zeta3); + out.elements[(size_t)8U + (size_t)4U] = product5.fst; + out.elements[(size_t)8U + (size_t)5U] = product5.snd; + K___int16_t_int16_t lit14; + lit14.fst = lhs->elements[(size_t)8U + (size_t)6U]; + lit14.snd = lhs->elements[(size_t)8U + (size_t)7U]; + K___int16_t_int16_t lit; + lit.fst = rhs->elements[(size_t)8U + (size_t)6U]; + lit.snd = rhs->elements[(size_t)8U + (size_t)7U]; + K___int16_t_int16_t product6 = + libcrux_ml_kem_vector_ntt_multiply_binomials(lit14, lit, -zeta3); + out.elements[(size_t)8U + (size_t)6U] = product6.fst; + out.elements[(size_t)8U + (size_t)7U] = product6.snd; + return out; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_multiply( + libcrux_ml_kem_vector_portable_PortableVector *lhs, + libcrux_ml_kem_vector_portable_PortableVector *rhs, int16_t zeta0, + int16_t zeta1, int16_t zeta2, int16_t zeta3) { + return libcrux_ml_kem_vector_ntt_multiply(lhs, rhs, zeta0, zeta1, zeta2, + zeta3); +} + +static inline void libcrux_ml_kem_vector_serialize_1( + libcrux_ml_kem_vector_portable_PortableVector v, uint8_t ret[2U]) { + uint8_t result[2U] = {0U}; + KRML_MAYBE_FOR8( + i, (size_t)0U, (size_t)8U, (size_t)1U, size_t i0 = i; + size_t uu____0 = (size_t)0U; + result[uu____0] = (uint32_t)result[uu____0] | + (uint32_t)(uint8_t)v.elements[i0] << (uint32_t)i0;); + KRML_MAYBE_FOR8(i, (size_t)8U, (size_t)16U, (size_t)1U, size_t i0 = i; + size_t uu____1 = (size_t)1U; + result[uu____1] = (uint32_t)result[uu____1] | + (uint32_t)(uint8_t)v.elements[i0] + << (uint32_t)(i0 - (size_t)8U);); + memcpy(ret, result, (size_t)2U * sizeof(uint8_t)); +} + +static inline void +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_1( + libcrux_ml_kem_vector_portable_PortableVector a, uint8_t ret[2U]) { + uint8_t ret0[2U]; + libcrux_ml_kem_vector_serialize_1(a, ret0); + memcpy(ret, ret0, (size_t)2U * sizeof(uint8_t)); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_deserialize_1(Eurydice_slice v) { + libcrux_ml_kem_vector_portable_PortableVector result = + libcrux_ml_kem_vector_zero(); + KRML_MAYBE_FOR8(i, (size_t)0U, (size_t)8U, (size_t)1U, size_t i0 = i; + uint8_t *uu____0 = &Eurydice_slice_index( + v, (size_t)0U, uint8_t, uint8_t *, uint8_t); + result.elements[i0] = + (int16_t)((uint32_t)uu____0[0U] >> (uint32_t)i0 & 1U);); + for (size_t i = (size_t)8U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + uint8_t *uu____1 = + &Eurydice_slice_index(v, (size_t)1U, uint8_t, uint8_t *, uint8_t); + result.elements[i0] = + (int16_t)((uint32_t)uu____1[0U] >> (uint32_t)(i0 - (size_t)8U) & 1U); + } + return result; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_1( + Eurydice_slice a) { + return libcrux_ml_kem_vector_deserialize_1(a); +} + +static inline void libcrux_ml_kem_vector_serialize_4( + libcrux_ml_kem_vector_portable_PortableVector v, uint8_t ret[8U]) { + uint8_t result[8U] = {0U}; + result[0U] = (uint32_t)(uint8_t)v.elements[1U] << 4U | + (uint32_t)(uint8_t)v.elements[0U]; + result[1U] = (uint32_t)(uint8_t)v.elements[3U] << 4U | + (uint32_t)(uint8_t)v.elements[2U]; + result[2U] = (uint32_t)(uint8_t)v.elements[5U] << 4U | + (uint32_t)(uint8_t)v.elements[4U]; + result[3U] = (uint32_t)(uint8_t)v.elements[7U] << 4U | + (uint32_t)(uint8_t)v.elements[6U]; + result[4U] = (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)1U] << 4U | + (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)0U]; + result[5U] = (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)3U] << 4U | + (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)2U]; + result[6U] = (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)5U] << 4U | + (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)4U]; + result[7U] = (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)7U] << 4U | + (uint32_t)(uint8_t)v.elements[(size_t)8U + (size_t)6U]; + memcpy(ret, result, (size_t)8U * sizeof(uint8_t)); +} + +static inline void +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_4( + libcrux_ml_kem_vector_portable_PortableVector a, uint8_t ret[8U]) { + uint8_t ret0[8U]; + libcrux_ml_kem_vector_serialize_4(a, ret0); + memcpy(ret, ret0, (size_t)8U * sizeof(uint8_t)); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_deserialize_4(Eurydice_slice bytes) { + libcrux_ml_kem_vector_portable_PortableVector v = + libcrux_ml_kem_vector_zero(); + uint8_t *uu____0 = + &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); + v.elements[0U] = (int16_t)((uint32_t)uu____0[0U] & 15U); + uint8_t *uu____1 = + &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); + v.elements[1U] = (int16_t)((uint32_t)uu____1[0U] >> 4U & 15U); + uint8_t *uu____2 = + &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + v.elements[2U] = (int16_t)((uint32_t)uu____2[0U] & 15U); + uint8_t *uu____3 = + &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + v.elements[3U] = (int16_t)((uint32_t)uu____3[0U] >> 4U & 15U); + uint8_t *uu____4 = + &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + v.elements[4U] = (int16_t)((uint32_t)uu____4[0U] & 15U); + uint8_t *uu____5 = + &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + v.elements[5U] = (int16_t)((uint32_t)uu____5[0U] >> 4U & 15U); + uint8_t *uu____6 = + &Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); + v.elements[6U] = (int16_t)((uint32_t)uu____6[0U] & 15U); + uint8_t *uu____7 = + &Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); + v.elements[7U] = (int16_t)((uint32_t)uu____7[0U] >> 4U & 15U); + uint8_t *uu____8 = + &Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); + v.elements[8U] = (int16_t)((uint32_t)uu____8[0U] & 15U); + uint8_t *uu____9 = + &Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); + v.elements[9U] = (int16_t)((uint32_t)uu____9[0U] >> 4U & 15U); + uint8_t *uu____10 = + &Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); + v.elements[10U] = (int16_t)((uint32_t)uu____10[0U] & 15U); + uint8_t *uu____11 = + &Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); + v.elements[11U] = (int16_t)((uint32_t)uu____11[0U] >> 4U & 15U); + uint8_t *uu____12 = + &Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); + v.elements[12U] = (int16_t)((uint32_t)uu____12[0U] & 15U); + uint8_t *uu____13 = + &Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); + v.elements[13U] = (int16_t)((uint32_t)uu____13[0U] >> 4U & 15U); + uint8_t *uu____14 = + &Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); + v.elements[14U] = (int16_t)((uint32_t)uu____14[0U] & 15U); + uint8_t *uu____15 = + &Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); + v.elements[15U] = (int16_t)((uint32_t)uu____15[0U] >> 4U & 15U); + return v; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_4( + Eurydice_slice a) { + return libcrux_ml_kem_vector_deserialize_4(a); +} + +static inline void libcrux_ml_kem_vector_serialize_5( + libcrux_ml_kem_vector_portable_PortableVector v, uint8_t ret[10U]) { + uint8_t result[10U] = {0U}; + result[0U] = (uint8_t)((v.elements[1U] & (int16_t)7) << 5U | v.elements[0U]); + result[1U] = + (uint8_t)(((v.elements[3U] & (int16_t)1) << 7U | v.elements[2U] << 2U) | + v.elements[1U] >> 3U); + result[2U] = + (uint8_t)((v.elements[4U] & (int16_t)15) << 4U | v.elements[3U] >> 1U); + result[3U] = + (uint8_t)(((v.elements[6U] & (int16_t)3) << 6U | v.elements[5U] << 1U) | + v.elements[4U] >> 4U); + result[4U] = (uint8_t)(v.elements[7U] << 3U | v.elements[6U] >> 2U); + result[5U] = + (uint8_t)((v.elements[(size_t)8U + (size_t)1U] & (int16_t)7) << 5U | + v.elements[(size_t)8U + (size_t)0U]); + result[6U] = + (uint8_t)(((v.elements[(size_t)8U + (size_t)3U] & (int16_t)1) << 7U | + v.elements[(size_t)8U + (size_t)2U] << 2U) | + v.elements[(size_t)8U + (size_t)1U] >> 3U); + result[7U] = + (uint8_t)((v.elements[(size_t)8U + (size_t)4U] & (int16_t)15) << 4U | + v.elements[(size_t)8U + (size_t)3U] >> 1U); + result[8U] = + (uint8_t)(((v.elements[(size_t)8U + (size_t)6U] & (int16_t)3) << 6U | + v.elements[(size_t)8U + (size_t)5U] << 1U) | + v.elements[(size_t)8U + (size_t)4U] >> 4U); + result[9U] = (uint8_t)(v.elements[(size_t)8U + (size_t)7U] << 3U | + v.elements[(size_t)8U + (size_t)6U] >> 2U); + memcpy(ret, result, (size_t)10U * sizeof(uint8_t)); +} + +static inline void +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_5( + libcrux_ml_kem_vector_portable_PortableVector a, uint8_t ret[10U]) { + uint8_t ret0[10U]; + libcrux_ml_kem_vector_serialize_5(a, ret0); + memcpy(ret, ret0, (size_t)10U * sizeof(uint8_t)); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_deserialize_5(Eurydice_slice bytes) { + libcrux_ml_kem_vector_portable_PortableVector v = + libcrux_ml_kem_vector_zero(); + uint8_t *uu____0 = + &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); + v.elements[0U] = (int16_t)((uint32_t)uu____0[0U] & 31U); + uint8_t uu____1 = ((uint32_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t) & + 3U) + << 3U; + uint8_t *uu____2 = + &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); + v.elements[1U] = (int16_t)((uint32_t)uu____1 | (uint32_t)uu____2[0U] >> 5U); + uint8_t *uu____3 = + &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + v.elements[2U] = (int16_t)((uint32_t)uu____3[0U] >> 2U & 31U); + uint8_t uu____4 = ((uint32_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, + uint8_t *, uint8_t) & + 15U) + << 1U; + uint8_t *uu____5 = + &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + v.elements[3U] = (int16_t)((uint32_t)uu____4 | (uint32_t)uu____5[0U] >> 7U); + uint8_t uu____6 = ((uint32_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, + uint8_t *, uint8_t) & + 1U) + << 4U; + uint8_t *uu____7 = + &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + v.elements[4U] = (int16_t)((uint32_t)uu____6 | (uint32_t)uu____7[0U] >> 4U); + uint8_t *uu____8 = + &Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); + v.elements[5U] = (int16_t)((uint32_t)uu____8[0U] >> 1U & 31U); + uint8_t uu____9 = ((uint32_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, + uint8_t *, uint8_t) & + 7U) + << 2U; + uint8_t *uu____10 = + &Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); + v.elements[6U] = (int16_t)((uint32_t)uu____9 | (uint32_t)uu____10[0U] >> 6U); + uint8_t *uu____11 = + &Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); + v.elements[7U] = (int16_t)((uint32_t)uu____11[0U] >> 3U); + uint8_t *uu____12 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)0U, + uint8_t, uint8_t *, uint8_t); + v.elements[8U] = (int16_t)((uint32_t)uu____12[0U] & 31U); + uint8_t uu____13 = + ((uint32_t)Eurydice_slice_index(bytes, (size_t)5U + (size_t)1U, uint8_t, + uint8_t *, uint8_t) & + 3U) + << 3U; + uint8_t *uu____14 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)0U, + uint8_t, uint8_t *, uint8_t); + v.elements[9U] = (int16_t)((uint32_t)uu____13 | (uint32_t)uu____14[0U] >> 5U); + uint8_t *uu____15 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)1U, + uint8_t, uint8_t *, uint8_t); + v.elements[10U] = (int16_t)((uint32_t)uu____15[0U] >> 2U & 31U); + uint8_t uu____16 = + ((uint32_t)Eurydice_slice_index(bytes, (size_t)5U + (size_t)2U, uint8_t, + uint8_t *, uint8_t) & + 15U) + << 1U; + uint8_t *uu____17 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)1U, + uint8_t, uint8_t *, uint8_t); + v.elements[11U] = + (int16_t)((uint32_t)uu____16 | (uint32_t)uu____17[0U] >> 7U); + uint8_t uu____18 = + ((uint32_t)Eurydice_slice_index(bytes, (size_t)5U + (size_t)3U, uint8_t, + uint8_t *, uint8_t) & + 1U) + << 4U; + uint8_t *uu____19 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)2U, + uint8_t, uint8_t *, uint8_t); + v.elements[12U] = + (int16_t)((uint32_t)uu____18 | (uint32_t)uu____19[0U] >> 4U); + uint8_t *uu____20 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)3U, + uint8_t, uint8_t *, uint8_t); + v.elements[13U] = (int16_t)((uint32_t)uu____20[0U] >> 1U & 31U); + uint8_t uu____21 = + ((uint32_t)Eurydice_slice_index(bytes, (size_t)5U + (size_t)4U, uint8_t, + uint8_t *, uint8_t) & + 7U) + << 2U; + uint8_t *uu____22 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)3U, + uint8_t, uint8_t *, uint8_t); + v.elements[14U] = + (int16_t)((uint32_t)uu____21 | (uint32_t)uu____22[0U] >> 6U); + uint8_t *uu____23 = &Eurydice_slice_index(bytes, (size_t)5U + (size_t)4U, + uint8_t, uint8_t *, uint8_t); + v.elements[15U] = (int16_t)((uint32_t)uu____23[0U] >> 3U); + return v; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_5( + Eurydice_slice a) { + return libcrux_ml_kem_vector_deserialize_5(a); +} + +static inline void libcrux_ml_kem_vector_serialize_10( + libcrux_ml_kem_vector_portable_PortableVector v, uint8_t ret[20U]) { + uint8_t result[20U] = {0U}; + result[0U] = (uint8_t)(v.elements[0U] & (int16_t)255); + result[1U] = (uint32_t)(uint8_t)(v.elements[1U] & (int16_t)63) << 2U | + (uint32_t)(uint8_t)(v.elements[0U] >> 8U & (int16_t)3); + result[2U] = (uint32_t)(uint8_t)(v.elements[2U] & (int16_t)15) << 4U | + (uint32_t)(uint8_t)(v.elements[1U] >> 6U & (int16_t)15); + result[3U] = (uint32_t)(uint8_t)(v.elements[3U] & (int16_t)3) << 6U | + (uint32_t)(uint8_t)(v.elements[2U] >> 4U & (int16_t)63); + result[4U] = (uint8_t)(v.elements[3U] >> 2U & (int16_t)255); + result[5U] = (uint8_t)(v.elements[4U] & (int16_t)255); + result[6U] = (uint32_t)(uint8_t)(v.elements[5U] & (int16_t)63) << 2U | + (uint32_t)(uint8_t)(v.elements[4U] >> 8U & (int16_t)3); + result[7U] = (uint32_t)(uint8_t)(v.elements[6U] & (int16_t)15) << 4U | + (uint32_t)(uint8_t)(v.elements[5U] >> 6U & (int16_t)15); + result[8U] = (uint32_t)(uint8_t)(v.elements[7U] & (int16_t)3) << 6U | + (uint32_t)(uint8_t)(v.elements[6U] >> 4U & (int16_t)63); + result[9U] = (uint8_t)(v.elements[7U] >> 2U & (int16_t)255); + result[10U] = (uint8_t)(v.elements[(size_t)8U + (size_t)0U] & (int16_t)255); + result[11U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] & (int16_t)63) + << 2U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)0U] >> 8U & + (int16_t)3); + result[12U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] & (int16_t)15) + << 4U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] >> 6U & + (int16_t)15); + result[13U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)3U] & (int16_t)3) + << 6U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 4U & + (int16_t)63); + result[14U] = + (uint8_t)(v.elements[(size_t)8U + (size_t)3U] >> 2U & (int16_t)255); + result[15U] = (uint8_t)(v.elements[(size_t)8U + (size_t)4U] & (int16_t)255); + result[16U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] & (int16_t)63) + << 2U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)4U] >> 8U & + (int16_t)3); + result[17U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] & (int16_t)15) + << 4U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 6U & + (int16_t)15); + result[18U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)7U] & (int16_t)3) + << 6U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] >> 4U & + (int16_t)63); + result[19U] = + (uint8_t)(v.elements[(size_t)8U + (size_t)7U] >> 2U & (int16_t)255); + memcpy(ret, result, (size_t)20U * sizeof(uint8_t)); +} + +static inline void +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_10( + libcrux_ml_kem_vector_portable_PortableVector a, uint8_t ret[20U]) { + uint8_t ret0[20U]; + libcrux_ml_kem_vector_serialize_10(a, ret0); + memcpy(ret, ret0, (size_t)20U * sizeof(uint8_t)); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_deserialize_10(Eurydice_slice bytes) { + libcrux_ml_kem_vector_portable_PortableVector result = + libcrux_ml_kem_vector_zero(); + int16_t uu____0 = ((int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)3) + << 8U; + uint8_t *uu____1 = + &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); + result.elements[0U] = uu____0 | ((int16_t)uu____1[0U] & (int16_t)255); + int16_t uu____2 = ((int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)15) + << 6U; + uint8_t *uu____3 = + &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + result.elements[1U] = uu____2 | (int16_t)uu____3[0U] >> 2U; + int16_t uu____4 = ((int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)63) + << 4U; + uint8_t *uu____5 = + &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + result.elements[2U] = uu____4 | (int16_t)uu____5[0U] >> 4U; + int16_t uu____6 = (int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, + uint8_t *, uint8_t) + << 2U; + uint8_t *uu____7 = + &Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *, uint8_t); + result.elements[3U] = uu____6 | (int16_t)uu____7[0U] >> 6U; + int16_t uu____8 = ((int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)3) + << 8U; + uint8_t *uu____9 = + &Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); + result.elements[4U] = uu____8 | ((int16_t)uu____9[0U] & (int16_t)255); + int16_t uu____10 = ((int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)15) + << 6U; + uint8_t *uu____11 = + &Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); + result.elements[5U] = uu____10 | (int16_t)uu____11[0U] >> 2U; + int16_t uu____12 = ((int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)63) + << 4U; + uint8_t *uu____13 = + &Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *, uint8_t); + result.elements[6U] = uu____12 | (int16_t)uu____13[0U] >> 4U; + int16_t uu____14 = (int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, + uint8_t *, uint8_t) + << 2U; + uint8_t *uu____15 = + &Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t); + result.elements[7U] = uu____14 | (int16_t)uu____15[0U] >> 6U; + int16_t uu____16 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)1U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)3) + << 8U; + uint8_t *uu____17 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)0U, + uint8_t, uint8_t *, uint8_t); + result.elements[8U] = uu____16 | ((int16_t)uu____17[0U] & (int16_t)255); + int16_t uu____18 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)2U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)15) + << 6U; + uint8_t *uu____19 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)1U, + uint8_t, uint8_t *, uint8_t); + result.elements[9U] = uu____18 | (int16_t)uu____19[0U] >> 2U; + int16_t uu____20 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)3U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)63) + << 4U; + uint8_t *uu____21 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)2U, + uint8_t, uint8_t *, uint8_t); + result.elements[10U] = uu____20 | (int16_t)uu____21[0U] >> 4U; + int16_t uu____22 = + (int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)4U, uint8_t, + uint8_t *, uint8_t) + << 2U; + uint8_t *uu____23 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)3U, + uint8_t, uint8_t *, uint8_t); + result.elements[11U] = uu____22 | (int16_t)uu____23[0U] >> 6U; + int16_t uu____24 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)6U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)3) + << 8U; + uint8_t *uu____25 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)5U, + uint8_t, uint8_t *, uint8_t); + result.elements[12U] = uu____24 | ((int16_t)uu____25[0U] & (int16_t)255); + int16_t uu____26 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)7U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)15) + << 6U; + uint8_t *uu____27 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)6U, + uint8_t, uint8_t *, uint8_t); + result.elements[13U] = uu____26 | (int16_t)uu____27[0U] >> 2U; + int16_t uu____28 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)8U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)63) + << 4U; + uint8_t *uu____29 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)7U, + uint8_t, uint8_t *, uint8_t); + result.elements[14U] = uu____28 | (int16_t)uu____29[0U] >> 4U; + int16_t uu____30 = + (int16_t)Eurydice_slice_index(bytes, (size_t)10U + (size_t)9U, uint8_t, + uint8_t *, uint8_t) + << 2U; + uint8_t *uu____31 = &Eurydice_slice_index(bytes, (size_t)10U + (size_t)8U, + uint8_t, uint8_t *, uint8_t); + result.elements[15U] = uu____30 | (int16_t)uu____31[0U] >> 6U; + return result; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_10( + Eurydice_slice a) { + return libcrux_ml_kem_vector_deserialize_10(a); +} + +static inline void libcrux_ml_kem_vector_serialize_11( + libcrux_ml_kem_vector_portable_PortableVector v, uint8_t ret[22U]) { + uint8_t result[22U] = {0U}; + result[0U] = (uint8_t)v.elements[0U]; + result[1U] = (uint32_t)(uint8_t)(v.elements[1U] & (int16_t)31) << 3U | + (uint32_t)(uint8_t)(v.elements[0U] >> 8U); + result[2U] = (uint32_t)(uint8_t)(v.elements[2U] & (int16_t)3) << 6U | + (uint32_t)(uint8_t)(v.elements[1U] >> 5U); + result[3U] = (uint8_t)(v.elements[2U] >> 2U & (int16_t)255); + result[4U] = (uint32_t)(uint8_t)(v.elements[3U] & (int16_t)127) << 1U | + (uint32_t)(uint8_t)(v.elements[2U] >> 10U); + result[5U] = (uint32_t)(uint8_t)(v.elements[4U] & (int16_t)15) << 4U | + (uint32_t)(uint8_t)(v.elements[3U] >> 7U); + result[6U] = (uint32_t)(uint8_t)(v.elements[5U] & (int16_t)1) << 7U | + (uint32_t)(uint8_t)(v.elements[4U] >> 4U); + result[7U] = (uint8_t)(v.elements[5U] >> 1U & (int16_t)255); + result[8U] = (uint32_t)(uint8_t)(v.elements[6U] & (int16_t)63) << 2U | + (uint32_t)(uint8_t)(v.elements[5U] >> 9U); + result[9U] = (uint32_t)(uint8_t)(v.elements[7U] & (int16_t)7) << 5U | + (uint32_t)(uint8_t)(v.elements[6U] >> 6U); + result[10U] = (uint8_t)(v.elements[7U] >> 3U); + result[11U] = (uint8_t)v.elements[(size_t)8U + (size_t)0U]; + result[12U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] & (int16_t)31) + << 3U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)0U] >> 8U); + result[13U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] & (int16_t)3) + << 6U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)1U] >> 5U); + result[14U] = + (uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 2U & (int16_t)255); + result[15U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)3U] & (int16_t)127) + << 1U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 10U); + result[16U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)4U] & (int16_t)15) + << 4U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)3U] >> 7U); + result[17U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] & (int16_t)1) + << 7U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)4U] >> 4U); + result[18U] = + (uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 1U & (int16_t)255); + result[19U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] & (int16_t)63) + << 2U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 9U); + result[20U] = + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)7U] & (int16_t)7) + << 5U | + (uint32_t)(uint8_t)(v.elements[(size_t)8U + (size_t)6U] >> 6U); + result[21U] = (uint8_t)(v.elements[(size_t)8U + (size_t)7U] >> 3U); + memcpy(ret, result, (size_t)22U * sizeof(uint8_t)); +} + +static inline void +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_11( + libcrux_ml_kem_vector_portable_PortableVector a, uint8_t ret[22U]) { + uint8_t ret0[22U]; + libcrux_ml_kem_vector_serialize_11(a, ret0); + memcpy(ret, ret0, (size_t)22U * sizeof(uint8_t)); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_deserialize_11(Eurydice_slice bytes) { + libcrux_ml_kem_vector_portable_PortableVector result = + libcrux_ml_kem_vector_zero(); + int16_t uu____0 = ((int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)7) + << 8U; + uint8_t *uu____1 = + &Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *, uint8_t); + result.elements[0U] = uu____0 | (int16_t)uu____1[0U]; + int16_t uu____2 = ((int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)63) + << 5U; + uint8_t *uu____3 = + &Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *, uint8_t); + result.elements[1U] = uu____2 | (int16_t)uu____3[0U] >> 3U; + int16_t uu____4 = ((int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)1) + << 10U; + int16_t uu____5 = + uu____4 | (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, + uint8_t *, uint8_t) + << 2U; + uint8_t *uu____6 = + &Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *, uint8_t); + result.elements[2U] = uu____5 | (int16_t)uu____6[0U] >> 6U; + int16_t uu____7 = ((int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)15) + << 7U; + uint8_t *uu____8 = + &Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *, uint8_t); + result.elements[3U] = uu____7 | (int16_t)uu____8[0U] >> 1U; + int16_t uu____9 = ((int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)127) + << 4U; + uint8_t *uu____10 = + &Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *, uint8_t); + result.elements[4U] = uu____9 | (int16_t)uu____10[0U] >> 4U; + int16_t uu____11 = ((int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)3) + << 9U; + int16_t uu____12 = + uu____11 | (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, + uint8_t *, uint8_t) + << 1U; + uint8_t *uu____13 = + &Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *, uint8_t); + result.elements[5U] = uu____12 | (int16_t)uu____13[0U] >> 7U; + int16_t uu____14 = ((int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)31) + << 6U; + uint8_t *uu____15 = + &Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *, uint8_t); + result.elements[6U] = uu____14 | (int16_t)uu____15[0U] >> 2U; + int16_t uu____16 = (int16_t)Eurydice_slice_index(bytes, (size_t)10U, uint8_t, + uint8_t *, uint8_t) + << 3U; + uint8_t *uu____17 = + &Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *, uint8_t); + result.elements[7U] = uu____16 | (int16_t)uu____17[0U] >> 5U; + int16_t uu____18 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)1U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)7) + << 8U; + uint8_t *uu____19 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)0U, + uint8_t, uint8_t *, uint8_t); + result.elements[8U] = uu____18 | (int16_t)uu____19[0U]; + int16_t uu____20 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)2U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)63) + << 5U; + uint8_t *uu____21 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)1U, + uint8_t, uint8_t *, uint8_t); + result.elements[9U] = uu____20 | (int16_t)uu____21[0U] >> 3U; + int16_t uu____22 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)4U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)1) + << 10U; + int16_t uu____23 = + uu____22 | (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)3U, + uint8_t, uint8_t *, uint8_t) + << 2U; + uint8_t *uu____24 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)2U, + uint8_t, uint8_t *, uint8_t); + result.elements[10U] = uu____23 | (int16_t)uu____24[0U] >> 6U; + int16_t uu____25 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)5U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)15) + << 7U; + uint8_t *uu____26 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)4U, + uint8_t, uint8_t *, uint8_t); + result.elements[11U] = uu____25 | (int16_t)uu____26[0U] >> 1U; + int16_t uu____27 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)6U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)127) + << 4U; + uint8_t *uu____28 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)5U, + uint8_t, uint8_t *, uint8_t); + result.elements[12U] = uu____27 | (int16_t)uu____28[0U] >> 4U; + int16_t uu____29 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)8U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)3) + << 9U; + int16_t uu____30 = + uu____29 | (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)7U, + uint8_t, uint8_t *, uint8_t) + << 1U; + uint8_t *uu____31 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)6U, + uint8_t, uint8_t *, uint8_t); + result.elements[13U] = uu____30 | (int16_t)uu____31[0U] >> 7U; + int16_t uu____32 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)9U, uint8_t, + uint8_t *, uint8_t) & + (int16_t)31) + << 6U; + uint8_t *uu____33 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)8U, + uint8_t, uint8_t *, uint8_t); + result.elements[14U] = uu____32 | (int16_t)uu____33[0U] >> 2U; + int16_t uu____34 = + (int16_t)Eurydice_slice_index(bytes, (size_t)11U + (size_t)10U, uint8_t, + uint8_t *, uint8_t) + << 3U; + uint8_t *uu____35 = &Eurydice_slice_index(bytes, (size_t)11U + (size_t)9U, + uint8_t, uint8_t *, uint8_t); + result.elements[15U] = uu____34 | (int16_t)uu____35[0U] >> 5U; + return result; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_11( + Eurydice_slice a) { + return libcrux_ml_kem_vector_deserialize_11(a); +} + +static inline void libcrux_ml_kem_vector_serialize_12( + libcrux_ml_kem_vector_portable_PortableVector v, uint8_t ret[24U]) { + uint8_t result[24U] = {0U}; + result[0U] = (uint8_t)(v.elements[0U] & (int16_t)255); + result[1U] = + (uint8_t)(v.elements[0U] >> 8U | (v.elements[1U] & (int16_t)15) << 4U); + result[2U] = (uint8_t)(v.elements[1U] >> 4U & (int16_t)255); + result[3U] = (uint8_t)(v.elements[2U] & (int16_t)255); + result[4U] = + (uint8_t)(v.elements[2U] >> 8U | (v.elements[3U] & (int16_t)15) << 4U); + result[5U] = (uint8_t)(v.elements[3U] >> 4U & (int16_t)255); + result[6U] = (uint8_t)(v.elements[4U] & (int16_t)255); + result[7U] = + (uint8_t)(v.elements[4U] >> 8U | (v.elements[5U] & (int16_t)15) << 4U); + result[8U] = (uint8_t)(v.elements[5U] >> 4U & (int16_t)255); + result[9U] = (uint8_t)(v.elements[6U] & (int16_t)255); + result[10U] = + (uint8_t)(v.elements[6U] >> 8U | (v.elements[7U] & (int16_t)15) << 4U); + result[11U] = (uint8_t)(v.elements[7U] >> 4U & (int16_t)255); + result[12U] = (uint8_t)(v.elements[(size_t)8U + (size_t)0U] & (int16_t)255); + result[13U] = + (uint8_t)(v.elements[(size_t)8U + (size_t)0U] >> 8U | + (v.elements[(size_t)8U + (size_t)1U] & (int16_t)15) << 4U); + result[14U] = + (uint8_t)(v.elements[(size_t)8U + (size_t)1U] >> 4U & (int16_t)255); + result[15U] = (uint8_t)(v.elements[(size_t)8U + (size_t)2U] & (int16_t)255); + result[16U] = + (uint8_t)(v.elements[(size_t)8U + (size_t)2U] >> 8U | + (v.elements[(size_t)8U + (size_t)3U] & (int16_t)15) << 4U); + result[17U] = + (uint8_t)(v.elements[(size_t)8U + (size_t)3U] >> 4U & (int16_t)255); + result[18U] = (uint8_t)(v.elements[(size_t)8U + (size_t)4U] & (int16_t)255); + result[19U] = + (uint8_t)(v.elements[(size_t)8U + (size_t)4U] >> 8U | + (v.elements[(size_t)8U + (size_t)5U] & (int16_t)15) << 4U); + result[20U] = + (uint8_t)(v.elements[(size_t)8U + (size_t)5U] >> 4U & (int16_t)255); + result[21U] = (uint8_t)(v.elements[(size_t)8U + (size_t)6U] & (int16_t)255); + result[22U] = + (uint8_t)(v.elements[(size_t)8U + (size_t)6U] >> 8U | + (v.elements[(size_t)8U + (size_t)7U] & (int16_t)15) << 4U); + result[23U] = + (uint8_t)(v.elements[(size_t)8U + (size_t)7U] >> 4U & (int16_t)255); + memcpy(ret, result, (size_t)24U * sizeof(uint8_t)); +} + +static inline void +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_12( + libcrux_ml_kem_vector_portable_PortableVector a, uint8_t ret[24U]) { + uint8_t ret0[24U]; + libcrux_ml_kem_vector_serialize_12(a, ret0); + memcpy(ret, ret0, (size_t)24U * sizeof(uint8_t)); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_deserialize_12(Eurydice_slice bytes) { + libcrux_ml_kem_vector_portable_PortableVector re = + libcrux_ml_kem_vector_zero(); + int16_t byte0 = (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, + uint8_t *, uint8_t); + int16_t byte1 = (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, + uint8_t *, uint8_t); + int16_t byte2 = (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, + uint8_t *, uint8_t); + int16_t byte3 = (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, + uint8_t *, uint8_t); + int16_t byte4 = (int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, + uint8_t *, uint8_t); + int16_t byte5 = (int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, + uint8_t *, uint8_t); + int16_t byte6 = (int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, + uint8_t *, uint8_t); + int16_t byte7 = (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, + uint8_t *, uint8_t); + int16_t byte8 = (int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, + uint8_t *, uint8_t); + int16_t byte9 = (int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, + uint8_t *, uint8_t); + int16_t byte10 = (int16_t)Eurydice_slice_index(bytes, (size_t)10U, uint8_t, + uint8_t *, uint8_t); + int16_t byte11 = (int16_t)Eurydice_slice_index(bytes, (size_t)11U, uint8_t, + uint8_t *, uint8_t); + re.elements[0U] = (byte1 & (int16_t)15) << 8U | (byte0 & (int16_t)255); + re.elements[1U] = byte2 << 4U | (byte1 >> 4U & (int16_t)15); + re.elements[2U] = (byte4 & (int16_t)15) << 8U | (byte3 & (int16_t)255); + re.elements[3U] = byte5 << 4U | (byte4 >> 4U & (int16_t)15); + re.elements[4U] = (byte7 & (int16_t)15) << 8U | (byte6 & (int16_t)255); + re.elements[5U] = byte8 << 4U | (byte7 >> 4U & (int16_t)15); + re.elements[6U] = (byte10 & (int16_t)15) << 8U | (byte9 & (int16_t)255); + re.elements[7U] = byte11 << 4U | (byte10 >> 4U & (int16_t)15); + int16_t byte12 = (int16_t)Eurydice_slice_index(bytes, (size_t)12U, uint8_t, + uint8_t *, uint8_t); + int16_t byte13 = (int16_t)Eurydice_slice_index(bytes, (size_t)13U, uint8_t, + uint8_t *, uint8_t); + int16_t byte14 = (int16_t)Eurydice_slice_index(bytes, (size_t)14U, uint8_t, + uint8_t *, uint8_t); + int16_t byte15 = (int16_t)Eurydice_slice_index(bytes, (size_t)15U, uint8_t, + uint8_t *, uint8_t); + int16_t byte16 = (int16_t)Eurydice_slice_index(bytes, (size_t)16U, uint8_t, + uint8_t *, uint8_t); + int16_t byte17 = (int16_t)Eurydice_slice_index(bytes, (size_t)17U, uint8_t, + uint8_t *, uint8_t); + int16_t byte18 = (int16_t)Eurydice_slice_index(bytes, (size_t)18U, uint8_t, + uint8_t *, uint8_t); + int16_t byte19 = (int16_t)Eurydice_slice_index(bytes, (size_t)19U, uint8_t, + uint8_t *, uint8_t); + int16_t byte20 = (int16_t)Eurydice_slice_index(bytes, (size_t)20U, uint8_t, + uint8_t *, uint8_t); + int16_t byte21 = (int16_t)Eurydice_slice_index(bytes, (size_t)21U, uint8_t, + uint8_t *, uint8_t); + int16_t byte22 = (int16_t)Eurydice_slice_index(bytes, (size_t)22U, uint8_t, + uint8_t *, uint8_t); + int16_t byte23 = (int16_t)Eurydice_slice_index(bytes, (size_t)23U, uint8_t, + uint8_t *, uint8_t); + re.elements[8U] = (byte13 & (int16_t)15) << 8U | (byte12 & (int16_t)255); + re.elements[9U] = byte14 << 4U | (byte13 >> 4U & (int16_t)15); + re.elements[10U] = (byte16 & (int16_t)15) << 8U | (byte15 & (int16_t)255); + re.elements[11U] = byte17 << 4U | (byte16 >> 4U & (int16_t)15); + re.elements[12U] = (byte19 & (int16_t)15) << 8U | (byte18 & (int16_t)255); + re.elements[13U] = byte20 << 4U | (byte19 >> 4U & (int16_t)15); + re.elements[14U] = (byte22 & (int16_t)15) << 8U | (byte21 & (int16_t)255); + re.elements[15U] = byte23 << 4U | (byte22 >> 4U & (int16_t)15); + return re; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_12( + Eurydice_slice a) { + return libcrux_ml_kem_vector_deserialize_12(a); +} + +static inline size_t libcrux_ml_kem_vector_rej_sample(Eurydice_slice a, + Eurydice_slice result) { + size_t sampled = (size_t)0U; + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(a, uint8_t, size_t) / (size_t)3U; i++) { + size_t i0 = i; + int16_t b1 = (int16_t)Eurydice_slice_index(a, i0 * (size_t)3U + (size_t)0U, + uint8_t, uint8_t *, uint8_t); + int16_t b2 = (int16_t)Eurydice_slice_index(a, i0 * (size_t)3U + (size_t)1U, + uint8_t, uint8_t *, uint8_t); + int16_t b3 = (int16_t)Eurydice_slice_index(a, i0 * (size_t)3U + (size_t)2U, + uint8_t, uint8_t *, uint8_t); + int16_t d1 = (b2 & (int16_t)15) << 8U | b1; + int16_t d2 = b3 << 4U | b2 >> 4U; + bool uu____0; + int16_t uu____1; + bool uu____2; + size_t uu____3; + int16_t uu____4; + size_t uu____5; + int16_t uu____6; + if (d1 < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS) { + if (sampled < (size_t)16U) { + int16_t uu____7 = d1; + Eurydice_slice_index(result, sampled, int16_t, int16_t *, int16_t) = + uu____7; + sampled++; + uu____1 = d2; + uu____6 = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + uu____0 = uu____1 < uu____6; + if (uu____0) { + uu____3 = sampled; + uu____2 = uu____3 < (size_t)16U; + if (uu____2) { + uu____4 = d2; + uu____5 = sampled; + Eurydice_slice_index(result, uu____5, int16_t, int16_t *, int16_t) = + uu____4; + sampled++; + continue; + } + } + continue; + } + } + uu____1 = d2; + uu____6 = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + uu____0 = uu____1 < uu____6; + if (uu____0) { + uu____3 = sampled; + uu____2 = uu____3 < (size_t)16U; + if (uu____2) { + uu____4 = d2; + uu____5 = sampled; + Eurydice_slice_index(result, uu____5, int16_t, int16_t *, int16_t) = + uu____4; + sampled++; + continue; + } + } + } + return sampled; +} + +static inline size_t +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___rej_sample( + Eurydice_slice a, Eurydice_slice out) { + return libcrux_ml_kem_vector_rej_sample(a, out); +} + +#define LIBCRUX_ML_KEM_MLKEM768_VECTOR_U_COMPRESSION_FACTOR_768 ((size_t)10U) + +#define LIBCRUX_ML_KEM_MLKEM768_C1_BLOCK_SIZE_768 \ + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ + LIBCRUX_ML_KEM_MLKEM768_VECTOR_U_COMPRESSION_FACTOR_768 / (size_t)8U) + +#define LIBCRUX_ML_KEM_MLKEM768_RANK_768 ((size_t)3U) + +#define LIBCRUX_ML_KEM_MLKEM768_C1_SIZE_768 \ + (LIBCRUX_ML_KEM_MLKEM768_C1_BLOCK_SIZE_768 * LIBCRUX_ML_KEM_MLKEM768_RANK_768) + +#define LIBCRUX_ML_KEM_MLKEM768_VECTOR_V_COMPRESSION_FACTOR_768 ((size_t)4U) + +#define LIBCRUX_ML_KEM_MLKEM768_C2_SIZE_768 \ + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ + LIBCRUX_ML_KEM_MLKEM768_VECTOR_V_COMPRESSION_FACTOR_768 / (size_t)8U) + +#define LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768 \ + (LIBCRUX_ML_KEM_MLKEM768_C1_SIZE_768 + LIBCRUX_ML_KEM_MLKEM768_C2_SIZE_768) + +#define LIBCRUX_ML_KEM_MLKEM768_T_AS_NTT_ENCODED_SIZE_768 \ + (LIBCRUX_ML_KEM_MLKEM768_RANK_768 * \ + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ + LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) + +#define LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE_768 \ + (LIBCRUX_ML_KEM_MLKEM768_T_AS_NTT_ENCODED_SIZE_768 + (size_t)32U) + +#define LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_SECRET_KEY_SIZE_768 \ + (LIBCRUX_ML_KEM_MLKEM768_RANK_768 * \ + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ + LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) + +#define LIBCRUX_ML_KEM_MLKEM768_ETA1 ((size_t)2U) + +#define LIBCRUX_ML_KEM_MLKEM768_ETA1_RANDOMNESS_SIZE \ + (LIBCRUX_ML_KEM_MLKEM768_ETA1 * (size_t)64U) + +#define LIBCRUX_ML_KEM_MLKEM768_ETA2 ((size_t)2U) + +#define LIBCRUX_ML_KEM_MLKEM768_ETA2_RANDOMNESS_SIZE \ + (LIBCRUX_ML_KEM_MLKEM768_ETA2 * (size_t)64U) + +#define LIBCRUX_ML_KEM_MLKEM768_IMPLICIT_REJECTION_HASH_INPUT_SIZE \ + (LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE + \ + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768) + +typedef libcrux_ml_kem_types_MlKemPrivateKey____2400size_t + libcrux_ml_kem_mlkem768_MlKem768PrivateKey; + +typedef libcrux_ml_kem_types_MlKemPublicKey____1184size_t + libcrux_ml_kem_mlkem768_MlKem768PublicKey; + +#define LIBCRUX_ML_KEM_MLKEM768_RANKED_BYTES_PER_RING_ELEMENT_768 \ + (LIBCRUX_ML_KEM_MLKEM768_RANK_768 * \ + LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT / (size_t)8U) + +#define LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768 \ + (LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_SECRET_KEY_SIZE_768 + \ + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE_768 + \ + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + \ + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) + +typedef struct + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_s { + libcrux_ml_kem_vector_portable_PortableVector coefficients[16U]; +} libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector; + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector( + void) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + lit; + lit.coefficients[0U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[1U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[2U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[3U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[4U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[5U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[6U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[7U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[8U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[9U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[10U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[11U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[12U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[13U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[14U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + lit.coefficients[15U] = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(); + return lit; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_ind_cpa_deserialize_then_decompress_u_closure__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1088size_t_10size_t( + size_t _) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_decompress_ciphertext_coefficient___10int32_t( + libcrux_ml_kem_vector_portable_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + int32_t decompressed = (int32_t)v.elements[i0] * + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)10); + decompressed = decompressed >> (uint32_t)((int32_t)10 + (int32_t)1); + v.elements[i0] = (int16_t)decompressed; + } + return v; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___decompress_ciphertext_coefficient___10int32_t( + libcrux_ml_kem_vector_portable_PortableVector v) { + return libcrux_ml_kem_vector_decompress_ciphertext_coefficient___10int32_t(v); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_serialize_deserialize_then_decompress_10__libcrux_ml_kem_vector_portable_PortableVector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)20U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * (size_t)20U, .end = i0 * (size_t)20U + (size_t)20U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_vector_portable_PortableVector coefficient = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_10( + bytes); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___decompress_ciphertext_coefficient___10int32_t( + coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_decompress_ciphertext_coefficient___11int32_t( + libcrux_ml_kem_vector_portable_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + int32_t decompressed = (int32_t)v.elements[i0] * + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)11); + decompressed = decompressed >> (uint32_t)((int32_t)11 + (int32_t)1); + v.elements[i0] = (int16_t)decompressed; + } + return v; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___decompress_ciphertext_coefficient___11int32_t( + libcrux_ml_kem_vector_portable_PortableVector v) { + return libcrux_ml_kem_vector_decompress_ciphertext_coefficient___11int32_t(v); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_serialize_deserialize_then_decompress_11__libcrux_ml_kem_vector_portable_PortableVector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)22U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * (size_t)22U, .end = i0 * (size_t)22U + (size_t)22U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_vector_portable_PortableVector coefficient = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_11( + bytes); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___decompress_ciphertext_coefficient___11int32_t( + coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0; + uu____0 = + libcrux_ml_kem_serialize_deserialize_then_decompress_10__libcrux_ml_kem_vector_portable_PortableVector( + serialized); + return uu____0; +} + +typedef struct + K___libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector_s { + libcrux_ml_kem_vector_portable_PortableVector fst; + libcrux_ml_kem_vector_portable_PortableVector snd; +} K___libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector; + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_traits_montgomery_multiply_fe__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_vector_portable_PortableVector v, int16_t fer) { + return libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___montgomery_multiply_by_constant( + v, fer); +} + +static inline K___libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_ntt_ntt_layer_int_vec_step__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_vector_portable_PortableVector a, + libcrux_ml_kem_vector_portable_PortableVector b, int16_t zeta_r) { + libcrux_ml_kem_vector_portable_PortableVector t = + libcrux_ml_kem_vector_traits_montgomery_multiply_fe__libcrux_ml_kem_vector_portable_PortableVector( + b, zeta_r); + b = libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___sub( + a, &t); + a = libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add( + a, &t); + return (CLITERAL( + K___libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector){ + .fst = a, .snd = b}); +} + +static inline void +libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + size_t layer, size_t _initial_coefficient_bound) { + size_t step = (size_t)1U << (uint32_t)layer; + for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { + size_t round = i0; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + size_t offset = round * step * (size_t)2U; + size_t offset_vec = offset / (size_t)16U; + size_t step_vec = step / (size_t)16U; + for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { + size_t j = i; + K___libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + libcrux_ml_kem_ntt_ntt_layer_int_vec_step__libcrux_ml_kem_vector_portable_PortableVector( + re->coefficients[j], re->coefficients[j + step_vec], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R + [zeta_i[0U]]); + libcrux_ml_kem_vector_portable_PortableVector x = uu____0.fst; + libcrux_ml_kem_vector_portable_PortableVector y = uu____0.snd; + re->coefficients[j] = x; + re->coefficients[j + step_vec] = y; + } + } +} + +static inline void +libcrux_ml_kem_ntt_ntt_at_layer_3__libcrux_ml_kem_vector_portable_PortableVector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + size_t _layer, size_t _initial_coefficient_bound) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_layer_3_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + re->coefficients[round] = uu____0;); +} + +static inline void +libcrux_ml_kem_ntt_ntt_at_layer_2__libcrux_ml_kem_vector_portable_PortableVector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + size_t _layer, size_t _initial_coefficient_bound) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_layer_2_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)1U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] + (size_t)1U;); +} + +static inline void +libcrux_ml_kem_ntt_ntt_at_layer_1__libcrux_ml_kem_vector_portable_PortableVector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + size_t _layer, size_t _initial_coefficient_bound) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_layer_1_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)3U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] + (size_t)3U;); +} + +static inline void +libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___poly_barrett_reduce__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *self) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce( + self->coefficients[i0]); + self->coefficients[i0] = uu____0; + } +} + +static inline void +libcrux_ml_kem_ntt_ntt_vector_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re) { + size_t zeta_i = (size_t)0U; + libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)7U, (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)6U, (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)5U, (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)4U, (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_3__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)3U, (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_2__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)2U, (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_1__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)1U, (size_t)3328U); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___poly_barrett_reduce__libcrux_ml_kem_vector_portable_PortableVector( + re); +} + +static inline void +libcrux_ml_kem_ind_cpa_deserialize_then_decompress_u__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1088size_t_10size_t( + uint8_t *ciphertext, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + u_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + u_as_ntt[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len( + Eurydice_array_to_slice((size_t)1088U, ciphertext, uint8_t, + Eurydice_slice), + uint8_t, size_t) / + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U); + i++) { + size_t i0 = i; + Eurydice_slice u_bytes = Eurydice_array_to_subslice( + (size_t)1088U, ciphertext, + (CLITERAL(core_ops_range_Range__size_t){ + .start = + i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U), + .end = i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U) + + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t( + u_bytes); + u_as_ntt[i0] = uu____0; + libcrux_ml_kem_ntt_ntt_vector_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t( + &u_as_ntt[i0]); + } + memcpy( + ret, u_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_decompress_ciphertext_coefficient___4int32_t( + libcrux_ml_kem_vector_portable_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + int32_t decompressed = (int32_t)v.elements[i0] * + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)4); + decompressed = decompressed >> (uint32_t)((int32_t)4 + (int32_t)1); + v.elements[i0] = (int16_t)decompressed; + } + return v; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___decompress_ciphertext_coefficient___4int32_t( + libcrux_ml_kem_vector_portable_PortableVector v) { + return libcrux_ml_kem_vector_decompress_ciphertext_coefficient___4int32_t(v); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_serialize_deserialize_then_decompress_4__libcrux_ml_kem_vector_portable_PortableVector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)8U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * (size_t)8U, .end = i0 * (size_t)8U + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_vector_portable_PortableVector coefficient = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_4( + bytes); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___decompress_ciphertext_coefficient___4int32_t( + coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_decompress_ciphertext_coefficient___5int32_t( + libcrux_ml_kem_vector_portable_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + int32_t decompressed = (int32_t)v.elements[i0] * + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)5); + decompressed = decompressed >> (uint32_t)((int32_t)5 + (int32_t)1); + v.elements[i0] = (int16_t)decompressed; + } + return v; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___decompress_ciphertext_coefficient___5int32_t( + libcrux_ml_kem_vector_portable_PortableVector v) { + return libcrux_ml_kem_vector_decompress_ciphertext_coefficient___5int32_t(v); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_serialize_deserialize_then_decompress_5__libcrux_ml_kem_vector_portable_PortableVector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)10U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * (size_t)10U, .end = i0 * (size_t)10U + (size_t)10U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_5( + bytes); + re.coefficients[i0] = uu____0; + libcrux_ml_kem_vector_portable_PortableVector uu____1 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___decompress_ciphertext_coefficient___5int32_t( + re.coefficients[i0]); + re.coefficients[i0] = uu____1; + } + return re; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_4size_t( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0; + uu____0 = + libcrux_ml_kem_serialize_deserialize_then_decompress_4__libcrux_ml_kem_vector_portable_PortableVector( + serialized); + return uu____0; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_ind_cpa_deserialize_secret_key_closure__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + size_t _) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_serialize_deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * (size_t)24U, .end = i0 * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_12( + bytes); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline void +libcrux_ml_kem_ind_cpa_deserialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + Eurydice_slice secret_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + secret_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + secret_as_ntt[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(secret_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice secret_bytes = Eurydice_slice_subslice( + secret_key, + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + libcrux_ml_kem_serialize_deserialize_to_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + secret_bytes); + secret_as_ntt[i0] = uu____0; + } + memcpy( + ret, secret_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *rhs) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + out = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ntt_multiply( + &self->coefficients[i0], &rhs->coefficients[i0], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0 + + (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0 + + (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0 + + (size_t)3U]); + out.coefficients[i0] = uu____0; + } + return out; +} + +static inline void +libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *rhs) { + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)16U, self->coefficients, + libcrux_ml_kem_vector_portable_PortableVector, Eurydice_slice), + libcrux_ml_kem_vector_portable_PortableVector, size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add( + self->coefficients[i0], &rhs->coefficients[i0]); + self->coefficients[i0] = uu____0; + } +} + +static inline void +libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_1__libcrux_ml_kem_vector_portable_PortableVector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + size_t _layer) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___inv_ntt_layer_1_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)3U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] - (size_t)3U;); +} + +static inline void +libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_2__libcrux_ml_kem_vector_portable_PortableVector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + size_t _layer) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___inv_ntt_layer_2_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)1U]); + re->coefficients[round] = uu____0; zeta_i[0U] = zeta_i[0U] - (size_t)1U;); +} + +static inline void +libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_3__libcrux_ml_kem_vector_portable_PortableVector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + size_t _layer) { + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___inv_ntt_layer_3_step( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + re->coefficients[round] = uu____0;); +} + +static inline K___libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_invert_ntt_inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_vector_portable_PortableVector a, + libcrux_ml_kem_vector_portable_PortableVector b, int16_t zeta_r) { + libcrux_ml_kem_vector_portable_PortableVector a_minus_b = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___sub( + b, &a); + a = libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce( + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add( + a, &b)); + b = libcrux_ml_kem_vector_traits_montgomery_multiply_fe__libcrux_ml_kem_vector_portable_PortableVector( + a_minus_b, zeta_r); + return (CLITERAL( + K___libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector){ + .fst = a, .snd = b}); +} + +static inline void +libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + size_t *zeta_i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + size_t layer) { + size_t step = (size_t)1U << (uint32_t)layer; + for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { + size_t round = i0; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + size_t offset = round * step * (size_t)2U; + size_t offset_vec = + offset / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; + size_t step_vec = + step / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; + for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { + size_t j = i; + K___libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + libcrux_ml_kem_invert_ntt_inv_ntt_layer_int_vec_step_reduce__libcrux_ml_kem_vector_portable_PortableVector( + re->coefficients[j], re->coefficients[j + step_vec], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R + [zeta_i[0U]]); + libcrux_ml_kem_vector_portable_PortableVector x = uu____0.fst; + libcrux_ml_kem_vector_portable_PortableVector y = uu____0.snd; + re->coefficients[j] = x; + re->coefficients[j + step_vec] = y; + } + } +} + +static inline void +libcrux_ml_kem_invert_ntt_invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re) { + size_t zeta_i = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_1__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)1U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_2__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)2U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_3__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)3U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)4U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)5U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)6U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)7U); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___poly_barrett_reduce__libcrux_ml_kem_vector_portable_PortableVector( + re); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___subtract_reduce__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + b) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector coefficient_normal_form = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___montgomery_multiply_by_constant( + b.coefficients[i0], (int16_t)1441); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce( + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___sub( + self->coefficients[i0], &coefficient_normal_form)); + b.coefficients[i0] = uu____0; + } + return b; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_matrix_compute_message__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *v, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *secret_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *u_as_ntt) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + product = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector( + &secret_as_ntt[i0], &u_as_ntt[i0]); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + &result, &product);); + libcrux_ml_kem_invert_ntt_invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + &result); + result = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___subtract_reduce__libcrux_ml_kem_vector_portable_PortableVector( + v, result); + return result; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_shift_right___15int32_t( + libcrux_ml_kem_vector_portable_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + v.elements[i0] = v.elements[i0] >> (uint32_t)(int32_t)15; + } + return v; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___shift_right___15int32_t( + libcrux_ml_kem_vector_portable_PortableVector v) { + return libcrux_ml_kem_vector_shift_right___15int32_t(v); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_vector_portable_PortableVector a) { + libcrux_ml_kem_vector_portable_PortableVector t = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___shift_right___15int32_t( + a); + libcrux_ml_kem_vector_portable_PortableVector fm = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___bitwise_and_with_constant( + t, LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + return libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add( + a, &fm); +} + +static inline void +libcrux_ml_kem_serialize_compress_then_serialize_message__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re, + uint8_t ret[32U]) { + uint8_t serialized[32U] = {0U}; + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector coefficient = + libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector( + re.coefficients[i0]); + libcrux_ml_kem_vector_portable_PortableVector coefficient_compressed = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___compress_1( + coefficient); + uint8_t bytes[2U]; + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_1( + coefficient_compressed, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)32U, serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)2U * i0, .end = (size_t)2U * i0 + (size_t)2U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)2U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *);); + memcpy(ret, serialized, (size_t)32U * sizeof(uint8_t)); +} + +static inline void +libcrux_ml_kem_ind_cpa_decrypt__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1088size_t_960size_t_10size_t_4size_t( + Eurydice_slice secret_key, uint8_t *ciphertext, uint8_t ret[32U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + u_as_ntt[3U]; + libcrux_ml_kem_ind_cpa_deserialize_then_decompress_u__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1088size_t_10size_t( + ciphertext, u_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + v = libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_4size_t( + Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, + (size_t)960U, uint8_t, size_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + secret_as_ntt[3U]; + libcrux_ml_kem_ind_cpa_deserialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + secret_key, secret_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + message = + libcrux_ml_kem_matrix_compute_message__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + &v, secret_as_ntt, u_as_ntt); + uint8_t ret0[32U]; + libcrux_ml_kem_serialize_compress_then_serialize_message__libcrux_ml_kem_vector_portable_PortableVector( + message, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +static inline void +libcrux_ml_kem_hash_functions_portable___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__portable__PortableHash_K____G___3size_t( + Eurydice_slice input, uint8_t ret[64U]) { + uint8_t digest[64U] = {0U}; + libcrux_sha3_portable_sha512( + Eurydice_array_to_slice((size_t)64U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); +} + +static inline void +libcrux_ml_kem_hash_functions_portable___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__portable__PortableHash_K____PRF___3size_t_32size_t( + Eurydice_slice input, uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_closure__libcrux_ml_kem_vector_portable_PortableVector_1152size_t_3size_t( + size_t _i) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + for (size_t i = (size_t)0U; + i < + core_slice___Slice_T___len(serialized, uint8_t, size_t) / (size_t)24U; + i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice( + serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * (size_t)24U, .end = i0 * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_vector_portable_PortableVector coefficient = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_12( + bytes); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___cond_subtract_3329( + coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +static inline void +libcrux_ml_kem_serialize_deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_1152size_t_3size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + deserialized_pk[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + deserialized_pk[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_matrix_sample_matrix_A_closure_closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + size_t _j) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline void +libcrux_ml_kem_matrix_sample_matrix_A_closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + size_t _i, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret0[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + ret0[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + memcpy( + ret, ret0, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); +} + +typedef struct + libcrux_ml_kem_hash_functions_portable_PortableHash____3size_t_s { + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t shake128_state[3U]; +} libcrux_ml_kem_hash_functions_portable_PortableHash____3size_t; + +static inline libcrux_ml_kem_hash_functions_portable_PortableHash____3size_t +libcrux_ml_kem_hash_functions_portable___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__portable__PortableHash_K____shake128_init_absorb___3size_t( + uint8_t input[3U][34U]) { + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t state[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + state[i] = libcrux_sha3_portable_incremental_shake128_init();); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = + &state[i0]; + libcrux_sha3_portable_incremental_shake128_absorb_final( + uu____0, Eurydice_array_to_slice((size_t)34U, input[i0], uint8_t, + Eurydice_slice));); + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t uu____1[3U]; + memcpy( + uu____1, state, + (size_t)3U * + sizeof(libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); + libcrux_ml_kem_hash_functions_portable_PortableHash____3size_t lit; + memcpy( + lit.shake128_state, uu____1, + (size_t)3U * + sizeof(libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t)); + return lit; +} + +static inline void +libcrux_ml_kem_hash_functions_portable___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__portable__PortableHash_K____shake128_squeeze_three_blocks___3size_t( + libcrux_ml_kem_hash_functions_portable_PortableHash____3size_t *self, + uint8_t ret[3U][504U]) { + uint8_t out[3U][504U] = {{0U}}; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = + &self->shake128_state[i0]; + libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks( + uu____0, Eurydice_array_to_slice((size_t)504U, out[i0], uint8_t, + Eurydice_slice));); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[504U])); +} + +static inline bool +libcrux_ml_kem_sampling_sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_3size_t_504size_t( + uint8_t randomness[3U][504U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)504U, randomness[i1], + (CLITERAL(core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + (CLITERAL(core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); + return done; +} + +static inline void +libcrux_ml_kem_hash_functions_portable___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__portable__PortableHash_K____shake128_squeeze_block___3size_t( + libcrux_ml_kem_hash_functions_portable_PortableHash____3size_t *self, + uint8_t ret[3U][168U]) { + uint8_t out[3U][168U] = {{0U}}; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = + &self->shake128_state[i0]; + libcrux_sha3_portable_incremental_shake128_squeeze_next_block( + uu____0, Eurydice_array_to_slice((size_t)168U, out[i0], uint8_t, + Eurydice_slice));); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[168U])); +} + +static inline bool +libcrux_ml_kem_sampling_sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_3size_t_168size_t( + uint8_t randomness[3U][168U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)168U, randomness[i1], + (CLITERAL(core_ops_range_Range__size_t){ + .start = r * (size_t)24U, + .end = r * (size_t)24U + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + size_t sampled = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___rej_sample( + uu____0, + Eurydice_array_to_subslice( + (size_t)272U, out[i1], + (CLITERAL(core_ops_range_Range__size_t){ + .start = sampled_coefficients[i1], + .end = sampled_coefficients[i1] + (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = + sampled_coefficients[uu____1] + sampled; + } + }); + bool done = true; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { done = false; }); + return done; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___from_i16_array__libcrux_ml_kem_vector_portable_PortableVector( + Eurydice_slice a) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___from_i16_array( + Eurydice_slice_subslice( + a, + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * (size_t)16U, + .end = (i0 + (size_t)1U) * (size_t)16U}), + int16_t, core_ops_range_Range__size_t, Eurydice_slice)); + result.coefficients[i0] = uu____0; + } + return result; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_sampling_sample_from_xof_closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + int16_t s[272U]) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___from_i16_array__libcrux_ml_kem_vector_portable_PortableVector( + Eurydice_array_to_subslice((size_t)272U, s, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)256U}), + int16_t, core_ops_range_Range__size_t, + Eurydice_slice)); +} + +static inline void +libcrux_ml_kem_sampling_sample_from_xof__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + uint8_t seeds[3U][34U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[3U]) { + size_t sampled_coefficients[3U] = {0U}; + int16_t out[3U][272U] = {{0U}}; + uint8_t uu____0[3U][34U]; + memcpy(uu____0, seeds, (size_t)3U * sizeof(uint8_t[34U])); + libcrux_ml_kem_hash_functions_portable_PortableHash____3size_t xof_state = + libcrux_ml_kem_hash_functions_portable___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__portable__PortableHash_K____shake128_init_absorb___3size_t( + uu____0); + uint8_t randomness0[3U][504U]; + libcrux_ml_kem_hash_functions_portable___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__portable__PortableHash_K____shake128_squeeze_three_blocks___3size_t( + &xof_state, randomness0); + uint8_t uu____1[3U][504U]; + memcpy(uu____1, randomness0, (size_t)3U * sizeof(uint8_t[504U])); + bool done = + libcrux_ml_kem_sampling_sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_3size_t_504size_t( + uu____1, sampled_coefficients, out); + while (true) { + if (done) { + break; + } else { + uint8_t randomness[3U][168U]; + libcrux_ml_kem_hash_functions_portable___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__portable__PortableHash_K____shake128_squeeze_block___3size_t( + &xof_state, randomness); + uint8_t uu____2[3U][168U]; + memcpy(uu____2, randomness, (size_t)3U * sizeof(uint8_t[168U])); + done = + libcrux_ml_kem_sampling_sample_from_uniform_distribution_next__libcrux_ml_kem_vector_portable_PortableVector_3size_t_168size_t( + uu____2, sampled_coefficients, out); + } + } + int16_t uu____3[3U][272U]; + memcpy(uu____3, out, (size_t)3U * sizeof(int16_t[272U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret0[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + ret0[i] = + libcrux_ml_kem_sampling_sample_from_xof_closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + uu____3[i]);); + memcpy( + ret, ret0, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); +} + +static inline void +libcrux_ml_kem_matrix_sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + uint8_t seed[34U], bool transpose, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[3U][3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + A_transpose[3U][3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + libcrux_ml_kem_matrix_sample_matrix_A_closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + i, A_transpose[i]);); + KRML_MAYBE_FOR3( + i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0; + uint8_t uu____0[34U]; + memcpy(uu____0, seed, (size_t)34U * sizeof(uint8_t)); + uint8_t seeds[3U][34U]; KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + memcpy(seeds[i], uu____0, (size_t)34U * sizeof(uint8_t));); + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t j = i; + seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;); + uint8_t uu____1[3U][34U]; + memcpy(uu____1, seeds, (size_t)3U * sizeof(uint8_t[34U])); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + sampled[3U]; + libcrux_ml_kem_sampling_sample_from_xof__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + uu____1, sampled); + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, sampled, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + sample = sampled[j]; + if (transpose) { + A_transpose[j][i1] = sample; + } else { + A_transpose[i1][j] = sample; + } + }); + memcpy( + ret, A_transpose, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + [3U])); +} + +typedef struct + K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t_s { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + fst[3U]; + uint8_t snd; +} K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t; + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( + size_t _i) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline void +libcrux_ml_kem_hash_functions_portable___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__portable__PortableHash_K____PRFxN___3size_t_128size_t( + uint8_t (*input)[33U], uint8_t ret[3U][128U]) { + uint8_t out[3U][128U] = {{0U}}; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_array_to_slice((size_t)128U, out[i0], + uint8_t, Eurydice_slice); + libcrux_sha3_portable_shake256( + uu____0, Eurydice_array_to_slice((size_t)33U, input[i0], uint8_t, + Eurydice_slice));); + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[128U])); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_sampling_sample_from_binomial_distribution_2__libcrux_ml_kem_vector_portable_PortableVector( + Eurydice_slice randomness) { + int16_t sampled_i16s[256U] = {0U}; + for (size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)4U; + i0++) { + size_t chunk_number = i0; + Eurydice_slice byte_chunk = Eurydice_slice_subslice( + randomness, + (CLITERAL(core_ops_range_Range__size_t){ + .start = chunk_number * (size_t)4U, + .end = chunk_number * (size_t)4U + (size_t)4U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint32_t uu____0 = (uint32_t)Eurydice_slice_index( + byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); + uint32_t uu____1 = + uu____0 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, + uint8_t, uint8_t *, uint8_t) + << 8U; + uint32_t uu____2 = + uu____1 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, + uint8_t, uint8_t *, uint8_t) + << 16U; + uint32_t random_bits_as_u32 = + uu____2 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)3U, + uint8_t, uint8_t *, uint8_t) + << 24U; + uint32_t even_bits = random_bits_as_u32 & 1431655765U; + uint32_t odd_bits = random_bits_as_u32 >> 1U & 1431655765U; + uint32_t coin_toss_outcomes = even_bits + odd_bits; + for (uint32_t i = 0U; i < CORE_NUM__U32_8__BITS / 4U; i++) { + uint32_t outcome_set = i; + uint32_t outcome_set0 = outcome_set * 4U; + int16_t outcome_1 = + (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 3U); + int16_t outcome_2 = + (int16_t)(coin_toss_outcomes >> (uint32_t)(outcome_set0 + 2U) & 3U); + size_t offset = (size_t)(outcome_set0 >> 2U); + sampled_i16s[(size_t)8U * chunk_number + offset] = outcome_1 - outcome_2; + } + } + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___from_i16_array__libcrux_ml_kem_vector_portable_PortableVector( + Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t, + Eurydice_slice)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_sampling_sample_from_binomial_distribution_3__libcrux_ml_kem_vector_portable_PortableVector( + Eurydice_slice randomness) { + int16_t sampled_i16s[256U] = {0U}; + for (size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len(randomness, uint8_t, size_t) / (size_t)3U; + i0++) { + size_t chunk_number = i0; + Eurydice_slice byte_chunk = Eurydice_slice_subslice( + randomness, + (CLITERAL(core_ops_range_Range__size_t){ + .start = chunk_number * (size_t)3U, + .end = chunk_number * (size_t)3U + (size_t)3U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint32_t uu____0 = (uint32_t)Eurydice_slice_index( + byte_chunk, (size_t)0U, uint8_t, uint8_t *, uint8_t); + uint32_t uu____1 = + uu____0 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, + uint8_t, uint8_t *, uint8_t) + << 8U; + uint32_t random_bits_as_u24 = + uu____1 | (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, + uint8_t, uint8_t *, uint8_t) + << 16U; + uint32_t first_bits = random_bits_as_u24 & 2396745U; + uint32_t second_bits = random_bits_as_u24 >> 1U & 2396745U; + uint32_t third_bits = random_bits_as_u24 >> 2U & 2396745U; + uint32_t coin_toss_outcomes = first_bits + second_bits + third_bits; + for (int32_t i = (int32_t)0; i < (int32_t)24 / (int32_t)6; i++) { + int32_t outcome_set = i; + int32_t outcome_set0 = outcome_set * (int32_t)6; + int16_t outcome_1 = + (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 7U); + int16_t outcome_2 = (int16_t)(coin_toss_outcomes >> + (uint32_t)(outcome_set0 + (int32_t)3) & + 7U); + size_t offset = (size_t)(outcome_set0 / (int32_t)6); + sampled_i16s[(size_t)4U * chunk_number + offset] = outcome_1 - outcome_2; + } + } + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___from_i16_array__libcrux_ml_kem_vector_portable_PortableVector( + Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t, + Eurydice_slice)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + Eurydice_slice randomness) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0; + uu____0 = + libcrux_ml_kem_sampling_sample_from_binomial_distribution_2__libcrux_ml_kem_vector_portable_PortableVector( + randomness); + return uu____0; +} + +static inline void +libcrux_ml_kem_ntt_ntt_at_layer_7__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re) { + size_t step = LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT / (size_t)2U; + for (size_t i = (size_t)0U; i < step; i++) { + size_t j = i; + libcrux_ml_kem_vector_portable_PortableVector t = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___multiply_by_constant( + re->coefficients[j + step], (int16_t)-1600); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___sub( + re->coefficients[j], &t); + re->coefficients[j + step] = uu____0; + libcrux_ml_kem_vector_portable_PortableVector uu____1 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add( + re->coefficients[j], &t); + re->coefficients[j] = uu____1; + } +} + +static inline void +libcrux_ml_kem_ntt_ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re) { + libcrux_ml_kem_ntt_ntt_at_layer_7__libcrux_ml_kem_vector_portable_PortableVector( + re); + size_t zeta_i = (size_t)1U; + libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)6U, (size_t)3U); + libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)5U, (size_t)3U); + libcrux_ml_kem_ntt_ntt_at_layer_4_plus__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)4U, (size_t)3U); + libcrux_ml_kem_ntt_ntt_at_layer_3__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)3U, (size_t)3U); + libcrux_ml_kem_ntt_ntt_at_layer_2__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)2U, (size_t)3U); + libcrux_ml_kem_ntt_ntt_at_layer_1__libcrux_ml_kem_vector_portable_PortableVector( + &zeta_i, re, (size_t)1U, (size_t)3U); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___poly_barrett_reduce__libcrux_ml_kem_vector_portable_PortableVector( + re); +} + +static inline K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t +libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re_as_ntt[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + re_as_ntt[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[3U][33U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[3U][128U]; + libcrux_ml_kem_hash_functions_portable___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__portable__PortableHash_K____PRFxN___3size_t_128size_t( + prf_inputs, prf_outputs); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____1 = + libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + re_as_ntt[i0] = uu____1; + libcrux_ml_kem_ntt_ntt_binomially_sampled_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + &re_as_ntt[i0]);); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____2[3U]; + memcpy( + uu____2, re_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); + K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t + lit; + memcpy( + lit.fst, uu____2, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); + lit.snd = domain_separator; + return lit; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_ind_cpa_sample_ring_element_cbd_closure__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_128size_t_2size_t( + size_t _i) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t +libcrux_ml_kem_ind_cpa_sample_ring_element_cbd__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_128size_t_2size_t( + uint8_t prf_input[33U], uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_1[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + error_1[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[3U][33U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + memcpy(prf_inputs[i], uu____0, (size_t)33U * sizeof(uint8_t));); + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + uint8_t prf_outputs[3U][128U]; + libcrux_ml_kem_hash_functions_portable___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__portable__PortableHash_K____PRFxN___3size_t_128size_t( + prf_inputs, prf_outputs); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____1 = + libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], + uint8_t, Eurydice_slice)); + error_1[i0] = uu____1;); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____2[3U]; + memcpy( + uu____2, error_1, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); + K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t + lit; + memcpy( + lit.fst, uu____2, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); + lit.snd = domain_separator; + return lit; +} + +static inline void +libcrux_ml_kem_hash_functions_portable___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__portable__PortableHash_K____PRF___3size_t_128size_t( + Eurydice_slice input, uint8_t ret[128U]) { + uint8_t digest[128U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)128U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_matrix_compute_vector_u_closure__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + size_t _i) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline void +libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_error_reduce__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *error) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t j = i; + libcrux_ml_kem_vector_portable_PortableVector coefficient_normal_form = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___montgomery_multiply_by_constant( + self->coefficients[j], (int16_t)1441); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce( + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add( + coefficient_normal_form, &error->coefficients[j])); + self->coefficients[j] = uu____0; + } +} + +static inline void +libcrux_ml_kem_matrix_compute_vector_u__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector ( + *a_as_ntt)[3U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *error_1, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + result[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, a_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + [3U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + [3U], + size_t); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *row = a_as_ntt[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *a_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + product = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector( + a_element, &r_as_ntt[j]); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + &result[i1], &product); + } + libcrux_ml_kem_invert_ntt_invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + &result[i1]); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_error_reduce__libcrux_ml_kem_vector_portable_PortableVector( + &result[i1], &error_1[i1]); + } + memcpy( + ret, result, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_traits_decompress_1__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_vector_portable_PortableVector v) { + return libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___bitwise_and_with_constant( + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___sub( + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___ZERO(), + &v), + (int16_t)1665); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_serialize_deserialize_then_decompress_message__libcrux_ml_kem_vector_portable_PortableVector( + uint8_t serialized[32U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + KRML_MAYBE_FOR16( + i, (size_t)0U, (size_t)16U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector coefficient_compressed = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___deserialize_1( + Eurydice_array_to_subslice( + (size_t)32U, serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)2U * i0, + .end = (size_t)2U * i0 + (size_t)2U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector_traits_decompress_1__libcrux_ml_kem_vector_portable_PortableVector( + coefficient_compressed); + re.coefficients[i0] = uu____0;); + return re; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_message_error_reduce__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *message, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector coefficient_normal_form = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___montgomery_multiply_by_constant( + result.coefficients[i0], (int16_t)1441); + libcrux_ml_kem_vector_portable_PortableVector tmp = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add( + self->coefficients[i0], &message->coefficients[i0]); + libcrux_ml_kem_vector_portable_PortableVector tmp0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add( + coefficient_normal_form, &tmp); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce( + tmp0); + result.coefficients[i0] = uu____0; + } + return result; +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_matrix_compute_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *t_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *error_2, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *message) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector(); + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + product = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector( + &t_as_ntt[i0], &r_as_ntt[i0]); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + &result, &product);); + libcrux_ml_kem_invert_ntt_invert_ntt_montgomery__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + &result); + result = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_message_error_reduce__libcrux_ml_kem_vector_portable_PortableVector( + error_2, message, result); + return result; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_compress___10int32_t( + libcrux_ml_kem_vector_portable_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + int16_t uu____0 = libcrux_ml_kem_vector_compress_ciphertext_coefficient( + (uint8_t)(int32_t)10, (uint16_t)v.elements[i0]); + v.elements[i0] = uu____0; + } + return v; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___compress___10int32_t( + libcrux_ml_kem_vector_portable_PortableVector v) { + return libcrux_ml_kem_vector_compress___10int32_t(v); +} + +static inline void +libcrux_ml_kem_serialize_compress_then_serialize_10__libcrux_ml_kem_vector_portable_PortableVector_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + uint8_t ret[320U]) { + uint8_t serialized[320U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector coefficient = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___compress___10int32_t( + libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector( + re->coefficients[i0])); + uint8_t bytes[20U]; + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_10( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)320U, serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)20U * i0, .end = (size_t)20U * i0 + (size_t)20U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)20U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_compress___11int32_t( + libcrux_ml_kem_vector_portable_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + int16_t uu____0 = libcrux_ml_kem_vector_compress_ciphertext_coefficient( + (uint8_t)(int32_t)11, (uint16_t)v.elements[i0]); + v.elements[i0] = uu____0; + } + return v; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___compress___11int32_t( + libcrux_ml_kem_vector_portable_PortableVector v) { + return libcrux_ml_kem_vector_compress___11int32_t(v); +} + +static inline void +libcrux_ml_kem_serialize_compress_then_serialize_11__libcrux_ml_kem_vector_portable_PortableVector_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + uint8_t ret[320U]) { + uint8_t serialized[320U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector coefficient = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___compress___11int32_t( + libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector( + re->coefficients[i0])); + uint8_t bytes[22U]; + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_11( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)320U, serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)22U * i0, .end = (size_t)22U * i0 + (size_t)22U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)22U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); +} + +static inline void +libcrux_ml_kem_serialize_compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + uint8_t ret[320U]) { + uint8_t uu____0[320U]; + libcrux_ml_kem_serialize_compress_then_serialize_10__libcrux_ml_kem_vector_portable_PortableVector_320size_t( + re, uu____0); + memcpy(ret, uu____0, (size_t)320U * sizeof(uint8_t)); +} + +static inline void +libcrux_ml_kem_ind_cpa_compress_then_serialize_u__libcrux_ml_kem_vector_portable_PortableVector_3size_t_960size_t_10size_t_320size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + input[3U], + Eurydice_slice out) { + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, input, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = input[i0]; + Eurydice_slice uu____0 = Eurydice_slice_subslice( + out, + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * ((size_t)960U / (size_t)3U), + .end = (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret[320U]; + libcrux_ml_kem_serialize_compress_then_serialize_ring_element_u__libcrux_ml_kem_vector_portable_PortableVector_10size_t_320size_t( + &re, ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)320U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_compress___4int32_t( + libcrux_ml_kem_vector_portable_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + int16_t uu____0 = libcrux_ml_kem_vector_compress_ciphertext_coefficient( + (uint8_t)(int32_t)4, (uint16_t)v.elements[i0]); + v.elements[i0] = uu____0; + } + return v; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___compress___4int32_t( + libcrux_ml_kem_vector_portable_PortableVector v) { + return libcrux_ml_kem_vector_compress___4int32_t(v); +} + +static inline void +libcrux_ml_kem_serialize_compress_then_serialize_4__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re, + Eurydice_slice serialized) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector coefficient = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___compress___4int32_t( + libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector( + re.coefficients[i0])); + uint8_t bytes[8U]; + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_4( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_slice_subslice( + serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)8U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_compress___5int32_t( + libcrux_ml_kem_vector_portable_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + int16_t uu____0 = libcrux_ml_kem_vector_compress_ciphertext_coefficient( + (uint8_t)(int32_t)5, (uint16_t)v.elements[i0]); + v.elements[i0] = uu____0; + } + return v; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___compress___5int32_t( + libcrux_ml_kem_vector_portable_PortableVector v) { + return libcrux_ml_kem_vector_compress___5int32_t(v); +} + +static inline void +libcrux_ml_kem_serialize_compress_then_serialize_5__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re, + Eurydice_slice serialized) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector coefficients = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___compress___5int32_t( + libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector( + re.coefficients[i0])); + uint8_t bytes[10U]; + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_5( + coefficients, bytes); + Eurydice_slice uu____0 = Eurydice_slice_subslice( + serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)10U * i0, .end = (size_t)10U * i0 + (size_t)10U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)10U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline void +libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_4size_t_128size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re, + Eurydice_slice out) { + libcrux_ml_kem_serialize_compress_then_serialize_4__libcrux_ml_kem_vector_portable_PortableVector( + re, out); +} + +static inline void +libcrux_ml_kem_ind_cpa_encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, + uint8_t ret[1088U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + t_as_ntt[3U]; + libcrux_ml_kem_serialize_deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_1152size_t_3size_t( + Eurydice_slice_subslice_to(public_key, (size_t)1152U, uint8_t, size_t, + Eurydice_slice), + t_as_ntt); + Eurydice_slice seed = Eurydice_slice_subslice_from( + public_key, (size_t)1152U, uint8_t, size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + A_transpose[3U][3U]; + uint8_t ret0[34U]; + libcrux_ml_kem_utils_into_padded_array___34size_t(seed, ret0); + libcrux_ml_kem_matrix_sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + ret0, false, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_utils_into_padded_array___33size_t(randomness, prf_input); + uint8_t uu____0[33U]; + memcpy(uu____0, prf_input, (size_t)33U * sizeof(uint8_t)); + K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t + uu____1 = + libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( + uu____0, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + r_as_ntt[3U]; + memcpy( + r_as_ntt, uu____1.fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); + uint8_t domain_separator0 = uu____1.snd; + uint8_t uu____2[33U]; + memcpy(uu____2, prf_input, (size_t)33U * sizeof(uint8_t)); + K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t + uu____3 = + libcrux_ml_kem_ind_cpa_sample_ring_element_cbd__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_128size_t_2size_t( + uu____2, domain_separator0); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_1[3U]; + memcpy( + error_1, uu____3.fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); + uint8_t domain_separator = uu____3.snd; + prf_input[32U] = domain_separator; + uint8_t prf_output[128U]; + libcrux_ml_kem_hash_functions_portable___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__portable__PortableHash_K____PRF___3size_t_128size_t( + Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t, Eurydice_slice), + prf_output); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_2 = + libcrux_ml_kem_sampling_sample_from_binomial_distribution__libcrux_ml_kem_vector_portable_PortableVector_2size_t( + Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t, + Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + u[3U]; + libcrux_ml_kem_matrix_compute_vector_u__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + A_transpose, r_as_ntt, error_1, u); + uint8_t uu____4[32U]; + memcpy(uu____4, message, (size_t)32U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + message_as_ring_element = + libcrux_ml_kem_serialize_deserialize_then_decompress_message__libcrux_ml_kem_vector_portable_PortableVector( + uu____4); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + v = libcrux_ml_kem_matrix_compute_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); + uint8_t ciphertext[1088U] = {0U}; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____5[3U]; + memcpy( + uu____5, u, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); + libcrux_ml_kem_ind_cpa_compress_then_serialize_u__libcrux_ml_kem_vector_portable_PortableVector_3size_t_960size_t_10size_t_320size_t( + uu____5, Eurydice_array_to_subslice( + (size_t)1088U, ciphertext, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)960U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____6 = v; + libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v__libcrux_ml_kem_vector_portable_PortableVector_4size_t_128size_t( + uu____6, + Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, (size_t)960U, + uint8_t, size_t, Eurydice_slice)); + memcpy(ret, ciphertext, (size_t)1088U * sizeof(uint8_t)); +} + +static inline void +libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t, + Eurydice_slice), + (size_t)1152U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice secret_key0 = uu____0.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + secret_key0, (size_t)1184U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key = uu____1.fst; + Eurydice_slice secret_key = uu____1.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = + core_slice___Slice_T___split_at( + secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; + Eurydice_slice implicit_rejection_value = uu____2.snd; + uint8_t decrypted[32U]; + libcrux_ml_kem_ind_cpa_decrypt__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1088size_t_960size_t_10size_t_4size_t( + ind_cpa_secret_key, ciphertext->value, decrypted); + uint8_t to_hash0[64U]; + libcrux_ml_kem_utils_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t, Eurydice_slice), + to_hash0); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from( + (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice), + ind_cpa_public_key_hash, uint8_t, void *); + uint8_t hashed[64U]; + libcrux_ml_kem_hash_functions_portable___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__portable__PortableHash_K____G___3size_t( + Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____3.fst; + Eurydice_slice pseudorandomness = uu____3.snd; + uint8_t to_hash[1120U]; + libcrux_ml_kem_utils_into_padded_array___1120size_t(implicit_rejection_value, + to_hash); + Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( + ciphertext), + uint8_t, void *); + uint8_t implicit_rejection_shared_secret[32U]; + libcrux_ml_kem_hash_functions_portable___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__portable__PortableHash_K____PRF___3size_t_32size_t( + Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t, Eurydice_slice), + implicit_rejection_shared_secret); + Eurydice_slice uu____5 = ind_cpa_public_key; + uint8_t uu____6[32U]; + memcpy(uu____6, decrypted, (size_t)32U * sizeof(uint8_t)); + uint8_t expected_ciphertext[1088U]; + libcrux_ml_kem_ind_cpa_encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____5, uu____6, pseudorandomness, expected_ciphertext); + Eurydice_slice uu____7 = + libcrux_ml_kem_types___core__convert__AsRef__Slice_u8___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___1__as_ref___1088size_t( + ciphertext); + uint8_t selector = + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time___1088size_t( + uu____7, Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, + uint8_t, Eurydice_slice)); + Eurydice_slice uu____8 = shared_secret; + uint8_t ret0[32U]; + libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( + uu____8, + Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, + uint8_t, Eurydice_slice), + selector, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +static inline void +libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_decapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +static inline void libcrux_ml_kem_mlkem768_portable_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate___3size_t_2400size_t_1152size_t_1184size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t_1120size_t( + private_key, ciphertext, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +static inline void +libcrux_ml_kem_hash_functions_portable___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__portable__PortableHash_K____H___3size_t( + Eurydice_slice input, uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_sha256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t, Eurydice_slice), + input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +static inline K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { + uint8_t to_hash[64U]; + libcrux_ml_kem_utils_into_padded_array___64size_t( + Eurydice_array_to_slice((size_t)32U, randomness, uint8_t, Eurydice_slice), + to_hash); + Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( + (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + size_t, Eurydice_slice); + uint8_t ret[32U]; + libcrux_ml_kem_hash_functions_portable___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__portable__PortableHash_K____H___3size_t( + Eurydice_array_to_slice( + (size_t)1184U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( + public_key), + uint8_t, Eurydice_slice), + ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)32U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + uint8_t hashed[64U]; + libcrux_ml_kem_hash_functions_portable___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__portable__PortableHash_K____G___3size_t( + Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t, Eurydice_slice), + hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice shared_secret = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; + Eurydice_slice uu____2 = Eurydice_array_to_slice( + (size_t)1184U, + libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemPublicKey_SIZE__18__as_slice___1184size_t( + public_key), + uint8_t, Eurydice_slice); + uint8_t uu____3[32U]; + memcpy(uu____3, randomness, (size_t)32U * sizeof(uint8_t)); + uint8_t ciphertext[1088U]; + libcrux_ml_kem_ind_cpa_encrypt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____2, uu____3, pseudorandomness, ciphertext); + uint8_t shared_secret_array[32U] = {0U}; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_slice((size_t)32U, shared_secret_array, uint8_t, + Eurydice_slice), + shared_secret, uint8_t, void *); + uint8_t uu____4[1088U]; + memcpy(uu____4, ciphertext, (size_t)1088U * sizeof(uint8_t)); + libcrux_ml_kem_mlkem768_MlKem768Ciphertext uu____5 = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemCiphertext_SIZE___2__from___1088size_t( + uu____4); + uint8_t uu____6[32U]; + memcpy(uu____6, shared_secret_array, (size_t)32U * sizeof(uint8_t)); + K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ lit; + lit.fst = uu____5; + memcpy(lit.snd, uu____6, (size_t)32U * sizeof(uint8_t)); + return lit; +} + +static inline K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_encapsulate__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); +} + +static inline K___libcrux_ml_kem_types_MlKemCiphertext___1088size_t___uint8_t_32size_t_ +libcrux_ml_kem_mlkem768_portable_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey____1184size_t *uu____0 = public_key; + uint8_t uu____1[32U]; + memcpy(uu____1, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate___3size_t_1088size_t_1184size_t_1152size_t_960size_t_128size_t_10size_t_4size_t_320size_t_2size_t_128size_t_2size_t_128size_t( + uu____0, uu____1); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_matrix_compute_As_plus_e_closure__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + size_t _i) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_traits_to_standard_domain__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_vector_portable_PortableVector v) { + return libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___montgomery_multiply_by_constant( + v, LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS); +} + +static inline void +libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_standard_error_reduce__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *self, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *error) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t j = i; + libcrux_ml_kem_vector_portable_PortableVector coefficient_normal_form = + libcrux_ml_kem_vector_traits_to_standard_domain__libcrux_ml_kem_vector_portable_PortableVector( + self->coefficients[j]); + libcrux_ml_kem_vector_portable_PortableVector uu____0 = + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___barrett_reduce( + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___add( + coefficient_normal_form, &error->coefficients[j])); + self->coefficients[j] = uu____0; + } +} + +static inline void +libcrux_ml_kem_matrix_compute_As_plus_e__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector ( + *matrix_A)[3U], + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *s_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *error_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + result[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + result[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for ( + size_t i0 = (size_t)0U; + i0 < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, matrix_A, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + [3U], + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + [3U], + size_t); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *row = matrix_A[i1]; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + size_t); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *matrix_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + product = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ntt_multiply__libcrux_ml_kem_vector_portable_PortableVector( + matrix_element, &s_as_ntt[j]); + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_to_ring_element__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + &result[i1], &product); + } + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___add_standard_error_reduce__libcrux_ml_kem_vector_portable_PortableVector( + &result[i1], &error_as_ntt[i1]); + } + memcpy( + ret, result, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); +} + +static inline void +libcrux_ml_kem_serialize_serialize_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + *re, + uint8_t ret[384U]) { + uint8_t serialized[384U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_portable_PortableVector coefficient = + libcrux_ml_kem_vector_traits_to_unsigned_representative__libcrux_ml_kem_vector_portable_PortableVector( + re->coefficients[i0]); + uint8_t bytes[24U]; + libcrux_ml_kem_vector___libcrux_ml_kem__vector__traits__Operations_for_libcrux_ml_kem__vector__portable__PortableVector___serialize_12( + coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)384U, serialized, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)24U * i0, .end = (size_t)24U * i0 + (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)24U, bytes, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, serialized, (size_t)384U * sizeof(uint8_t)); +} + +static inline void +libcrux_ml_kem_ind_cpa_serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + key[3U], + uint8_t ret[1152U]) { + uint8_t out[1152U] = {0U}; + for ( + size_t i = (size_t)0U; + i < + core_slice___Slice_T___len( + Eurydice_array_to_slice( + (size_t)3U, key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + Eurydice_slice), + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector, + size_t); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + re = key[i0]; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)1152U, out, + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = (i0 + (size_t)1U) * + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret0[384U]; + libcrux_ml_kem_serialize_serialize_uncompressed_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + &re, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)384U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + } + memcpy(ret, out, (size_t)1152U * sizeof(uint8_t)); +} + +static inline void +libcrux_ml_kem_ind_cpa_serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t_1184size_t( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + t_as_ntt[3U], + Eurydice_slice seed_for_a, uint8_t ret[1184U]) { + uint8_t public_key_serialized[1184U] = {0U}; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)1184U, public_key_serialized, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)1152U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____1[3U]; + memcpy( + uu____1, t_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); + uint8_t ret0[1152U]; + libcrux_ml_kem_ind_cpa_serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t( + uu____1, ret0); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)1152U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice_from((size_t)1184U, public_key_serialized, + (size_t)1152U, uint8_t, size_t, + Eurydice_slice), + seed_for_a, uint8_t, void *); + memcpy(ret, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); +} + +static inline libcrux_ml_kem_utils_extraction_helper_Keypair768 +libcrux_ml_kem_ind_cpa_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( + Eurydice_slice key_generation_seed) { + uint8_t hashed[64U]; + libcrux_ml_kem_hash_functions_portable___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__portable__PortableHash_K____G___3size_t( + key_generation_seed, hashed); + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t, Eurydice_slice), + (size_t)32U, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice seed_for_A = uu____0.fst; + Eurydice_slice seed_for_secret_and_error = uu____0.snd; + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + A_transpose[3U][3U]; + uint8_t ret[34U]; + libcrux_ml_kem_utils_into_padded_array___34size_t(seed_for_A, ret); + libcrux_ml_kem_matrix_sample_matrix_A__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t( + ret, true, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_utils_into_padded_array___33size_t(seed_for_secret_and_error, + prf_input); + uint8_t uu____1[33U]; + memcpy(uu____1, prf_input, (size_t)33U * sizeof(uint8_t)); + K___libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector_3size_t__uint8_t + uu____2 = + libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( + uu____1, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + secret_as_ntt[3U]; + memcpy( + secret_as_ntt, uu____2.fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); + uint8_t domain_separator = uu____2.snd; + uint8_t uu____3[33U]; + memcpy(uu____3, prf_input, (size_t)33U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + error_as_ntt[3U]; + memcpy( + error_as_ntt, + libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2size_t_128size_t( + uu____3, domain_separator) + .fst, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + t_as_ntt[3U]; + libcrux_ml_kem_matrix_compute_As_plus_e__libcrux_ml_kem_vector_portable_PortableVector_3size_t( + A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____4[3U]; + memcpy( + uu____4, t_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); + uint8_t public_key_serialized[1184U]; + libcrux_ml_kem_ind_cpa_serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t_1184size_t( + uu____4, seed_for_A, public_key_serialized); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____5[3U]; + memcpy( + uu____5, secret_as_ntt, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); + uint8_t secret_key_serialized[1152U]; + libcrux_ml_kem_ind_cpa_serialize_secret_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t( + uu____5, secret_key_serialized); + uint8_t uu____6[1152U]; + memcpy(uu____6, secret_key_serialized, (size_t)1152U * sizeof(uint8_t)); + uint8_t uu____7[1184U]; + memcpy(uu____7, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); + libcrux_ml_kem_utils_extraction_helper_Keypair768 lit; + memcpy(lit.fst, uu____6, (size_t)1152U * sizeof(uint8_t)); + memcpy(lit.snd, uu____7, (size_t)1184U * sizeof(uint8_t)); + return lit; +} + +static inline void +libcrux_ml_kem_ind_cca_serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t( + Eurydice_slice private_key, Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { + uint8_t out[2400U] = {0U}; + size_t pointer = (size_t)0U; + uint8_t *uu____0 = out; + size_t uu____1 = pointer; + size_t uu____2 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)2400U, uu____0, + (CLITERAL(core_ops_range_Range__size_t){ + .start = uu____1, + .end = uu____2 + + core_slice___Slice_T___len(private_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + private_key, uint8_t, void *); + pointer = pointer + core_slice___Slice_T___len(private_key, uint8_t, size_t); + uint8_t *uu____3 = out; + size_t uu____4 = pointer; + size_t uu____5 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)2400U, uu____3, + (CLITERAL(core_ops_range_Range__size_t){ + .start = uu____4, + .end = uu____5 + + core_slice___Slice_T___len(public_key, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + public_key, uint8_t, void *); + pointer = pointer + core_slice___Slice_T___len(public_key, uint8_t, size_t); + Eurydice_slice uu____6 = Eurydice_array_to_subslice( + (size_t)2400U, out, + (CLITERAL(core_ops_range_Range__size_t){ + .start = pointer, + .end = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret0[32U]; + libcrux_ml_kem_hash_functions_portable___libcrux_ml_kem__hash_functions__Hash_K__for_libcrux_ml_kem__hash_functions__portable__PortableHash_K____H___3size_t( + public_key, ret0); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_array_to_slice((size_t)32U, ret0, uint8_t, Eurydice_slice), + uint8_t, void *); + pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; + uint8_t *uu____7 = out; + size_t uu____8 = pointer; + size_t uu____9 = pointer; + core_slice___Slice_T___copy_from_slice( + Eurydice_array_to_subslice( + (size_t)2400U, uu____7, + (CLITERAL(core_ops_range_Range__size_t){ + .start = uu____8, + .end = uu____9 + core_slice___Slice_T___len( + implicit_rejection_value, uint8_t, size_t)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + implicit_rejection_value, uint8_t, void *); + memcpy(ret, out, (size_t)2400U * sizeof(uint8_t)); +} + +static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]) { + Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice( + (size_t)64U, randomness, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( + (size_t)64U, randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, + size_t, Eurydice_slice); + libcrux_ml_kem_utils_extraction_helper_Keypair768 uu____0 = + libcrux_ml_kem_ind_cpa_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_1184size_t_1152size_t_2size_t_128size_t( + ind_cpa_keypair_randomness); + uint8_t ind_cpa_private_key[1152U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof(uint8_t)); + uint8_t public_key[1184U]; + memcpy(public_key, uu____0.snd, (size_t)1184U * sizeof(uint8_t)); + Eurydice_slice uu____1 = Eurydice_array_to_slice( + (size_t)1152U, ind_cpa_private_key, uint8_t, Eurydice_slice); + uint8_t secret_key_serialized[2400U]; + libcrux_ml_kem_ind_cca_serialize_kem_secret_key__libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_2400size_t( + uu____1, + Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t, + Eurydice_slice), + implicit_rejection_value, secret_key_serialized); + uint8_t uu____2[2400U]; + memcpy(uu____2, secret_key_serialized, (size_t)2400U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t private_key = + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPrivateKey_SIZE___8__from___2400size_t( + uu____2); + libcrux_ml_kem_types_MlKemPrivateKey____2400size_t uu____3 = private_key; + uint8_t uu____4[1184U]; + memcpy(uu____4, public_key, (size_t)1184U * sizeof(uint8_t)); + return libcrux_ml_kem_types__libcrux_ml_kem__types__MlKemKeyPair_PRIVATE_KEY_SIZE__PUBLIC_KEY_SIZE___from___2400size_t_1184size_t( + uu____3, + libcrux_ml_kem_types___core__convert__From__Array_u8__SIZE___for_libcrux_ml_kem__types__MlKemPublicKey_SIZE___14__from___1184size_t( + uu____4)); +} + +static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_generate_keypair__libcrux_ml_kem_vector_portable_PortableVector_libcrux_ml_kem_hash_functions_portable_PortableHash___3size_t___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uu____0); +} + +static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_mlkem768_portable_generate_key_pair(uint8_t randomness[64U]) { + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair___3size_t_1152size_t_2400size_t_1184size_t_1152size_t_2size_t_128size_t( + uu____0); +} + +static inline libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_closure__libcrux_ml_kem_vector_portable_PortableVector_1184size_t_3size_t( + size_t _i) { + return libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector(); +} + +static inline void +libcrux_ml_kem_serialize_deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_1184size_t_3size_t( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + deserialized_pk[3U]; + KRML_MAYBE_FOR3( + i, (size_t)0U, (size_t)3U, (size_t)1U, + deserialized_pk[i] = + libcrux_ml_kem_polynomial__libcrux_ml_kem__polynomial__PolynomialRingElement_Vector__TraitClause_0___ZERO__libcrux_ml_kem_vector_portable_PortableVector();); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(public_key, uint8_t, size_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice( + public_key, + (CLITERAL(core_ops_range_Range__size_t){ + .start = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + .end = i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0 = + libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element__libcrux_ml_kem_vector_portable_PortableVector( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); +} + +static inline bool +libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t_1184size_t( + uint8_t *public_key) { + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + deserialized_pk[3U]; + libcrux_ml_kem_serialize_deserialize_ring_elements_reduced__libcrux_ml_kem_vector_portable_PortableVector_1184size_t_3size_t( + Eurydice_array_to_subslice_to((size_t)1184U, public_key, (size_t)1152U, + uint8_t, size_t, Eurydice_slice), + deserialized_pk); + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector + uu____0[3U]; + memcpy( + uu____0, deserialized_pk, + (size_t)3U * + sizeof( + libcrux_ml_kem_polynomial_PolynomialRingElement__libcrux_ml_kem_vector_portable_PortableVector)); + uint8_t public_key_serialized[1184U]; + libcrux_ml_kem_ind_cpa_serialize_public_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t_1184size_t( + uu____0, + Eurydice_array_to_subslice_from((size_t)1184U, public_key, (size_t)1152U, + uint8_t, size_t, Eurydice_slice), + public_key_serialized); + return core_array_equality___core__cmp__PartialEq__Array_B__N___for__Array_A__N____eq( + (size_t)1184U, public_key, public_key_serialized, uint8_t, uint8_t, bool); +} + +static inline bool +libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( + uint8_t *public_key) { + return libcrux_ml_kem_ind_cca_validate_public_key__libcrux_ml_kem_vector_portable_PortableVector_3size_t_1152size_t_1184size_t( + public_key); +} + +static inline core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ +libcrux_ml_kem_mlkem768_portable_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey____1184size_t public_key) { + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__ + uu____0; + if (libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key___3size_t_1152size_t_1184size_t( + public_key.value)) { + uu____0 = (CLITERAL( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ + .tag = core_option_Some, .f0 = public_key}); + } else { + uu____0 = (CLITERAL( + core_option_Option__libcrux_ml_kem_types_MlKemPublicKey___1184size_t__){ + .tag = core_option_None}); + } + return uu____0; +} + +static inline libcrux_ml_kem_vector_portable_PortableVector +libcrux_ml_kem_vector_portable___core__clone__Clone_for_libcrux_ml_kem__vector__portable__PortableVector___clone( + libcrux_ml_kem_vector_portable_PortableVector *self) { + return self[0U]; +} + +typedef int16_t libcrux_ml_kem_vector_MontgomeryFieldElement; + +typedef int16_t libcrux_ml_kem_vector_FieldElementTimesMontgomeryR; + +typedef int16_t libcrux_ml_kem_vector_FieldElement; + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem768_portable_H_DEFINED +#endif diff --git a/libcrux-ml-kem/cg/libcrux_sha3_avx2.h b/libcrux-ml-kem/cg/libcrux_sha3_avx2.h new file mode 100644 index 000000000..51717b013 --- /dev/null +++ b/libcrux-ml-kem/cg/libcrux_sha3_avx2.h @@ -0,0 +1,2370 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../cg.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 409fe455 + */ + +#ifndef __libcrux_sha3_avx2_H +#define __libcrux_sha3_avx2_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "eurydice_glue.h" +#include "intrinsics/libcrux_intrinsics_avx2.h" +#include "libcrux_core.h" +#include "libcrux_sha3_portable.h" + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___zero( + void) { + return libcrux_intrinsics_avx2_mm256_set1_epi64x((int64_t)0); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i libcrux_sha3_simd_avx2__veor5q_u64( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b, + core_core_arch_x86___m256i c, core_core_arch_x86___m256i d, + core_core_arch_x86___m256i e) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + core_core_arch_x86___m256i cd = libcrux_intrinsics_avx2_mm256_xor_si256(c, d); + core_core_arch_x86___m256i abcd = + libcrux_intrinsics_avx2_mm256_xor_si256(ab, cd); + return libcrux_intrinsics_avx2_mm256_xor_si256(abcd, e); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor5( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b, + core_core_arch_x86___m256i c, core_core_arch_x86___m256i d, + core_core_arch_x86___m256i e) { + return libcrux_sha3_simd_avx2__veor5q_u64(a, b, c, d, e); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2_rotate_left___1int32_t_63int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)1, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)63, x, core_core_arch_x86___m256i)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i libcrux_sha3_simd_avx2__vrax1q_u64( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i uu____0 = a; + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_sha3_simd_avx2_rotate_left___1int32_t_63int32_t(b)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___rotate_left1_and_xor( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return libcrux_sha3_simd_avx2__vrax1q_u64(a, b); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i libcrux_sha3_simd_avx2__vbcaxq_u64( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b, + core_core_arch_x86___m256i c) { + core_core_arch_x86___m256i uu____0 = a; + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_andnot_si256(c, b)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___and_not_xor( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b, + core_core_arch_x86___m256i c) { + return libcrux_sha3_simd_avx2__vbcaxq_u64(a, b, c); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i libcrux_sha3_simd_avx2__veorq_n_u64( + core_core_arch_x86___m256i a, uint64_t c) { + core_core_arch_x86___m256i c0 = + libcrux_intrinsics_avx2_mm256_set1_epi64x((int64_t)c); + return libcrux_intrinsics_avx2_mm256_xor_si256(a, c0); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_constant( + core_core_arch_x86___m256i a, uint64_t c) { + return libcrux_sha3_simd_avx2__veorq_n_u64(a, c); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return libcrux_intrinsics_avx2_mm256_xor_si256(a, b); +} + +__attribute__((target("avx2"))) +static inline void libcrux_sha3_simd_avx2_slice_4(Eurydice_slice a[4U], + size_t start, size_t len, + Eurydice_slice ret[4U]) { + Eurydice_slice uu____0 = Eurydice_slice_subslice( + a[0U], + (CLITERAL(core_ops_range_Range__size_t){.start = start, + .end = start + len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + Eurydice_slice uu____1 = Eurydice_slice_subslice( + a[1U], + (CLITERAL(core_ops_range_Range__size_t){.start = start, + .end = start + len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + Eurydice_slice uu____2 = Eurydice_slice_subslice( + a[2U], + (CLITERAL(core_ops_range_Range__size_t){.start = start, + .end = start + len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + ret[0U] = uu____0; + ret[1U] = uu____1; + ret[2U] = uu____2; + ret[3U] = Eurydice_slice_subslice(a[3U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = start, .end = start + len}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___slice_n( + Eurydice_slice a[4U], size_t start, size_t len, Eurydice_slice ret[4U]) { + Eurydice_slice uu____0[4U]; + memcpy(uu____0, a, (size_t)4U * sizeof(Eurydice_slice)); + Eurydice_slice ret0[4U]; + libcrux_sha3_simd_avx2_slice_4(uu____0, start, len, ret0); + memcpy(ret, ret0, (size_t)4U * sizeof(Eurydice_slice)); +} + +__attribute__((target("avx2"))) +static inline K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ +libcrux_sha3_simd_avx2_split_at_mut_4(Eurydice_slice out[4U], size_t mid) { + Eurydice_slice out0 = out[0U]; + Eurydice_slice out1 = out[1U]; + Eurydice_slice out2 = out[2U]; + Eurydice_slice out3 = out[3U]; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at_mut( + out0, mid, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice out00 = uu____0.fst; + Eurydice_slice out01 = uu____0.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____1 = + core_slice___Slice_T___split_at_mut( + out1, mid, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice out10 = uu____1.fst; + Eurydice_slice out11 = uu____1.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____2 = + core_slice___Slice_T___split_at_mut( + out2, mid, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice out20 = uu____2.fst; + Eurydice_slice out21 = uu____2.snd; + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____3 = + core_slice___Slice_T___split_at_mut( + out3, mid, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice out30 = uu____3.fst; + Eurydice_slice out31 = uu____3.snd; + K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ lit; + lit.fst[0U] = out00; + lit.fst[1U] = out10; + lit.fst[2U] = out20; + lit.fst[3U] = out30; + lit.snd[0U] = out01; + lit.snd[1U] = out11; + lit.snd[2U] = out21; + lit.snd[3U] = out31; + return lit; +} + +__attribute__((target("avx2"))) +static inline K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___split_at_mut_n( + Eurydice_slice a[4U], size_t mid) { + return libcrux_sha3_simd_avx2_split_at_mut_4(a, mid); +} + +typedef struct + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t_s { + core_core_arch_x86___m256i st[5U][5U]; +} libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t; + +__attribute__((target("avx2"))) +static inline libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t +libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__core_core_arch_x86___m256i_4size_t( + void) { + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + lit; + lit.st[0U][0U] = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___zero(); + lit.st[0U][1U] = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___zero(); + lit.st[0U][2U] = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___zero(); + lit.st[0U][3U] = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___zero(); + lit.st[0U][4U] = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___zero(); + lit.st[1U][0U] = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___zero(); + lit.st[1U][1U] = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___zero(); + lit.st[1U][2U] = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___zero(); + lit.st[1U][3U] = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___zero(); + lit.st[1U][4U] = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___zero(); + lit.st[2U][0U] = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___zero(); + lit.st[2U][1U] = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___zero(); + lit.st[2U][2U] = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___zero(); + lit.st[2U][3U] = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___zero(); + lit.st[2U][4U] = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___zero(); + lit.st[3U][0U] = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___zero(); + lit.st[3U][1U] = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___zero(); + lit.st[3U][2U] = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___zero(); + lit.st[3U][3U] = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___zero(); + lit.st[3U][4U] = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___zero(); + lit.st[4U][0U] = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___zero(); + lit.st[4U][1U] = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___zero(); + lit.st[4U][2U] = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___zero(); + lit.st[4U][3U] = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___zero(); + lit.st[4U][4U] = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___zero(); + return lit; +} + +__attribute__((target("avx2"))) +static inline void libcrux_sha3_simd_avx2_load_block___136size_t( + core_core_arch_x86___m256i (*s)[5U], Eurydice_slice blocks[4U]) { + for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)32U; i++) { + size_t i0 = i; + core_core_arch_x86___m256i v00 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( + blocks[0U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m256i v10 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( + blocks[1U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m256i v20 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( + blocks[2U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m256i v30 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( + blocks[3U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m256i v0l = + libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v00, v10); + core_core_arch_x86___m256i v1h = + libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v00, v10); + core_core_arch_x86___m256i v2l = + libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v20, v30); + core_core_arch_x86___m256i v3h = + libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v20, v30); + core_core_arch_x86___m256i v0 = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)32, v0l, v2l, core_core_arch_x86___m256i); + core_core_arch_x86___m256i v1 = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)32, v1h, v3h, core_core_arch_x86___m256i); + core_core_arch_x86___m256i v2 = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)49, v0l, v2l, core_core_arch_x86___m256i); + core_core_arch_x86___m256i v3 = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)49, v1h, v3h, core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____0 = + libcrux_intrinsics_avx2_mm256_xor_si256( + s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], v0); + s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U] = uu____0; + core_core_arch_x86___m256i uu____1 = + libcrux_intrinsics_avx2_mm256_xor_si256( + s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], + v1); + s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)1U) % (size_t)5U] = uu____1; + core_core_arch_x86___m256i uu____2 = + libcrux_intrinsics_avx2_mm256_xor_si256( + s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], + v2); + s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)2U) % (size_t)5U] = uu____2; + core_core_arch_x86___m256i uu____3 = + libcrux_intrinsics_avx2_mm256_xor_si256( + s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], + v3); + s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)3U) % (size_t)5U] = uu____3; + } + size_t rem = (size_t)136U % (size_t)32U; + size_t start = (size_t)32U * ((size_t)136U / (size_t)32U); + uint8_t u8s[32U] = {0U}; + Eurydice_slice uu____4 = Eurydice_array_to_subslice( + (size_t)32U, u8s, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + Eurydice_slice_subslice(blocks[0U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = start, .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____5 = Eurydice_array_to_subslice( + (size_t)32U, u8s, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____5, + Eurydice_slice_subslice(blocks[1U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = start, .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____6 = Eurydice_array_to_subslice( + (size_t)32U, u8s, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)16U, + .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_slice_subslice(blocks[2U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = start, .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____7 = Eurydice_array_to_subslice( + (size_t)32U, u8s, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)24U, + .end = (size_t)32U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____7, + Eurydice_slice_subslice(blocks[3U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = start, .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + core_core_arch_x86___m256i u = libcrux_intrinsics_avx2_mm256_loadu_si256_u8( + core_array___Array_T__N__23__as_slice((size_t)32U, u8s, uint8_t, + Eurydice_slice)); + size_t i0 = (size_t)4U * ((size_t)136U / (size_t)32U) / (size_t)5U; + size_t j0 = (size_t)4U * ((size_t)136U / (size_t)32U) % (size_t)5U; + core_core_arch_x86___m256i uu____8 = + libcrux_intrinsics_avx2_mm256_xor_si256(s[i0][j0], u); + s[i0][j0] = uu____8; + if (rem == (size_t)16U) { + uint8_t u8s0[32U] = {0U}; + Eurydice_slice uu____9 = Eurydice_array_to_subslice( + (size_t)32U, u8s0, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____9, + Eurydice_slice_subslice( + blocks[0U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = start + (size_t)8U, .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____10 = Eurydice_array_to_subslice( + (size_t)32U, u8s0, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____10, + Eurydice_slice_subslice( + blocks[1U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = start + (size_t)8U, .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____11 = Eurydice_array_to_subslice( + (size_t)32U, u8s0, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)16U, + .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____11, + Eurydice_slice_subslice( + blocks[2U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = start + (size_t)8U, .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____12 = Eurydice_array_to_subslice( + (size_t)32U, u8s0, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)24U, + .end = (size_t)32U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____12, + Eurydice_slice_subslice( + blocks[3U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = start + (size_t)8U, .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + core_core_arch_x86___m256i u0 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8( + core_array___Array_T__N__23__as_slice((size_t)32U, u8s0, uint8_t, + Eurydice_slice)); + size_t i = + ((size_t)4U * ((size_t)136U / (size_t)32U) + (size_t)1U) / (size_t)5U; + size_t j = + ((size_t)4U * ((size_t)136U / (size_t)32U) + (size_t)1U) % (size_t)5U; + core_core_arch_x86___m256i uu____13 = + libcrux_intrinsics_avx2_mm256_xor_si256(s[i][j], u0); + s[i][j] = uu____13; + } +} + +__attribute__((target("avx2"))) +static inline void +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___load_block___136size_t( + core_core_arch_x86___m256i (*a)[5U], Eurydice_slice b[4U]) { + core_core_arch_x86___m256i(*uu____0)[5U] = a; + Eurydice_slice uu____1[4U]; + memcpy(uu____1, b, (size_t)4U * sizeof(Eurydice_slice)); + libcrux_sha3_simd_avx2_load_block___136size_t(uu____0, uu____1); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2_rotate_left___36int32_t_28int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)36, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)28, x, core_core_arch_x86___m256i)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2__vxarq_u64___36int32_t_28int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return libcrux_sha3_simd_avx2_rotate_left___36int32_t_28int32_t(ab); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___36int32_t_28int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return libcrux_sha3_simd_avx2__vxarq_u64___36int32_t_28int32_t(a, b); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2_rotate_left___3int32_t_61int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)3, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)61, x, core_core_arch_x86___m256i)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2__vxarq_u64___3int32_t_61int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return libcrux_sha3_simd_avx2_rotate_left___3int32_t_61int32_t(ab); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___3int32_t_61int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return libcrux_sha3_simd_avx2__vxarq_u64___3int32_t_61int32_t(a, b); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2_rotate_left___41int32_t_23int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)41, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)23, x, core_core_arch_x86___m256i)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2__vxarq_u64___41int32_t_23int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return libcrux_sha3_simd_avx2_rotate_left___41int32_t_23int32_t(ab); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___41int32_t_23int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return libcrux_sha3_simd_avx2__vxarq_u64___41int32_t_23int32_t(a, b); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2_rotate_left___18int32_t_46int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)18, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)46, x, core_core_arch_x86___m256i)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2__vxarq_u64___18int32_t_46int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return libcrux_sha3_simd_avx2_rotate_left___18int32_t_46int32_t(ab); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___18int32_t_46int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return libcrux_sha3_simd_avx2__vxarq_u64___18int32_t_46int32_t(a, b); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2__vxarq_u64___1int32_t_63int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return libcrux_sha3_simd_avx2_rotate_left___1int32_t_63int32_t(ab); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___1int32_t_63int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return libcrux_sha3_simd_avx2__vxarq_u64___1int32_t_63int32_t(a, b); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2_rotate_left___44int32_t_20int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)44, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)20, x, core_core_arch_x86___m256i)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2__vxarq_u64___44int32_t_20int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return libcrux_sha3_simd_avx2_rotate_left___44int32_t_20int32_t(ab); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___44int32_t_20int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return libcrux_sha3_simd_avx2__vxarq_u64___44int32_t_20int32_t(a, b); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2_rotate_left___10int32_t_54int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)10, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)54, x, core_core_arch_x86___m256i)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2__vxarq_u64___10int32_t_54int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return libcrux_sha3_simd_avx2_rotate_left___10int32_t_54int32_t(ab); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___10int32_t_54int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return libcrux_sha3_simd_avx2__vxarq_u64___10int32_t_54int32_t(a, b); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2_rotate_left___45int32_t_19int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)45, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)19, x, core_core_arch_x86___m256i)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2__vxarq_u64___45int32_t_19int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return libcrux_sha3_simd_avx2_rotate_left___45int32_t_19int32_t(ab); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___45int32_t_19int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return libcrux_sha3_simd_avx2__vxarq_u64___45int32_t_19int32_t(a, b); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2_rotate_left___2int32_t_62int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)2, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)62, x, core_core_arch_x86___m256i)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2__vxarq_u64___2int32_t_62int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return libcrux_sha3_simd_avx2_rotate_left___2int32_t_62int32_t(ab); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___2int32_t_62int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return libcrux_sha3_simd_avx2__vxarq_u64___2int32_t_62int32_t(a, b); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2_rotate_left___62int32_t_2int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)62, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)2, x, core_core_arch_x86___m256i)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2__vxarq_u64___62int32_t_2int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return libcrux_sha3_simd_avx2_rotate_left___62int32_t_2int32_t(ab); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___62int32_t_2int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return libcrux_sha3_simd_avx2__vxarq_u64___62int32_t_2int32_t(a, b); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2_rotate_left___6int32_t_58int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)6, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)58, x, core_core_arch_x86___m256i)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2__vxarq_u64___6int32_t_58int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return libcrux_sha3_simd_avx2_rotate_left___6int32_t_58int32_t(ab); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___6int32_t_58int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return libcrux_sha3_simd_avx2__vxarq_u64___6int32_t_58int32_t(a, b); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2_rotate_left___43int32_t_21int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)43, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)21, x, core_core_arch_x86___m256i)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2__vxarq_u64___43int32_t_21int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return libcrux_sha3_simd_avx2_rotate_left___43int32_t_21int32_t(ab); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___43int32_t_21int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return libcrux_sha3_simd_avx2__vxarq_u64___43int32_t_21int32_t(a, b); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2_rotate_left___15int32_t_49int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)15, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)49, x, core_core_arch_x86___m256i)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2__vxarq_u64___15int32_t_49int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return libcrux_sha3_simd_avx2_rotate_left___15int32_t_49int32_t(ab); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___15int32_t_49int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return libcrux_sha3_simd_avx2__vxarq_u64___15int32_t_49int32_t(a, b); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2_rotate_left___61int32_t_3int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)61, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)3, x, core_core_arch_x86___m256i)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2__vxarq_u64___61int32_t_3int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return libcrux_sha3_simd_avx2_rotate_left___61int32_t_3int32_t(ab); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___61int32_t_3int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return libcrux_sha3_simd_avx2__vxarq_u64___61int32_t_3int32_t(a, b); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2_rotate_left___28int32_t_36int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)28, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)36, x, core_core_arch_x86___m256i)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2__vxarq_u64___28int32_t_36int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return libcrux_sha3_simd_avx2_rotate_left___28int32_t_36int32_t(ab); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___28int32_t_36int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return libcrux_sha3_simd_avx2__vxarq_u64___28int32_t_36int32_t(a, b); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2_rotate_left___55int32_t_9int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)55, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)9, x, core_core_arch_x86___m256i)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2__vxarq_u64___55int32_t_9int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return libcrux_sha3_simd_avx2_rotate_left___55int32_t_9int32_t(ab); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___55int32_t_9int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return libcrux_sha3_simd_avx2__vxarq_u64___55int32_t_9int32_t(a, b); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2_rotate_left___25int32_t_39int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)25, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)39, x, core_core_arch_x86___m256i)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2__vxarq_u64___25int32_t_39int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return libcrux_sha3_simd_avx2_rotate_left___25int32_t_39int32_t(ab); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___25int32_t_39int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return libcrux_sha3_simd_avx2__vxarq_u64___25int32_t_39int32_t(a, b); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2_rotate_left___21int32_t_43int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)21, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)43, x, core_core_arch_x86___m256i)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2__vxarq_u64___21int32_t_43int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return libcrux_sha3_simd_avx2_rotate_left___21int32_t_43int32_t(ab); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___21int32_t_43int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return libcrux_sha3_simd_avx2__vxarq_u64___21int32_t_43int32_t(a, b); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2_rotate_left___56int32_t_8int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)56, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)8, x, core_core_arch_x86___m256i)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2__vxarq_u64___56int32_t_8int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return libcrux_sha3_simd_avx2_rotate_left___56int32_t_8int32_t(ab); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___56int32_t_8int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return libcrux_sha3_simd_avx2__vxarq_u64___56int32_t_8int32_t(a, b); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2_rotate_left___27int32_t_37int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)27, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)37, x, core_core_arch_x86___m256i)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2__vxarq_u64___27int32_t_37int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return libcrux_sha3_simd_avx2_rotate_left___27int32_t_37int32_t(ab); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___27int32_t_37int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return libcrux_sha3_simd_avx2__vxarq_u64___27int32_t_37int32_t(a, b); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2_rotate_left___20int32_t_44int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)20, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)44, x, core_core_arch_x86___m256i)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2__vxarq_u64___20int32_t_44int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return libcrux_sha3_simd_avx2_rotate_left___20int32_t_44int32_t(ab); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___20int32_t_44int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return libcrux_sha3_simd_avx2__vxarq_u64___20int32_t_44int32_t(a, b); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2_rotate_left___39int32_t_25int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)39, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)25, x, core_core_arch_x86___m256i)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2__vxarq_u64___39int32_t_25int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return libcrux_sha3_simd_avx2_rotate_left___39int32_t_25int32_t(ab); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___39int32_t_25int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return libcrux_sha3_simd_avx2__vxarq_u64___39int32_t_25int32_t(a, b); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2_rotate_left___8int32_t_56int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)8, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)56, x, core_core_arch_x86___m256i)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2__vxarq_u64___8int32_t_56int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return libcrux_sha3_simd_avx2_rotate_left___8int32_t_56int32_t(ab); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___8int32_t_56int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return libcrux_sha3_simd_avx2__vxarq_u64___8int32_t_56int32_t(a, b); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2_rotate_left___14int32_t_50int32_t( + core_core_arch_x86___m256i x) { + core_core_arch_x86___m256i uu____0 = libcrux_intrinsics_avx2_mm256_slli_epi64( + (int32_t)14, x, core_core_arch_x86___m256i); + return libcrux_intrinsics_avx2_mm256_xor_si256( + uu____0, libcrux_intrinsics_avx2_mm256_srli_epi64( + (int32_t)50, x, core_core_arch_x86___m256i)); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2__vxarq_u64___14int32_t_50int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + core_core_arch_x86___m256i ab = libcrux_intrinsics_avx2_mm256_xor_si256(a, b); + return libcrux_sha3_simd_avx2_rotate_left___14int32_t_50int32_t(ab); +} + +__attribute__((target("avx2"))) +static inline core_core_arch_x86___m256i +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___14int32_t_50int32_t( + core_core_arch_x86___m256i a, core_core_arch_x86___m256i b) { + return libcrux_sha3_simd_avx2__vxarq_u64___14int32_t_50int32_t(a, b); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_sha3_generic_keccak_theta_rho__core_core_arch_x86___m256i_4size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s) { + core_core_arch_x86___m256i uu____0 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor5( + s->st[0U][0U], s->st[1U][0U], s->st[2U][0U], s->st[3U][0U], + s->st[4U][0U]); + core_core_arch_x86___m256i uu____1 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor5( + s->st[0U][1U], s->st[1U][1U], s->st[2U][1U], s->st[3U][1U], + s->st[4U][1U]); + core_core_arch_x86___m256i uu____2 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor5( + s->st[0U][2U], s->st[1U][2U], s->st[2U][2U], s->st[3U][2U], + s->st[4U][2U]); + core_core_arch_x86___m256i uu____3 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor5( + s->st[0U][3U], s->st[1U][3U], s->st[2U][3U], s->st[3U][3U], + s->st[4U][3U]); + core_core_arch_x86___m256i c[5U] = { + uu____0, uu____1, uu____2, uu____3, + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor5( + s->st[0U][4U], s->st[1U][4U], s->st[2U][4U], s->st[3U][4U], + s->st[4U][4U])}; + core_core_arch_x86___m256i uu____4 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___rotate_left1_and_xor( + c[((size_t)0U + (size_t)4U) % (size_t)5U], + c[((size_t)0U + (size_t)1U) % (size_t)5U]); + core_core_arch_x86___m256i uu____5 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___rotate_left1_and_xor( + c[((size_t)1U + (size_t)4U) % (size_t)5U], + c[((size_t)1U + (size_t)1U) % (size_t)5U]); + core_core_arch_x86___m256i uu____6 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___rotate_left1_and_xor( + c[((size_t)2U + (size_t)4U) % (size_t)5U], + c[((size_t)2U + (size_t)1U) % (size_t)5U]); + core_core_arch_x86___m256i uu____7 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___rotate_left1_and_xor( + c[((size_t)3U + (size_t)4U) % (size_t)5U], + c[((size_t)3U + (size_t)1U) % (size_t)5U]); + core_core_arch_x86___m256i t[5U] = { + uu____4, uu____5, uu____6, uu____7, + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___rotate_left1_and_xor( + c[((size_t)4U + (size_t)4U) % (size_t)5U], + c[((size_t)4U + (size_t)1U) % (size_t)5U])}; + core_core_arch_x86___m256i uu____8 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor( + s->st[0U][0U], t[0U]); + s->st[0U][0U] = uu____8; + core_core_arch_x86___m256i uu____9 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___36int32_t_28int32_t( + s->st[1U][0U], t[0U]); + s->st[1U][0U] = uu____9; + core_core_arch_x86___m256i uu____10 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___3int32_t_61int32_t( + s->st[2U][0U], t[0U]); + s->st[2U][0U] = uu____10; + core_core_arch_x86___m256i uu____11 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___41int32_t_23int32_t( + s->st[3U][0U], t[0U]); + s->st[3U][0U] = uu____11; + core_core_arch_x86___m256i uu____12 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___18int32_t_46int32_t( + s->st[4U][0U], t[0U]); + s->st[4U][0U] = uu____12; + core_core_arch_x86___m256i uu____13 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___1int32_t_63int32_t( + s->st[0U][1U], t[1U]); + s->st[0U][1U] = uu____13; + core_core_arch_x86___m256i uu____14 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___44int32_t_20int32_t( + s->st[1U][1U], t[1U]); + s->st[1U][1U] = uu____14; + core_core_arch_x86___m256i uu____15 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___10int32_t_54int32_t( + s->st[2U][1U], t[1U]); + s->st[2U][1U] = uu____15; + core_core_arch_x86___m256i uu____16 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___45int32_t_19int32_t( + s->st[3U][1U], t[1U]); + s->st[3U][1U] = uu____16; + core_core_arch_x86___m256i uu____17 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___2int32_t_62int32_t( + s->st[4U][1U], t[1U]); + s->st[4U][1U] = uu____17; + core_core_arch_x86___m256i uu____18 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___62int32_t_2int32_t( + s->st[0U][2U], t[2U]); + s->st[0U][2U] = uu____18; + core_core_arch_x86___m256i uu____19 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___6int32_t_58int32_t( + s->st[1U][2U], t[2U]); + s->st[1U][2U] = uu____19; + core_core_arch_x86___m256i uu____20 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___43int32_t_21int32_t( + s->st[2U][2U], t[2U]); + s->st[2U][2U] = uu____20; + core_core_arch_x86___m256i uu____21 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___15int32_t_49int32_t( + s->st[3U][2U], t[2U]); + s->st[3U][2U] = uu____21; + core_core_arch_x86___m256i uu____22 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___61int32_t_3int32_t( + s->st[4U][2U], t[2U]); + s->st[4U][2U] = uu____22; + core_core_arch_x86___m256i uu____23 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___28int32_t_36int32_t( + s->st[0U][3U], t[3U]); + s->st[0U][3U] = uu____23; + core_core_arch_x86___m256i uu____24 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___55int32_t_9int32_t( + s->st[1U][3U], t[3U]); + s->st[1U][3U] = uu____24; + core_core_arch_x86___m256i uu____25 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___25int32_t_39int32_t( + s->st[2U][3U], t[3U]); + s->st[2U][3U] = uu____25; + core_core_arch_x86___m256i uu____26 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___21int32_t_43int32_t( + s->st[3U][3U], t[3U]); + s->st[3U][3U] = uu____26; + core_core_arch_x86___m256i uu____27 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___56int32_t_8int32_t( + s->st[4U][3U], t[3U]); + s->st[4U][3U] = uu____27; + core_core_arch_x86___m256i uu____28 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___27int32_t_37int32_t( + s->st[0U][4U], t[4U]); + s->st[0U][4U] = uu____28; + core_core_arch_x86___m256i uu____29 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___20int32_t_44int32_t( + s->st[1U][4U], t[4U]); + s->st[1U][4U] = uu____29; + core_core_arch_x86___m256i uu____30 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___39int32_t_25int32_t( + s->st[2U][4U], t[4U]); + s->st[2U][4U] = uu____30; + core_core_arch_x86___m256i uu____31 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___8int32_t_56int32_t( + s->st[3U][4U], t[4U]); + s->st[3U][4U] = uu____31; + core_core_arch_x86___m256i uu____32 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_and_rotate___14int32_t_50int32_t( + s->st[4U][4U], t[4U]); + s->st[4U][4U] = uu____32; +} + +__attribute__((target("avx2"))) +static inline void +libcrux_sha3_generic_keccak_pi__core_core_arch_x86___m256i_4size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s) { + core_core_arch_x86___m256i old[5U][5U]; + core_array___core__clone__Clone_for__Array_T__N___20__clone( + (size_t)5U, s->st, old, core_core_arch_x86___m256i[5U], void *); + s->st[0U][1U] = old[1U][1U]; + s->st[0U][2U] = old[2U][2U]; + s->st[0U][3U] = old[3U][3U]; + s->st[0U][4U] = old[4U][4U]; + s->st[1U][0U] = old[0U][3U]; + s->st[1U][1U] = old[1U][4U]; + s->st[1U][2U] = old[2U][0U]; + s->st[1U][3U] = old[3U][1U]; + s->st[1U][4U] = old[4U][2U]; + s->st[2U][0U] = old[0U][1U]; + s->st[2U][1U] = old[1U][2U]; + s->st[2U][2U] = old[2U][3U]; + s->st[2U][3U] = old[3U][4U]; + s->st[2U][4U] = old[4U][0U]; + s->st[3U][0U] = old[0U][4U]; + s->st[3U][1U] = old[1U][0U]; + s->st[3U][2U] = old[2U][1U]; + s->st[3U][3U] = old[3U][2U]; + s->st[3U][4U] = old[4U][3U]; + s->st[4U][0U] = old[0U][2U]; + s->st[4U][1U] = old[1U][3U]; + s->st[4U][2U] = old[2U][4U]; + s->st[4U][3U] = old[3U][0U]; + s->st[4U][4U] = old[4U][1U]; +} + +__attribute__((target("avx2"))) +static inline void +libcrux_sha3_generic_keccak_chi__core_core_arch_x86___m256i_4size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s) { + core_core_arch_x86___m256i old[5U][5U]; + memcpy(old, s->st, (size_t)5U * sizeof(core_core_arch_x86___m256i[5U])); + KRML_MAYBE_FOR5( + i0, (size_t)0U, (size_t)5U, (size_t)1U, size_t i1 = i0; KRML_MAYBE_FOR5( + i, (size_t)0U, (size_t)5U, (size_t)1U, size_t j = i; + core_core_arch_x86___m256i uu____0 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___and_not_xor( + s->st[i1][j], old[i1][(j + (size_t)2U) % (size_t)5U], + old[i1][(j + (size_t)1U) % (size_t)5U]); + s->st[i1][j] = uu____0;);); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_sha3_generic_keccak_iota__core_core_arch_x86___m256i_4size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + size_t i) { + core_core_arch_x86___m256i uu____0 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___xor_constant( + s->st[0U][0U], libcrux_sha3_generic_keccak_ROUNDCONSTANTS[i]); + s->st[0U][0U] = uu____0; +} + +__attribute__((target("avx2"))) +static inline void +libcrux_sha3_generic_keccak_keccakf1600__core_core_arch_x86___m256i_4size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s) { + for (size_t i = (size_t)0U; i < (size_t)24U; i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_theta_rho__core_core_arch_x86___m256i_4size_t( + s); + libcrux_sha3_generic_keccak_pi__core_core_arch_x86___m256i_4size_t(s); + libcrux_sha3_generic_keccak_chi__core_core_arch_x86___m256i_4size_t(s); + libcrux_sha3_generic_keccak_iota__core_core_arch_x86___m256i_4size_t(s, i0); + } +} + +__attribute__((target("avx2"))) +static inline void +libcrux_sha3_generic_keccak_absorb_block__core_core_arch_x86___m256i_4size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice blocks[4U]) { + core_core_arch_x86___m256i(*uu____0)[5U] = s->st; + Eurydice_slice uu____1[4U]; + memcpy(uu____1, blocks, (size_t)4U * sizeof(Eurydice_slice)); + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___load_block___136size_t( + uu____0, uu____1); + libcrux_sha3_generic_keccak_keccakf1600__core_core_arch_x86___m256i_4size_t( + s); +} + +__attribute__((target("avx2"))) +static inline void libcrux_sha3_simd_avx2_load_block_full___136size_t( + core_core_arch_x86___m256i (*s)[5U], uint8_t blocks[4U][200U]) { + core_core_arch_x86___m256i(*uu____0)[5U] = s; + Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], + uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = Eurydice_array_to_slice((size_t)200U, blocks[1U], + uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = Eurydice_array_to_slice((size_t)200U, blocks[2U], + uint8_t, Eurydice_slice); + Eurydice_slice buf[4U] = {uu____1, uu____2, uu____3, + Eurydice_array_to_slice((size_t)200U, blocks[3U], + uint8_t, Eurydice_slice)}; + libcrux_sha3_simd_avx2_load_block___136size_t(uu____0, buf); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___load_block_full___136size_t( + core_core_arch_x86___m256i (*a)[5U], uint8_t b[4U][200U]) { + core_core_arch_x86___m256i(*uu____0)[5U] = a; + uint8_t uu____1[4U][200U]; + memcpy(uu____1, b, (size_t)4U * sizeof(uint8_t[200U])); + libcrux_sha3_simd_avx2_load_block_full___136size_t(uu____0, uu____1); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice last[4U]) { + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[4U][200U] = {{0U}}; + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)200U, blocks[i0], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = last_len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i0], + uint8_t, void *); + blocks[i0][last_len] = 31U; + blocks[i0][(size_t)136U - (size_t)1U] = + (uint32_t)blocks[i0][(size_t)136U - (size_t)1U] | 128U;); + core_core_arch_x86___m256i(*uu____1)[5U] = s->st; + uint8_t uu____2[4U][200U]; + memcpy(uu____2, blocks, (size_t)4U * sizeof(uint8_t[200U])); + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___load_block_full___136size_t( + uu____1, uu____2); + libcrux_sha3_generic_keccak_keccakf1600__core_core_arch_x86___m256i_4size_t( + s); +} + +__attribute__((target("avx2"))) +static inline void libcrux_sha3_simd_avx2_store_block___136size_t( + core_core_arch_x86___m256i (*s)[5U], Eurydice_slice out[4U]) { + for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)32U; i++) { + size_t i0 = i; + core_core_arch_x86___m256i v0l = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)32, + s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], + s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], + core_core_arch_x86___m256i); + core_core_arch_x86___m256i v1h = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)32, + s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], + s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], + core_core_arch_x86___m256i); + core_core_arch_x86___m256i v2l = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)49, + s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], + s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], + core_core_arch_x86___m256i); + core_core_arch_x86___m256i v3h = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)49, + s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], + s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], + core_core_arch_x86___m256i); + core_core_arch_x86___m256i v0 = + libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v0l, v1h); + core_core_arch_x86___m256i v1 = + libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v0l, v1h); + core_core_arch_x86___m256i v2 = + libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v2l, v3h); + core_core_arch_x86___m256i v3 = + libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v2l, v3h); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8( + Eurydice_slice_subslice(out[0U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v0); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8( + Eurydice_slice_subslice(out[1U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v1); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8( + Eurydice_slice_subslice(out[2U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v2); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8( + Eurydice_slice_subslice(out[3U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v3); + } + size_t rem = (size_t)136U % (size_t)32U; + size_t start = (size_t)32U * ((size_t)136U / (size_t)32U); + uint8_t u8s[32U] = {0U}; + size_t i0 = (size_t)4U * ((size_t)136U / (size_t)32U) / (size_t)5U; + size_t j0 = (size_t)4U * ((size_t)136U / (size_t)32U) % (size_t)5U; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)32U, u8s, uint8_t, Eurydice_slice); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____0, s[i0][j0]); + Eurydice_slice uu____1 = Eurydice_slice_subslice( + out[0U], + (CLITERAL(core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____1, + Eurydice_array_to_subslice((size_t)32U, u8s, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____2 = Eurydice_slice_subslice( + out[1U], + (CLITERAL(core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____2, + Eurydice_array_to_subslice((size_t)32U, u8s, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)8U, .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____3 = Eurydice_slice_subslice( + out[2U], + (CLITERAL(core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____3, + Eurydice_array_to_subslice((size_t)32U, u8s, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)16U, .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____4 = Eurydice_slice_subslice( + out[3U], + (CLITERAL(core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + Eurydice_array_to_subslice((size_t)32U, u8s, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)24U, .end = (size_t)32U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + if (rem == (size_t)16U) { + uint8_t u8s0[32U] = {0U}; + size_t i = + ((size_t)4U * ((size_t)136U / (size_t)32U) + (size_t)1U) / (size_t)5U; + size_t j = + ((size_t)4U * ((size_t)136U / (size_t)32U) + (size_t)1U) % (size_t)5U; + Eurydice_slice uu____5 = + Eurydice_array_to_slice((size_t)32U, u8s0, uint8_t, Eurydice_slice); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____5, s[i][j]); + Eurydice_slice uu____6 = Eurydice_slice_subslice( + out[0U], + (CLITERAL(core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_array_to_subslice((size_t)32U, u8s0, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____7 = Eurydice_slice_subslice( + out[1U], + (CLITERAL(core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____7, + Eurydice_array_to_subslice( + (size_t)32U, u8s0, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____8 = Eurydice_slice_subslice( + out[2U], + (CLITERAL(core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____8, + Eurydice_array_to_subslice( + (size_t)32U, u8s0, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)16U, + .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____9 = Eurydice_slice_subslice( + out[3U], + (CLITERAL(core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____9, + Eurydice_array_to_subslice( + (size_t)32U, u8s0, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)24U, + .end = (size_t)32U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + } +} + +__attribute__((target("avx2"))) +static inline void libcrux_sha3_simd_avx2_store_block_full___136size_t( + core_core_arch_x86___m256i (*s)[5U], uint8_t ret[4U][200U]) { + uint8_t out0[200U] = {0U}; + uint8_t out1[200U] = {0U}; + uint8_t out2[200U] = {0U}; + uint8_t out3[200U] = {0U}; + core_core_arch_x86___m256i(*uu____0)[5U] = s; + Eurydice_slice uu____1 = + Eurydice_array_to_slice((size_t)200U, out0, uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = + Eurydice_array_to_slice((size_t)200U, out1, uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = + Eurydice_array_to_slice((size_t)200U, out2, uint8_t, Eurydice_slice); + Eurydice_slice buf[4U] = { + uu____1, uu____2, uu____3, + Eurydice_array_to_slice((size_t)200U, out3, uint8_t, Eurydice_slice)}; + libcrux_sha3_simd_avx2_store_block___136size_t(uu____0, buf); + uint8_t uu____4[200U]; + memcpy(uu____4, out0, (size_t)200U * sizeof(uint8_t)); + uint8_t uu____5[200U]; + memcpy(uu____5, out1, (size_t)200U * sizeof(uint8_t)); + uint8_t uu____6[200U]; + memcpy(uu____6, out2, (size_t)200U * sizeof(uint8_t)); + uint8_t uu____7[200U]; + memcpy(uu____7, out3, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[0U], uu____4, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[1U], uu____5, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[2U], uu____6, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[3U], uu____7, (size_t)200U * sizeof(uint8_t)); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___store_block_full___136size_t( + core_core_arch_x86___m256i (*a)[5U], uint8_t ret[4U][200U]) { + uint8_t ret0[4U][200U]; + libcrux_sha3_simd_avx2_store_block_full___136size_t(a, ret0); + memcpy(ret, ret0, (size_t)4U * sizeof(uint8_t[200U])); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_sha3_generic_keccak_squeeze_first_and_last__core_core_arch_x86___m256i_4size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out[4U]) { + uint8_t b[4U][200U]; + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___store_block_full___136size_t( + s->st, b); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; uint8_t *uu____1 = b[i0]; + core_ops_range_Range__size_t lit; lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *);); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___store_block___136size_t( + core_core_arch_x86___m256i (*a)[5U], Eurydice_slice b[4U]) { + libcrux_sha3_simd_avx2_store_block___136size_t(a, b); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_sha3_generic_keccak_squeeze_first_block__core_core_arch_x86___m256i_4size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out[4U]) { + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___store_block___136size_t( + s->st, out); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_sha3_generic_keccak_squeeze_next_block__core_core_arch_x86___m256i_4size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out[4U]) { + libcrux_sha3_generic_keccak_keccakf1600__core_core_arch_x86___m256i_4size_t( + s); + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___store_block___136size_t( + s->st, out); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_sha3_generic_keccak_squeeze_last__core_core_arch_x86___m256i_4size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + s, + Eurydice_slice out[4U]) { + libcrux_sha3_generic_keccak_keccakf1600__core_core_arch_x86___m256i_4size_t( + &s); + uint8_t b[4U][200U]; + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___store_block_full___136size_t( + s.st, b); + KRML_MAYBE_FOR4( + i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; uint8_t *uu____1 = b[i0]; + core_ops_range_Range__size_t lit; lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i0], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *);); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_sha3_generic_keccak_keccak__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t( + Eurydice_slice data[4U], Eurydice_slice out[4U]) { + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t s = + libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__core_core_arch_x86___m256i_4size_t(); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)136U; + i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *uu____0 = &s; + Eurydice_slice uu____1[4U]; + memcpy(uu____1, data, (size_t)4U * sizeof(Eurydice_slice)); + Eurydice_slice ret[4U]; + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___slice_n( + uu____1, i0 * (size_t)136U, (size_t)136U, ret); + libcrux_sha3_generic_keccak_absorb_block__core_core_arch_x86___m256i_4size_t_136size_t( + uu____0, ret); + } + size_t rem = + core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)136U; + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *uu____2 = &s; + Eurydice_slice uu____3[4U]; + memcpy(uu____3, data, (size_t)4U * sizeof(Eurydice_slice)); + Eurydice_slice ret[4U]; + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___slice_n( + uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, + ret); + libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t( + uu____2, ret); + size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); + size_t blocks = outlen / (size_t)136U; + size_t last = outlen - outlen % (size_t)136U; + if (blocks == (size_t)0U) { + libcrux_sha3_generic_keccak_squeeze_first_and_last__core_core_arch_x86___m256i_4size_t_136size_t( + &s, out); + } else { + K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ uu____4 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___split_at_mut_n( + out, (size_t)136U); + Eurydice_slice o0[4U]; + memcpy(o0, uu____4.fst, (size_t)4U * sizeof(Eurydice_slice)); + Eurydice_slice o1[4U]; + memcpy(o1, uu____4.snd, (size_t)4U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block__core_core_arch_x86___m256i_4size_t_136size_t( + &s, o0); + core_ops_range_Range__size_t iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range__size_t, core_ops_range_Range__size_t); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, core_option_Option__size_t) + .tag == core_option_None) { + break; + } else { + K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ uu____5 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___split_at_mut_n( + o1, (size_t)136U); + Eurydice_slice o[4U]; + memcpy(o, uu____5.fst, (size_t)4U * sizeof(Eurydice_slice)); + Eurydice_slice orest[4U]; + memcpy(orest, uu____5.snd, (size_t)4U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__core_core_arch_x86___m256i_4size_t_136size_t( + &s, o); + memcpy(o1, orest, (size_t)4U * sizeof(Eurydice_slice)); + } + } + if (last < outlen) { + libcrux_sha3_generic_keccak_squeeze_last__core_core_arch_x86___m256i_4size_t_136size_t( + s, o1); + } + } +} + +__attribute__((target("avx2"))) +static inline void libcrux_sha3_avx2_x4_shake256( + Eurydice_slice input0, Eurydice_slice input1, Eurydice_slice input2, + Eurydice_slice input3, Eurydice_slice out0, Eurydice_slice out1, + Eurydice_slice out2, Eurydice_slice out3) { + Eurydice_slice buf0[4U] = {input0, input1, input2, input3}; + Eurydice_slice buf[4U] = {out0, out1, out2, out3}; + libcrux_sha3_generic_keccak_keccak__core_core_arch_x86___m256i_4size_t_136size_t_31uint8_t( + buf0, buf); +} + +typedef libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + libcrux_sha3_avx2_x4_incremental_KeccakState4; + +__attribute__((target("avx2"))) +static inline libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t +libcrux_sha3_avx2_x4_incremental_shake128_init(void) { + return libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__core_core_arch_x86___m256i_4size_t(); +} + +__attribute__((target("avx2"))) +static inline void libcrux_sha3_simd_avx2_load_block___168size_t( + core_core_arch_x86___m256i (*s)[5U], Eurydice_slice blocks[4U]) { + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)32U; i++) { + size_t i0 = i; + core_core_arch_x86___m256i v00 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( + blocks[0U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m256i v10 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( + blocks[1U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m256i v20 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( + blocks[2U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m256i v30 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8(Eurydice_slice_subslice( + blocks[3U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice)); + core_core_arch_x86___m256i v0l = + libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v00, v10); + core_core_arch_x86___m256i v1h = + libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v00, v10); + core_core_arch_x86___m256i v2l = + libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v20, v30); + core_core_arch_x86___m256i v3h = + libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v20, v30); + core_core_arch_x86___m256i v0 = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)32, v0l, v2l, core_core_arch_x86___m256i); + core_core_arch_x86___m256i v1 = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)32, v1h, v3h, core_core_arch_x86___m256i); + core_core_arch_x86___m256i v2 = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)49, v0l, v2l, core_core_arch_x86___m256i); + core_core_arch_x86___m256i v3 = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)49, v1h, v3h, core_core_arch_x86___m256i); + core_core_arch_x86___m256i uu____0 = + libcrux_intrinsics_avx2_mm256_xor_si256( + s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], v0); + s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U] = uu____0; + core_core_arch_x86___m256i uu____1 = + libcrux_intrinsics_avx2_mm256_xor_si256( + s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], + v1); + s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)1U) % (size_t)5U] = uu____1; + core_core_arch_x86___m256i uu____2 = + libcrux_intrinsics_avx2_mm256_xor_si256( + s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], + v2); + s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)2U) % (size_t)5U] = uu____2; + core_core_arch_x86___m256i uu____3 = + libcrux_intrinsics_avx2_mm256_xor_si256( + s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], + v3); + s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)3U) % (size_t)5U] = uu____3; + } + size_t rem = (size_t)168U % (size_t)32U; + size_t start = (size_t)32U * ((size_t)168U / (size_t)32U); + uint8_t u8s[32U] = {0U}; + Eurydice_slice uu____4 = Eurydice_array_to_subslice( + (size_t)32U, u8s, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + Eurydice_slice_subslice(blocks[0U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = start, .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____5 = Eurydice_array_to_subslice( + (size_t)32U, u8s, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____5, + Eurydice_slice_subslice(blocks[1U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = start, .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____6 = Eurydice_array_to_subslice( + (size_t)32U, u8s, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)16U, + .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_slice_subslice(blocks[2U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = start, .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____7 = Eurydice_array_to_subslice( + (size_t)32U, u8s, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)24U, + .end = (size_t)32U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____7, + Eurydice_slice_subslice(blocks[3U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = start, .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + core_core_arch_x86___m256i u = libcrux_intrinsics_avx2_mm256_loadu_si256_u8( + core_array___Array_T__N__23__as_slice((size_t)32U, u8s, uint8_t, + Eurydice_slice)); + size_t i0 = (size_t)4U * ((size_t)168U / (size_t)32U) / (size_t)5U; + size_t j0 = (size_t)4U * ((size_t)168U / (size_t)32U) % (size_t)5U; + core_core_arch_x86___m256i uu____8 = + libcrux_intrinsics_avx2_mm256_xor_si256(s[i0][j0], u); + s[i0][j0] = uu____8; + if (rem == (size_t)16U) { + uint8_t u8s0[32U] = {0U}; + Eurydice_slice uu____9 = Eurydice_array_to_subslice( + (size_t)32U, u8s0, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____9, + Eurydice_slice_subslice( + blocks[0U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = start + (size_t)8U, .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____10 = Eurydice_array_to_subslice( + (size_t)32U, u8s0, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____10, + Eurydice_slice_subslice( + blocks[1U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = start + (size_t)8U, .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____11 = Eurydice_array_to_subslice( + (size_t)32U, u8s0, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)16U, + .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____11, + Eurydice_slice_subslice( + blocks[2U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = start + (size_t)8U, .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____12 = Eurydice_array_to_subslice( + (size_t)32U, u8s0, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)24U, + .end = (size_t)32U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____12, + Eurydice_slice_subslice( + blocks[3U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = start + (size_t)8U, .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + core_core_arch_x86___m256i u0 = + libcrux_intrinsics_avx2_mm256_loadu_si256_u8( + core_array___Array_T__N__23__as_slice((size_t)32U, u8s0, uint8_t, + Eurydice_slice)); + size_t i = + ((size_t)4U * ((size_t)168U / (size_t)32U) + (size_t)1U) / (size_t)5U; + size_t j = + ((size_t)4U * ((size_t)168U / (size_t)32U) + (size_t)1U) % (size_t)5U; + core_core_arch_x86___m256i uu____13 = + libcrux_intrinsics_avx2_mm256_xor_si256(s[i][j], u0); + s[i][j] = uu____13; + } +} + +__attribute__((target("avx2"))) +static inline void libcrux_sha3_simd_avx2_load_block_full___168size_t( + core_core_arch_x86___m256i (*s)[5U], uint8_t blocks[4U][200U]) { + core_core_arch_x86___m256i(*uu____0)[5U] = s; + Eurydice_slice uu____1 = Eurydice_array_to_slice((size_t)200U, blocks[0U], + uint8_t, Eurydice_slice); + Eurydice_slice uu____2 = Eurydice_array_to_slice((size_t)200U, blocks[1U], + uint8_t, Eurydice_slice); + Eurydice_slice uu____3 = Eurydice_array_to_slice((size_t)200U, blocks[2U], + uint8_t, Eurydice_slice); + Eurydice_slice buf[4U] = {uu____1, uu____2, uu____3, + Eurydice_array_to_slice((size_t)200U, blocks[3U], + uint8_t, Eurydice_slice)}; + libcrux_sha3_simd_avx2_load_block___168size_t(uu____0, buf); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___load_block_full___168size_t( + core_core_arch_x86___m256i (*a)[5U], uint8_t b[4U][200U]) { + core_core_arch_x86___m256i(*uu____0)[5U] = a; + uint8_t uu____1[4U][200U]; + memcpy(uu____1, b, (size_t)4U * sizeof(uint8_t[200U])); + libcrux_sha3_simd_avx2_load_block_full___168size_t(uu____0, uu____1); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_168size_t_31uint8_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice last[4U]) { + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[4U][200U] = {{0U}}; + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)200U, blocks[i0], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = last_len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i0], + uint8_t, void *); + blocks[i0][last_len] = 31U; + blocks[i0][(size_t)168U - (size_t)1U] = + (uint32_t)blocks[i0][(size_t)168U - (size_t)1U] | 128U;); + core_core_arch_x86___m256i(*uu____1)[5U] = s->st; + uint8_t uu____2[4U][200U]; + memcpy(uu____2, blocks, (size_t)4U * sizeof(uint8_t[200U])); + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___load_block_full___168size_t( + uu____1, uu____2); + libcrux_sha3_generic_keccak_keccakf1600__core_core_arch_x86___m256i_4size_t( + s); +} + +__attribute__((target("avx2"))) +static inline void libcrux_sha3_avx2_x4_incremental_shake128_absorb_final( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice data0, Eurydice_slice data1, Eurydice_slice data2, + Eurydice_slice data3) { + Eurydice_slice buf[4U] = {data0, data1, data2, data3}; + libcrux_sha3_generic_keccak_absorb_final__core_core_arch_x86___m256i_4size_t_168size_t_31uint8_t( + s, buf); +} + +__attribute__((target("avx2"))) +static inline void libcrux_sha3_simd_avx2_store_block___168size_t( + core_core_arch_x86___m256i (*s)[5U], Eurydice_slice out[4U]) { + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)32U; i++) { + size_t i0 = i; + core_core_arch_x86___m256i v0l = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)32, + s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], + s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], + core_core_arch_x86___m256i); + core_core_arch_x86___m256i v1h = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)32, + s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], + s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], + core_core_arch_x86___m256i); + core_core_arch_x86___m256i v2l = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)49, + s[(size_t)4U * i0 / (size_t)5U][(size_t)4U * i0 % (size_t)5U], + s[((size_t)4U * i0 + (size_t)2U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)2U) % (size_t)5U], + core_core_arch_x86___m256i); + core_core_arch_x86___m256i v3h = + libcrux_intrinsics_avx2_mm256_permute2x128_si256( + (int32_t)49, + s[((size_t)4U * i0 + (size_t)1U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)1U) % (size_t)5U], + s[((size_t)4U * i0 + (size_t)3U) / (size_t)5U] + [((size_t)4U * i0 + (size_t)3U) % (size_t)5U], + core_core_arch_x86___m256i); + core_core_arch_x86___m256i v0 = + libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v0l, v1h); + core_core_arch_x86___m256i v1 = + libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v0l, v1h); + core_core_arch_x86___m256i v2 = + libcrux_intrinsics_avx2_mm256_unpacklo_epi64(v2l, v3h); + core_core_arch_x86___m256i v3 = + libcrux_intrinsics_avx2_mm256_unpackhi_epi64(v2l, v3h); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8( + Eurydice_slice_subslice(out[0U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v0); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8( + Eurydice_slice_subslice(out[1U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v1); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8( + Eurydice_slice_subslice(out[2U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v2); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8( + Eurydice_slice_subslice(out[3U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)32U * i0, + .end = (size_t)32U * (i0 + (size_t)1U)}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + v3); + } + size_t rem = (size_t)168U % (size_t)32U; + size_t start = (size_t)32U * ((size_t)168U / (size_t)32U); + uint8_t u8s[32U] = {0U}; + size_t i0 = (size_t)4U * ((size_t)168U / (size_t)32U) / (size_t)5U; + size_t j0 = (size_t)4U * ((size_t)168U / (size_t)32U) % (size_t)5U; + Eurydice_slice uu____0 = + Eurydice_array_to_slice((size_t)32U, u8s, uint8_t, Eurydice_slice); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____0, s[i0][j0]); + Eurydice_slice uu____1 = Eurydice_slice_subslice( + out[0U], + (CLITERAL(core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____1, + Eurydice_array_to_subslice((size_t)32U, u8s, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____2 = Eurydice_slice_subslice( + out[1U], + (CLITERAL(core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____2, + Eurydice_array_to_subslice((size_t)32U, u8s, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)8U, .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____3 = Eurydice_slice_subslice( + out[2U], + (CLITERAL(core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____3, + Eurydice_array_to_subslice((size_t)32U, u8s, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)16U, .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____4 = Eurydice_slice_subslice( + out[3U], + (CLITERAL(core_ops_range_Range__size_t){.start = start, + .end = start + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____4, + Eurydice_array_to_subslice((size_t)32U, u8s, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)24U, .end = (size_t)32U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + if (rem == (size_t)16U) { + uint8_t u8s0[32U] = {0U}; + size_t i = + ((size_t)4U * ((size_t)168U / (size_t)32U) + (size_t)1U) / (size_t)5U; + size_t j = + ((size_t)4U * ((size_t)168U / (size_t)32U) + (size_t)1U) % (size_t)5U; + Eurydice_slice uu____5 = + Eurydice_array_to_slice((size_t)32U, u8s0, uint8_t, Eurydice_slice); + libcrux_intrinsics_avx2_mm256_storeu_si256_u8(uu____5, s[i][j]); + Eurydice_slice uu____6 = Eurydice_slice_subslice( + out[0U], + (CLITERAL(core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____6, + Eurydice_array_to_subslice((size_t)32U, u8s0, + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)0U, .end = (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____7 = Eurydice_slice_subslice( + out[1U], + (CLITERAL(core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____7, + Eurydice_array_to_subslice( + (size_t)32U, u8s0, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)8U, + .end = (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____8 = Eurydice_slice_subslice( + out[2U], + (CLITERAL(core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____8, + Eurydice_array_to_subslice( + (size_t)32U, u8s0, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)16U, + .end = (size_t)24U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + Eurydice_slice uu____9 = Eurydice_slice_subslice( + out[3U], + (CLITERAL(core_ops_range_Range__size_t){.start = start + (size_t)8U, + .end = start + (size_t)16U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice( + uu____9, + Eurydice_array_to_subslice( + (size_t)32U, u8s0, + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)24U, + .end = (size_t)32U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + uint8_t, void *); + } +} + +__attribute__((target("avx2"))) +static inline void +libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___store_block___168size_t( + core_core_arch_x86___m256i (*a)[5U], Eurydice_slice b[4U]) { + libcrux_sha3_simd_avx2_store_block___168size_t(a, b); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_sha3_generic_keccak_squeeze_next_block__core_core_arch_x86___m256i_4size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out[4U]) { + libcrux_sha3_generic_keccak_keccakf1600__core_core_arch_x86___m256i_4size_t( + s); + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___store_block___168size_t( + s->st, out); +} + +__attribute__((target("avx2"))) +static inline void libcrux_sha3_avx2_x4_incremental_shake128_squeeze_next_block( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out0, Eurydice_slice out1, Eurydice_slice out2, + Eurydice_slice out3) { + Eurydice_slice buf[4U] = {out0, out1, out2, out3}; + libcrux_sha3_generic_keccak_squeeze_next_block__core_core_arch_x86___m256i_4size_t_168size_t( + s, buf); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_sha3_generic_keccak_squeeze_first_block__core_core_arch_x86___m256i_4size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out[4U]) { + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___store_block___168size_t( + s->st, out); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_sha3_generic_keccak_squeeze_first_three_blocks__core_core_arch_x86___m256i_4size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out[4U]) { + K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ uu____0 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___split_at_mut_n( + out, (size_t)168U); + Eurydice_slice o0[4U]; + memcpy(o0, uu____0.fst, (size_t)4U * sizeof(Eurydice_slice)); + Eurydice_slice o10[4U]; + memcpy(o10, uu____0.snd, (size_t)4U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block__core_core_arch_x86___m256i_4size_t_168size_t( + s, o0); + K___Eurydice_slice_uint8_t_4size_t__Eurydice_slice_uint8_t_4size_t_ uu____1 = + libcrux_sha3_simd_avx2___libcrux_sha3__traits__internal__KeccakItem_4__usize__for_core__core_arch__x86____m256i___split_at_mut_n( + o10, (size_t)168U); + Eurydice_slice o1[4U]; + memcpy(o1, uu____1.fst, (size_t)4U * sizeof(Eurydice_slice)); + Eurydice_slice o2[4U]; + memcpy(o2, uu____1.snd, (size_t)4U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__core_core_arch_x86___m256i_4size_t_168size_t( + s, o1); + libcrux_sha3_generic_keccak_squeeze_next_block__core_core_arch_x86___m256i_4size_t_168size_t( + s, o2); +} + +__attribute__((target("avx2"))) +static inline void +libcrux_sha3_avx2_x4_incremental_shake128_squeeze_first_three_blocks( + libcrux_sha3_generic_keccak_KeccakState__core_core_arch_x86___m256i__4size_t + *s, + Eurydice_slice out0, Eurydice_slice out1, Eurydice_slice out2, + Eurydice_slice out3) { + Eurydice_slice buf[4U] = {out0, out1, out2, out3}; + libcrux_sha3_generic_keccak_squeeze_first_three_blocks__core_core_arch_x86___m256i_4size_t_168size_t( + s, buf); +} + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_sha3_avx2_H_DEFINED +#endif diff --git a/libcrux-ml-kem/cg/libcrux_sha3_portable.h b/libcrux-ml-kem/cg/libcrux_sha3_portable.h new file mode 100644 index 000000000..dc6234dd4 --- /dev/null +++ b/libcrux-ml-kem/cg/libcrux_sha3_portable.h @@ -0,0 +1,2752 @@ +/* + This file was generated by KaRaMeL + KaRaMeL invocation: /home/franziskus/eurydice//eurydice --config ../cg.yaml + ../../libcrux_ml_kem.llbc ../../libcrux_sha3.llbc F* version: + KaRaMeL version: 409fe455 + */ + +#ifndef __libcrux_sha3_portable_H +#define __libcrux_sha3_portable_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "eurydice_glue.h" +#include "libcrux_core.h" + +static const uint64_t libcrux_sha3_generic_keccak_ROUNDCONSTANTS[24U] = { + 1ULL, + 32898ULL, + 9223372036854808714ULL, + 9223372039002292224ULL, + 32907ULL, + 2147483649ULL, + 9223372039002292353ULL, + 9223372036854808585ULL, + 138ULL, + 136ULL, + 2147516425ULL, + 2147483658ULL, + 2147516555ULL, + 9223372036854775947ULL, + 9223372036854808713ULL, + 9223372036854808579ULL, + 9223372036854808578ULL, + 9223372036854775936ULL, + 32778ULL, + 9223372039002259466ULL, + 9223372039002292353ULL, + 9223372036854808704ULL, + 2147483649ULL, + 9223372039002292232ULL}; + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero( + void) { + return 0ULL; +} + +static inline uint64_t libcrux_sha3_portable_keccak__veor5q_u64( + uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint64_t e) { + uint64_t ab = a ^ b; + uint64_t cd = c ^ d; + uint64_t abcd = ab ^ cd; + return abcd ^ e; +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor5( + uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint64_t e) { + return libcrux_sha3_portable_keccak__veor5q_u64(a, b, c, d, e); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___1int32_t_63int32_t(uint64_t x) { + return x << (uint32_t)(int32_t)1 | x >> (uint32_t)(int32_t)63; +} + +static inline uint64_t libcrux_sha3_portable_keccak__vrax1q_u64(uint64_t a, + uint64_t b) { + uint64_t uu____0 = a; + return uu____0 ^ + libcrux_sha3_portable_keccak_rotate_left___1int32_t_63int32_t(b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( + uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vrax1q_u64(a, b); +} + +static inline uint64_t libcrux_sha3_portable_keccak__vbcaxq_u64(uint64_t a, + uint64_t b, + uint64_t c) { + return a ^ (b & ~c); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___and_not_xor( + uint64_t a, uint64_t b, uint64_t c) { + return libcrux_sha3_portable_keccak__vbcaxq_u64(a, b, c); +} + +static inline uint64_t libcrux_sha3_portable_keccak__veorq_n_u64(uint64_t a, + uint64_t c) { + return a ^ c; +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_constant( + uint64_t a, uint64_t c) { + return libcrux_sha3_portable_keccak__veorq_n_u64(a, c); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor( + uint64_t a, uint64_t b) { + return a ^ b; +} + +static inline void libcrux_sha3_portable_keccak_slice_1( + Eurydice_slice a[1U], size_t start, size_t len, Eurydice_slice ret[1U]) { + ret[0U] = Eurydice_slice_subslice(a[0U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = start, .end = start + len}), + uint8_t, core_ops_range_Range__size_t, + Eurydice_slice); +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___slice_n( + Eurydice_slice a[1U], size_t start, size_t len, Eurydice_slice ret[1U]) { + Eurydice_slice uu____0[1U]; + memcpy(uu____0, a, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret0[1U]; + libcrux_sha3_portable_keccak_slice_1(uu____0, start, len, ret0); + memcpy(ret, ret0, (size_t)1U * sizeof(Eurydice_slice)); +} + +static inline K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ +libcrux_sha3_portable_keccak_split_at_mut_1(Eurydice_slice out[1U], + size_t mid) { + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t uu____0 = + core_slice___Slice_T___split_at_mut( + out[0U], mid, uint8_t, + K___Eurydice_slice_uint8_t_Eurydice_slice_uint8_t); + Eurydice_slice out00 = uu____0.fst; + Eurydice_slice out01 = uu____0.snd; + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ lit; + lit.fst[0U] = out00; + lit.snd[0U] = out01; + return lit; +} + +static inline K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( + Eurydice_slice a[1U], size_t mid) { + return libcrux_sha3_portable_keccak_split_at_mut_1(a, mid); +} + +typedef struct libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t_s { + uint64_t st[5U][5U]; +} libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t; + +static inline libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t +libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t( + void) { + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t lit; + lit.st[0U][0U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); + lit.st[0U][1U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); + lit.st[0U][2U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); + lit.st[0U][3U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); + lit.st[0U][4U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); + lit.st[1U][0U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); + lit.st[1U][1U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); + lit.st[1U][2U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); + lit.st[1U][3U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); + lit.st[1U][4U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); + lit.st[2U][0U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); + lit.st[2U][1U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); + lit.st[2U][2U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); + lit.st[2U][3U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); + lit.st[2U][4U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); + lit.st[3U][0U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); + lit.st[3U][1U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); + lit.st[3U][2U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); + lit.st[3U][3U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); + lit.st[3U][4U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); + lit.st[4U][0U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); + lit.st[4U][1U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); + lit.st[4U][2U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); + lit.st[4U][3U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); + lit.st[4U][4U] = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___zero(); + return lit; +} + +static inline void libcrux_sha3_portable_keccak_load_block___72size_t( + uint64_t (*s)[5U], Eurydice_slice blocks[1U]) { + for (size_t i = (size_t)0U; i < (size_t)72U / (size_t)8U; i++) { + size_t i0 = i; + uint8_t ret[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_slice_subslice( + blocks[0U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + Eurydice_slice, uint8_t[8U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + dst, ret); + uint64_t uu____0 = core_num__u64_9__from_le_bytes(ret); + size_t uu____1 = i0 / (size_t)5U; + size_t uu____2 = i0 % (size_t)5U; + s[uu____1][uu____2] = s[uu____1][uu____2] ^ uu____0; + } +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block___72size_t( + uint64_t (*a)[5U], Eurydice_slice b[1U]) { + uint64_t(*uu____0)[5U] = a; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, b, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak_load_block___72size_t(uu____0, uu____1); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___36int32_t_28int32_t(uint64_t x) { + return x << (uint32_t)(int32_t)36 | x >> (uint32_t)(int32_t)28; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___36int32_t_28int32_t(uint64_t a, + uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___36int32_t_28int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___36int32_t_28int32_t( + uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64___36int32_t_28int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___3int32_t_61int32_t(uint64_t x) { + return x << (uint32_t)(int32_t)3 | x >> (uint32_t)(int32_t)61; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___3int32_t_61int32_t(uint64_t a, + uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___3int32_t_61int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___3int32_t_61int32_t( + uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64___3int32_t_61int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___41int32_t_23int32_t(uint64_t x) { + return x << (uint32_t)(int32_t)41 | x >> (uint32_t)(int32_t)23; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___41int32_t_23int32_t(uint64_t a, + uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___41int32_t_23int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___41int32_t_23int32_t( + uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64___41int32_t_23int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___18int32_t_46int32_t(uint64_t x) { + return x << (uint32_t)(int32_t)18 | x >> (uint32_t)(int32_t)46; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___18int32_t_46int32_t(uint64_t a, + uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___18int32_t_46int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___18int32_t_46int32_t( + uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64___18int32_t_46int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___1int32_t_63int32_t(uint64_t a, + uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___1int32_t_63int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___1int32_t_63int32_t( + uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64___1int32_t_63int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___44int32_t_20int32_t(uint64_t x) { + return x << (uint32_t)(int32_t)44 | x >> (uint32_t)(int32_t)20; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___44int32_t_20int32_t(uint64_t a, + uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___44int32_t_20int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___44int32_t_20int32_t( + uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64___44int32_t_20int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___10int32_t_54int32_t(uint64_t x) { + return x << (uint32_t)(int32_t)10 | x >> (uint32_t)(int32_t)54; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___10int32_t_54int32_t(uint64_t a, + uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___10int32_t_54int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___10int32_t_54int32_t( + uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64___10int32_t_54int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___45int32_t_19int32_t(uint64_t x) { + return x << (uint32_t)(int32_t)45 | x >> (uint32_t)(int32_t)19; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___45int32_t_19int32_t(uint64_t a, + uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___45int32_t_19int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___45int32_t_19int32_t( + uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64___45int32_t_19int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___2int32_t_62int32_t(uint64_t x) { + return x << (uint32_t)(int32_t)2 | x >> (uint32_t)(int32_t)62; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___2int32_t_62int32_t(uint64_t a, + uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___2int32_t_62int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___2int32_t_62int32_t( + uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64___2int32_t_62int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___62int32_t_2int32_t(uint64_t x) { + return x << (uint32_t)(int32_t)62 | x >> (uint32_t)(int32_t)2; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___62int32_t_2int32_t(uint64_t a, + uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___62int32_t_2int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___62int32_t_2int32_t( + uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64___62int32_t_2int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___6int32_t_58int32_t(uint64_t x) { + return x << (uint32_t)(int32_t)6 | x >> (uint32_t)(int32_t)58; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___6int32_t_58int32_t(uint64_t a, + uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___6int32_t_58int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___6int32_t_58int32_t( + uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64___6int32_t_58int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___43int32_t_21int32_t(uint64_t x) { + return x << (uint32_t)(int32_t)43 | x >> (uint32_t)(int32_t)21; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___43int32_t_21int32_t(uint64_t a, + uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___43int32_t_21int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___43int32_t_21int32_t( + uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64___43int32_t_21int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___15int32_t_49int32_t(uint64_t x) { + return x << (uint32_t)(int32_t)15 | x >> (uint32_t)(int32_t)49; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___15int32_t_49int32_t(uint64_t a, + uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___15int32_t_49int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___15int32_t_49int32_t( + uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64___15int32_t_49int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___61int32_t_3int32_t(uint64_t x) { + return x << (uint32_t)(int32_t)61 | x >> (uint32_t)(int32_t)3; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___61int32_t_3int32_t(uint64_t a, + uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___61int32_t_3int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___61int32_t_3int32_t( + uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64___61int32_t_3int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___28int32_t_36int32_t(uint64_t x) { + return x << (uint32_t)(int32_t)28 | x >> (uint32_t)(int32_t)36; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___28int32_t_36int32_t(uint64_t a, + uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___28int32_t_36int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___28int32_t_36int32_t( + uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64___28int32_t_36int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___55int32_t_9int32_t(uint64_t x) { + return x << (uint32_t)(int32_t)55 | x >> (uint32_t)(int32_t)9; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___55int32_t_9int32_t(uint64_t a, + uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___55int32_t_9int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___55int32_t_9int32_t( + uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64___55int32_t_9int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___25int32_t_39int32_t(uint64_t x) { + return x << (uint32_t)(int32_t)25 | x >> (uint32_t)(int32_t)39; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___25int32_t_39int32_t(uint64_t a, + uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___25int32_t_39int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___25int32_t_39int32_t( + uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64___25int32_t_39int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___21int32_t_43int32_t(uint64_t x) { + return x << (uint32_t)(int32_t)21 | x >> (uint32_t)(int32_t)43; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___21int32_t_43int32_t(uint64_t a, + uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___21int32_t_43int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___21int32_t_43int32_t( + uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64___21int32_t_43int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___56int32_t_8int32_t(uint64_t x) { + return x << (uint32_t)(int32_t)56 | x >> (uint32_t)(int32_t)8; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___56int32_t_8int32_t(uint64_t a, + uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___56int32_t_8int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___56int32_t_8int32_t( + uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64___56int32_t_8int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___27int32_t_37int32_t(uint64_t x) { + return x << (uint32_t)(int32_t)27 | x >> (uint32_t)(int32_t)37; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___27int32_t_37int32_t(uint64_t a, + uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___27int32_t_37int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___27int32_t_37int32_t( + uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64___27int32_t_37int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___20int32_t_44int32_t(uint64_t x) { + return x << (uint32_t)(int32_t)20 | x >> (uint32_t)(int32_t)44; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___20int32_t_44int32_t(uint64_t a, + uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___20int32_t_44int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___20int32_t_44int32_t( + uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64___20int32_t_44int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___39int32_t_25int32_t(uint64_t x) { + return x << (uint32_t)(int32_t)39 | x >> (uint32_t)(int32_t)25; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___39int32_t_25int32_t(uint64_t a, + uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___39int32_t_25int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___39int32_t_25int32_t( + uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64___39int32_t_25int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___8int32_t_56int32_t(uint64_t x) { + return x << (uint32_t)(int32_t)8 | x >> (uint32_t)(int32_t)56; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___8int32_t_56int32_t(uint64_t a, + uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___8int32_t_56int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___8int32_t_56int32_t( + uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64___8int32_t_56int32_t(a, b); +} + +static inline uint64_t +libcrux_sha3_portable_keccak_rotate_left___14int32_t_50int32_t(uint64_t x) { + return x << (uint32_t)(int32_t)14 | x >> (uint32_t)(int32_t)50; +} + +static inline uint64_t +libcrux_sha3_portable_keccak__vxarq_u64___14int32_t_50int32_t(uint64_t a, + uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left___14int32_t_50int32_t(ab); +} + +static inline uint64_t +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___14int32_t_50int32_t( + uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64___14int32_t_50int32_t(a, b); +} + +static inline void libcrux_sha3_generic_keccak_theta_rho__uint64_t_1size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s) { + uint64_t uu____0 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor5( + s->st[0U][0U], s->st[1U][0U], s->st[2U][0U], s->st[3U][0U], + s->st[4U][0U]); + uint64_t uu____1 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor5( + s->st[0U][1U], s->st[1U][1U], s->st[2U][1U], s->st[3U][1U], + s->st[4U][1U]); + uint64_t uu____2 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor5( + s->st[0U][2U], s->st[1U][2U], s->st[2U][2U], s->st[3U][2U], + s->st[4U][2U]); + uint64_t uu____3 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor5( + s->st[0U][3U], s->st[1U][3U], s->st[2U][3U], s->st[3U][3U], + s->st[4U][3U]); + uint64_t c[5U] = { + uu____0, uu____1, uu____2, uu____3, + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor5( + s->st[0U][4U], s->st[1U][4U], s->st[2U][4U], s->st[3U][4U], + s->st[4U][4U])}; + uint64_t uu____4 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( + c[((size_t)0U + (size_t)4U) % (size_t)5U], + c[((size_t)0U + (size_t)1U) % (size_t)5U]); + uint64_t uu____5 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( + c[((size_t)1U + (size_t)4U) % (size_t)5U], + c[((size_t)1U + (size_t)1U) % (size_t)5U]); + uint64_t uu____6 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( + c[((size_t)2U + (size_t)4U) % (size_t)5U], + c[((size_t)2U + (size_t)1U) % (size_t)5U]); + uint64_t uu____7 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( + c[((size_t)3U + (size_t)4U) % (size_t)5U], + c[((size_t)3U + (size_t)1U) % (size_t)5U]); + uint64_t t[5U] = { + uu____4, uu____5, uu____6, uu____7, + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___rotate_left1_and_xor( + c[((size_t)4U + (size_t)4U) % (size_t)5U], + c[((size_t)4U + (size_t)1U) % (size_t)5U])}; + uint64_t uu____8 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor( + s->st[0U][0U], t[0U]); + s->st[0U][0U] = uu____8; + uint64_t uu____9 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___36int32_t_28int32_t( + s->st[1U][0U], t[0U]); + s->st[1U][0U] = uu____9; + uint64_t uu____10 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___3int32_t_61int32_t( + s->st[2U][0U], t[0U]); + s->st[2U][0U] = uu____10; + uint64_t uu____11 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___41int32_t_23int32_t( + s->st[3U][0U], t[0U]); + s->st[3U][0U] = uu____11; + uint64_t uu____12 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___18int32_t_46int32_t( + s->st[4U][0U], t[0U]); + s->st[4U][0U] = uu____12; + uint64_t uu____13 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___1int32_t_63int32_t( + s->st[0U][1U], t[1U]); + s->st[0U][1U] = uu____13; + uint64_t uu____14 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___44int32_t_20int32_t( + s->st[1U][1U], t[1U]); + s->st[1U][1U] = uu____14; + uint64_t uu____15 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___10int32_t_54int32_t( + s->st[2U][1U], t[1U]); + s->st[2U][1U] = uu____15; + uint64_t uu____16 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___45int32_t_19int32_t( + s->st[3U][1U], t[1U]); + s->st[3U][1U] = uu____16; + uint64_t uu____17 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___2int32_t_62int32_t( + s->st[4U][1U], t[1U]); + s->st[4U][1U] = uu____17; + uint64_t uu____18 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___62int32_t_2int32_t( + s->st[0U][2U], t[2U]); + s->st[0U][2U] = uu____18; + uint64_t uu____19 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___6int32_t_58int32_t( + s->st[1U][2U], t[2U]); + s->st[1U][2U] = uu____19; + uint64_t uu____20 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___43int32_t_21int32_t( + s->st[2U][2U], t[2U]); + s->st[2U][2U] = uu____20; + uint64_t uu____21 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___15int32_t_49int32_t( + s->st[3U][2U], t[2U]); + s->st[3U][2U] = uu____21; + uint64_t uu____22 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___61int32_t_3int32_t( + s->st[4U][2U], t[2U]); + s->st[4U][2U] = uu____22; + uint64_t uu____23 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___28int32_t_36int32_t( + s->st[0U][3U], t[3U]); + s->st[0U][3U] = uu____23; + uint64_t uu____24 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___55int32_t_9int32_t( + s->st[1U][3U], t[3U]); + s->st[1U][3U] = uu____24; + uint64_t uu____25 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___25int32_t_39int32_t( + s->st[2U][3U], t[3U]); + s->st[2U][3U] = uu____25; + uint64_t uu____26 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___21int32_t_43int32_t( + s->st[3U][3U], t[3U]); + s->st[3U][3U] = uu____26; + uint64_t uu____27 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___56int32_t_8int32_t( + s->st[4U][3U], t[3U]); + s->st[4U][3U] = uu____27; + uint64_t uu____28 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___27int32_t_37int32_t( + s->st[0U][4U], t[4U]); + s->st[0U][4U] = uu____28; + uint64_t uu____29 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___20int32_t_44int32_t( + s->st[1U][4U], t[4U]); + s->st[1U][4U] = uu____29; + uint64_t uu____30 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___39int32_t_25int32_t( + s->st[2U][4U], t[4U]); + s->st[2U][4U] = uu____30; + uint64_t uu____31 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___8int32_t_56int32_t( + s->st[3U][4U], t[4U]); + s->st[3U][4U] = uu____31; + uint64_t uu____32 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_and_rotate___14int32_t_50int32_t( + s->st[4U][4U], t[4U]); + s->st[4U][4U] = uu____32; +} + +static inline void libcrux_sha3_generic_keccak_pi__uint64_t_1size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s) { + uint64_t old[5U][5U]; + core_array___core__clone__Clone_for__Array_T__N___20__clone( + (size_t)5U, s->st, old, uint64_t[5U], void *); + s->st[0U][1U] = old[1U][1U]; + s->st[0U][2U] = old[2U][2U]; + s->st[0U][3U] = old[3U][3U]; + s->st[0U][4U] = old[4U][4U]; + s->st[1U][0U] = old[0U][3U]; + s->st[1U][1U] = old[1U][4U]; + s->st[1U][2U] = old[2U][0U]; + s->st[1U][3U] = old[3U][1U]; + s->st[1U][4U] = old[4U][2U]; + s->st[2U][0U] = old[0U][1U]; + s->st[2U][1U] = old[1U][2U]; + s->st[2U][2U] = old[2U][3U]; + s->st[2U][3U] = old[3U][4U]; + s->st[2U][4U] = old[4U][0U]; + s->st[3U][0U] = old[0U][4U]; + s->st[3U][1U] = old[1U][0U]; + s->st[3U][2U] = old[2U][1U]; + s->st[3U][3U] = old[3U][2U]; + s->st[3U][4U] = old[4U][3U]; + s->st[4U][0U] = old[0U][2U]; + s->st[4U][1U] = old[1U][3U]; + s->st[4U][2U] = old[2U][4U]; + s->st[4U][3U] = old[3U][0U]; + s->st[4U][4U] = old[4U][1U]; +} + +static inline void libcrux_sha3_generic_keccak_chi__uint64_t_1size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s) { + uint64_t old[5U][5U]; + memcpy(old, s->st, (size_t)5U * sizeof(uint64_t[5U])); + KRML_MAYBE_FOR5( + i0, (size_t)0U, (size_t)5U, (size_t)1U, size_t i1 = i0; KRML_MAYBE_FOR5( + i, (size_t)0U, (size_t)5U, (size_t)1U, size_t j = i; + uint64_t uu____0 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___and_not_xor( + s->st[i1][j], old[i1][(j + (size_t)2U) % (size_t)5U], + old[i1][(j + (size_t)1U) % (size_t)5U]); + s->st[i1][j] = uu____0;);); +} + +static inline void libcrux_sha3_generic_keccak_iota__uint64_t_1size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, size_t i) { + uint64_t uu____0 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___xor_constant( + s->st[0U][0U], libcrux_sha3_generic_keccak_ROUNDCONSTANTS[i]); + s->st[0U][0U] = uu____0; +} + +static inline void libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s) { + for (size_t i = (size_t)0U; i < (size_t)24U; i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_theta_rho__uint64_t_1size_t(s); + libcrux_sha3_generic_keccak_pi__uint64_t_1size_t(s); + libcrux_sha3_generic_keccak_chi__uint64_t_1size_t(s); + libcrux_sha3_generic_keccak_iota__uint64_t_1size_t(s, i0); + } +} + +static inline void +libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_72size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice blocks[1U]) { + uint64_t(*uu____0)[5U] = s->st; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block___72size_t( + uu____0, uu____1); + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); +} + +static inline void libcrux_sha3_portable_keccak_load_block_full___72size_t( + uint64_t (*s)[5U], uint8_t blocks[1U][200U]) { + uint64_t(*uu____0)[5U] = s; + Eurydice_slice buf[1U] = {Eurydice_array_to_slice((size_t)200U, blocks[0U], + uint8_t, Eurydice_slice)}; + libcrux_sha3_portable_keccak_load_block___72size_t(uu____0, buf); +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block_full___72size_t( + uint64_t (*a)[5U], uint8_t b[1U][200U]) { + uint64_t(*uu____0)[5U] = a; + uint8_t uu____1[1U][200U]; + memcpy(uu____1, b, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak_load_block_full___72size_t(uu____0, uu____1); +} + +static inline void +libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_72size_t_6uint8_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice last[1U]) { + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[1U][200U] = {{0U}}; + { + size_t i = (size_t)0U; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)200U, blocks[i], + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = last_len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); + blocks[i][last_len] = 6U; + blocks[i][(size_t)72U - (size_t)1U] = + (uint32_t)blocks[i][(size_t)72U - (size_t)1U] | 128U; + } + uint64_t(*uu____1)[5U] = s->st; + uint8_t uu____2[1U][200U]; + memcpy(uu____2, blocks, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block_full___72size_t( + uu____1, uu____2); + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); +} + +static inline void libcrux_sha3_portable_keccak_store_block___72size_t( + uint64_t (*s)[5U], Eurydice_slice out[1U]) { + for (size_t i = (size_t)0U; i < (size_t)72U / (size_t)8U; i++) { + size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_slice_subslice( + out[0U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret[8U]; + core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline void libcrux_sha3_portable_keccak_store_block_full___72size_t( + uint64_t (*s)[5U], uint8_t ret[1U][200U]) { + uint8_t out[200U] = {0U}; + uint64_t(*uu____0)[5U] = s; + Eurydice_slice buf[1U] = { + Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice)}; + libcrux_sha3_portable_keccak_store_block___72size_t(uu____0, buf); + uint8_t uu____1[200U]; + memcpy(uu____1, out, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[0U], uu____1, (size_t)200U * sizeof(uint8_t)); +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___72size_t( + uint64_t (*a)[5U], uint8_t ret[1U][200U]) { + uint8_t ret0[1U][200U]; + libcrux_sha3_portable_keccak_store_block_full___72size_t(a, ret0); + memcpy(ret, ret0, (size_t)1U * sizeof(uint8_t[200U])); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_72size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___72size_t( + s->st, b); + { + size_t i = (size_t)0U; + Eurydice_slice uu____0 = out[i]; + uint8_t *uu____1 = b[i]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + } +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___72size_t( + uint64_t (*a)[5U], Eurydice_slice b[1U]) { + libcrux_sha3_portable_keccak_store_block___72size_t(a, b); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_72size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___72size_t( + s->st, out); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_72size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___72size_t( + s->st, out); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_72size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, + Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___72size_t( + s.st, b); + { + size_t i = (size_t)0U; + Eurydice_slice uu____0 = out[i]; + uint8_t *uu____1 = b[i]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + } +} + +static inline void +libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_72size_t_6uint8_t( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s = + libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)72U; + i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, data, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___slice_n( + uu____1, i0 * (size_t)72U, (size_t)72U, ret); + libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_72size_t(uu____0, + ret); + } + size_t rem = + core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)72U; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; + Eurydice_slice uu____3[1U]; + memcpy(uu____3, data, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___slice_n( + uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, + ret); + libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_72size_t_6uint8_t( + uu____2, ret); + size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); + size_t blocks = outlen / (size_t)72U; + size_t last = outlen - outlen % (size_t)72U; + if (blocks == (size_t)0U) { + libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_72size_t( + &s, out); + } else { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____4 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( + out, (size_t)72U); + Eurydice_slice o0[1U]; + memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o1[1U]; + memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_72size_t( + &s, o0); + core_ops_range_Range__size_t iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range__size_t, core_ops_range_Range__size_t); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, core_option_Option__size_t) + .tag == core_option_None) { + break; + } else { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____5 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( + o1, (size_t)72U); + Eurydice_slice o[1U]; + memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice orest[1U]; + memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_72size_t( + &s, o); + memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); + } + } + if (last < outlen) { + libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_72size_t(s, + o1); + } + } +} + +static inline void libcrux_sha3_portable_keccakx1___72size_t_6uint8_t( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + Eurydice_slice uu____0[1U]; + memcpy(uu____0, data, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_72size_t_6uint8_t( + uu____0, out); +} + +static inline void libcrux_sha3_portable_sha512(Eurydice_slice digest, + Eurydice_slice data) { + Eurydice_slice buf0[1U] = {data}; + Eurydice_slice buf[1U] = {digest}; + libcrux_sha3_portable_keccakx1___72size_t_6uint8_t(buf0, buf); +} + +static inline void libcrux_sha3_portable_keccak_load_block___136size_t( + uint64_t (*s)[5U], Eurydice_slice blocks[1U]) { + for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)8U; i++) { + size_t i0 = i; + uint8_t ret[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_slice_subslice( + blocks[0U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + Eurydice_slice, uint8_t[8U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + dst, ret); + uint64_t uu____0 = core_num__u64_9__from_le_bytes(ret); + size_t uu____1 = i0 / (size_t)5U; + size_t uu____2 = i0 % (size_t)5U; + s[uu____1][uu____2] = s[uu____1][uu____2] ^ uu____0; + } +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block___136size_t( + uint64_t (*a)[5U], Eurydice_slice b[1U]) { + uint64_t(*uu____0)[5U] = a; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, b, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak_load_block___136size_t(uu____0, uu____1); +} + +static inline void +libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice blocks[1U]) { + uint64_t(*uu____0)[5U] = s->st; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block___136size_t( + uu____0, uu____1); + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); +} + +static inline void libcrux_sha3_portable_keccak_load_block_full___136size_t( + uint64_t (*s)[5U], uint8_t blocks[1U][200U]) { + uint64_t(*uu____0)[5U] = s; + Eurydice_slice buf[1U] = {Eurydice_array_to_slice((size_t)200U, blocks[0U], + uint8_t, Eurydice_slice)}; + libcrux_sha3_portable_keccak_load_block___136size_t(uu____0, buf); +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block_full___136size_t( + uint64_t (*a)[5U], uint8_t b[1U][200U]) { + uint64_t(*uu____0)[5U] = a; + uint8_t uu____1[1U][200U]; + memcpy(uu____1, b, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak_load_block_full___136size_t(uu____0, uu____1); +} + +static inline void +libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_6uint8_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice last[1U]) { + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[1U][200U] = {{0U}}; + { + size_t i = (size_t)0U; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)200U, blocks[i], + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = last_len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); + blocks[i][last_len] = 6U; + blocks[i][(size_t)136U - (size_t)1U] = + (uint32_t)blocks[i][(size_t)136U - (size_t)1U] | 128U; + } + uint64_t(*uu____1)[5U] = s->st; + uint8_t uu____2[1U][200U]; + memcpy(uu____2, blocks, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block_full___136size_t( + uu____1, uu____2); + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); +} + +static inline void libcrux_sha3_portable_keccak_store_block___136size_t( + uint64_t (*s)[5U], Eurydice_slice out[1U]) { + for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)8U; i++) { + size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_slice_subslice( + out[0U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret[8U]; + core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline void libcrux_sha3_portable_keccak_store_block_full___136size_t( + uint64_t (*s)[5U], uint8_t ret[1U][200U]) { + uint8_t out[200U] = {0U}; + uint64_t(*uu____0)[5U] = s; + Eurydice_slice buf[1U] = { + Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice)}; + libcrux_sha3_portable_keccak_store_block___136size_t(uu____0, buf); + uint8_t uu____1[200U]; + memcpy(uu____1, out, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[0U], uu____1, (size_t)200U * sizeof(uint8_t)); +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___136size_t( + uint64_t (*a)[5U], uint8_t ret[1U][200U]) { + uint8_t ret0[1U][200U]; + libcrux_sha3_portable_keccak_store_block_full___136size_t(a, ret0); + memcpy(ret, ret0, (size_t)1U * sizeof(uint8_t[200U])); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___136size_t( + s->st, b); + { + size_t i = (size_t)0U; + Eurydice_slice uu____0 = out[i]; + uint8_t *uu____1 = b[i]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + } +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___136size_t( + uint64_t (*a)[5U], Eurydice_slice b[1U]) { + libcrux_sha3_portable_keccak_store_block___136size_t(a, b); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___136size_t( + s->st, out); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___136size_t( + s->st, out); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_136size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, + Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___136size_t( + s.st, b); + { + size_t i = (size_t)0U; + Eurydice_slice uu____0 = out[i]; + uint8_t *uu____1 = b[i]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + } +} + +static inline void +libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_6uint8_t( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s = + libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)136U; + i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, data, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___slice_n( + uu____1, i0 * (size_t)136U, (size_t)136U, ret); + libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_136size_t( + uu____0, ret); + } + size_t rem = + core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)136U; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; + Eurydice_slice uu____3[1U]; + memcpy(uu____3, data, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___slice_n( + uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, + ret); + libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_6uint8_t( + uu____2, ret); + size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); + size_t blocks = outlen / (size_t)136U; + size_t last = outlen - outlen % (size_t)136U; + if (blocks == (size_t)0U) { + libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_136size_t( + &s, out); + } else { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____4 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( + out, (size_t)136U); + Eurydice_slice o0[1U]; + memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o1[1U]; + memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_136size_t( + &s, o0); + core_ops_range_Range__size_t iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range__size_t, core_ops_range_Range__size_t); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, core_option_Option__size_t) + .tag == core_option_None) { + break; + } else { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____5 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( + o1, (size_t)136U); + Eurydice_slice o[1U]; + memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice orest[1U]; + memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_136size_t( + &s, o); + memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); + } + } + if (last < outlen) { + libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_136size_t(s, + o1); + } + } +} + +static inline void libcrux_sha3_portable_keccakx1___136size_t_6uint8_t( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + Eurydice_slice uu____0[1U]; + memcpy(uu____0, data, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_6uint8_t( + uu____0, out); +} + +static inline void libcrux_sha3_portable_sha256(Eurydice_slice digest, + Eurydice_slice data) { + Eurydice_slice buf0[1U] = {data}; + Eurydice_slice buf[1U] = {digest}; + libcrux_sha3_portable_keccakx1___136size_t_6uint8_t(buf0, buf); +} + +static inline void +libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_31uint8_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice last[1U]) { + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[1U][200U] = {{0U}}; + { + size_t i = (size_t)0U; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)200U, blocks[i], + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = last_len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); + blocks[i][last_len] = 31U; + blocks[i][(size_t)136U - (size_t)1U] = + (uint32_t)blocks[i][(size_t)136U - (size_t)1U] | 128U; + } + uint64_t(*uu____1)[5U] = s->st; + uint8_t uu____2[1U][200U]; + memcpy(uu____2, blocks, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block_full___136size_t( + uu____1, uu____2); + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); +} + +static inline void +libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_31uint8_t( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s = + libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)136U; + i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, data, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___slice_n( + uu____1, i0 * (size_t)136U, (size_t)136U, ret); + libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_136size_t( + uu____0, ret); + } + size_t rem = + core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)136U; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; + Eurydice_slice uu____3[1U]; + memcpy(uu____3, data, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___slice_n( + uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, + ret); + libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_136size_t_31uint8_t( + uu____2, ret); + size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); + size_t blocks = outlen / (size_t)136U; + size_t last = outlen - outlen % (size_t)136U; + if (blocks == (size_t)0U) { + libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_136size_t( + &s, out); + } else { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____4 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( + out, (size_t)136U); + Eurydice_slice o0[1U]; + memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o1[1U]; + memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_136size_t( + &s, o0); + core_ops_range_Range__size_t iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range__size_t, core_ops_range_Range__size_t); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, core_option_Option__size_t) + .tag == core_option_None) { + break; + } else { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____5 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( + o1, (size_t)136U); + Eurydice_slice o[1U]; + memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice orest[1U]; + memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_136size_t( + &s, o); + memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); + } + } + if (last < outlen) { + libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_136size_t(s, + o1); + } + } +} + +static inline void libcrux_sha3_portable_keccakx1___136size_t_31uint8_t( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + Eurydice_slice uu____0[1U]; + memcpy(uu____0, data, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_136size_t_31uint8_t( + uu____0, out); +} + +static inline void libcrux_sha3_portable_shake256(Eurydice_slice digest, + Eurydice_slice data) { + Eurydice_slice buf0[1U] = {data}; + Eurydice_slice buf[1U] = {digest}; + libcrux_sha3_portable_keccakx1___136size_t_31uint8_t(buf0, buf); +} + +static inline void libcrux_sha3_neon_sha512(Eurydice_slice digest, + Eurydice_slice data) { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +static inline void libcrux_sha3_neon_sha256(Eurydice_slice digest, + Eurydice_slice data) { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +static inline void libcrux_sha3_neon_x2_shake256(Eurydice_slice input0, + Eurydice_slice input1, + Eurydice_slice out0, + Eurydice_slice out1) { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +typedef libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t + libcrux_sha3_portable_KeccakState1; + +typedef struct libcrux_sha3_neon_x2_incremental_KeccakState2_s { + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t state[2U]; +} libcrux_sha3_neon_x2_incremental_KeccakState2; + +static inline libcrux_sha3_neon_x2_incremental_KeccakState2 +libcrux_sha3_neon_x2_incremental_shake128_init(void) { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +static inline void libcrux_sha3_neon_x2_incremental_shake128_absorb_final( + libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice data0, + Eurydice_slice data1) { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +static inline void libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( + libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice out0, + Eurydice_slice out1) { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +static inline void +libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( + libcrux_sha3_neon_x2_incremental_KeccakState2 *s, Eurydice_slice out0, + Eurydice_slice out1) { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +static inline libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t +libcrux_sha3_portable_incremental_shake128_init(void) { + return libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); +} + +static inline void libcrux_sha3_portable_keccak_load_block___168size_t( + uint64_t (*s)[5U], Eurydice_slice blocks[1U]) { + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)8U; i++) { + size_t i0 = i; + uint8_t ret[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_slice_subslice( + blocks[0U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + Eurydice_slice, uint8_t[8U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + dst, ret); + uint64_t uu____0 = core_num__u64_9__from_le_bytes(ret); + size_t uu____1 = i0 / (size_t)5U; + size_t uu____2 = i0 % (size_t)5U; + s[uu____1][uu____2] = s[uu____1][uu____2] ^ uu____0; + } +} + +static inline void libcrux_sha3_portable_keccak_load_block_full___168size_t( + uint64_t (*s)[5U], uint8_t blocks[1U][200U]) { + uint64_t(*uu____0)[5U] = s; + Eurydice_slice buf[1U] = {Eurydice_array_to_slice((size_t)200U, blocks[0U], + uint8_t, Eurydice_slice)}; + libcrux_sha3_portable_keccak_load_block___168size_t(uu____0, buf); +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block_full___168size_t( + uint64_t (*a)[5U], uint8_t b[1U][200U]) { + uint64_t(*uu____0)[5U] = a; + uint8_t uu____1[1U][200U]; + memcpy(uu____1, b, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak_load_block_full___168size_t(uu____0, uu____1); +} + +static inline void +libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_168size_t_31uint8_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice last[1U]) { + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[1U][200U] = {{0U}}; + { + size_t i = (size_t)0U; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)200U, blocks[i], + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = last_len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); + blocks[i][last_len] = 31U; + blocks[i][(size_t)168U - (size_t)1U] = + (uint32_t)blocks[i][(size_t)168U - (size_t)1U] | 128U; + } + uint64_t(*uu____1)[5U] = s->st; + uint8_t uu____2[1U][200U]; + memcpy(uu____2, blocks, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block_full___168size_t( + uu____1, uu____2); + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); +} + +static inline void libcrux_sha3_portable_incremental_shake128_absorb_final( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice data0) { + Eurydice_slice buf[1U] = {data0}; + libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_168size_t_31uint8_t( + s, buf); +} + +static inline void libcrux_sha3_portable_keccak_store_block___168size_t( + uint64_t (*s)[5U], Eurydice_slice out[1U]) { + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)8U; i++) { + size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_slice_subslice( + out[0U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret[8U]; + core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___168size_t( + uint64_t (*a)[5U], Eurydice_slice b[1U]) { + libcrux_sha3_portable_keccak_store_block___168size_t(a, b); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___168size_t( + s->st, out); +} + +static inline void +libcrux_sha3_portable_incremental_shake128_squeeze_next_block( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out0) { + Eurydice_slice buf[1U] = {out0}; + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( + s, buf); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___168size_t( + s->st, out); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_first_three_blocks__uint64_t_1size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____0 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( + out, (size_t)168U); + Eurydice_slice o0[1U]; + memcpy(o0, uu____0.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o10[1U]; + memcpy(o10, uu____0.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_168size_t( + s, o0); + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____1 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( + o10, (size_t)168U); + Eurydice_slice o1[1U]; + memcpy(o1, uu____1.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o2[1U]; + memcpy(o2, uu____1.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( + s, o1); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( + s, o2); +} + +static inline void +libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out0) { + Eurydice_slice buf[1U] = {out0}; + libcrux_sha3_generic_keccak_squeeze_first_three_blocks__uint64_t_1size_t_168size_t( + s, buf); +} + +#define libcrux_sha3_Sha224 0 +#define libcrux_sha3_Sha256 1 +#define libcrux_sha3_Sha384 2 +#define libcrux_sha3_Sha512 3 + +typedef uint8_t libcrux_sha3_Algorithm; + +static inline size_t libcrux_sha3_digest_size(libcrux_sha3_Algorithm mode) { + size_t uu____0; + switch (mode) { + case libcrux_sha3_Sha224: { + uu____0 = (size_t)28U; + break; + } + case libcrux_sha3_Sha256: { + uu____0 = (size_t)32U; + break; + } + case libcrux_sha3_Sha384: { + uu____0 = (size_t)48U; + break; + } + case libcrux_sha3_Sha512: { + uu____0 = (size_t)64U; + break; + } + default: { + KRML_HOST_EPRINTF("KaRaMeL incomplete match at %s:%d\n", __FILE__, + __LINE__); + KRML_HOST_EXIT(253U); + } + } + return uu____0; +} + +static inline void libcrux_sha3_portable_keccak_load_block___144size_t( + uint64_t (*s)[5U], Eurydice_slice blocks[1U]) { + for (size_t i = (size_t)0U; i < (size_t)144U / (size_t)8U; i++) { + size_t i0 = i; + uint8_t ret[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_slice_subslice( + blocks[0U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + Eurydice_slice, uint8_t[8U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + dst, ret); + uint64_t uu____0 = core_num__u64_9__from_le_bytes(ret); + size_t uu____1 = i0 / (size_t)5U; + size_t uu____2 = i0 % (size_t)5U; + s[uu____1][uu____2] = s[uu____1][uu____2] ^ uu____0; + } +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block___144size_t( + uint64_t (*a)[5U], Eurydice_slice b[1U]) { + uint64_t(*uu____0)[5U] = a; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, b, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak_load_block___144size_t(uu____0, uu____1); +} + +static inline void +libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_144size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice blocks[1U]) { + uint64_t(*uu____0)[5U] = s->st; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block___144size_t( + uu____0, uu____1); + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); +} + +static inline void libcrux_sha3_portable_keccak_load_block_full___144size_t( + uint64_t (*s)[5U], uint8_t blocks[1U][200U]) { + uint64_t(*uu____0)[5U] = s; + Eurydice_slice buf[1U] = {Eurydice_array_to_slice((size_t)200U, blocks[0U], + uint8_t, Eurydice_slice)}; + libcrux_sha3_portable_keccak_load_block___144size_t(uu____0, buf); +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block_full___144size_t( + uint64_t (*a)[5U], uint8_t b[1U][200U]) { + uint64_t(*uu____0)[5U] = a; + uint8_t uu____1[1U][200U]; + memcpy(uu____1, b, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak_load_block_full___144size_t(uu____0, uu____1); +} + +static inline void +libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_144size_t_6uint8_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice last[1U]) { + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[1U][200U] = {{0U}}; + { + size_t i = (size_t)0U; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)200U, blocks[i], + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = last_len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); + blocks[i][last_len] = 6U; + blocks[i][(size_t)144U - (size_t)1U] = + (uint32_t)blocks[i][(size_t)144U - (size_t)1U] | 128U; + } + uint64_t(*uu____1)[5U] = s->st; + uint8_t uu____2[1U][200U]; + memcpy(uu____2, blocks, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block_full___144size_t( + uu____1, uu____2); + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); +} + +static inline void libcrux_sha3_portable_keccak_store_block___144size_t( + uint64_t (*s)[5U], Eurydice_slice out[1U]) { + for (size_t i = (size_t)0U; i < (size_t)144U / (size_t)8U; i++) { + size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_slice_subslice( + out[0U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret[8U]; + core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline void libcrux_sha3_portable_keccak_store_block_full___144size_t( + uint64_t (*s)[5U], uint8_t ret[1U][200U]) { + uint8_t out[200U] = {0U}; + uint64_t(*uu____0)[5U] = s; + Eurydice_slice buf[1U] = { + Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice)}; + libcrux_sha3_portable_keccak_store_block___144size_t(uu____0, buf); + uint8_t uu____1[200U]; + memcpy(uu____1, out, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[0U], uu____1, (size_t)200U * sizeof(uint8_t)); +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___144size_t( + uint64_t (*a)[5U], uint8_t ret[1U][200U]) { + uint8_t ret0[1U][200U]; + libcrux_sha3_portable_keccak_store_block_full___144size_t(a, ret0); + memcpy(ret, ret0, (size_t)1U * sizeof(uint8_t[200U])); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_144size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___144size_t( + s->st, b); + { + size_t i = (size_t)0U; + Eurydice_slice uu____0 = out[i]; + uint8_t *uu____1 = b[i]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + } +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___144size_t( + uint64_t (*a)[5U], Eurydice_slice b[1U]) { + libcrux_sha3_portable_keccak_store_block___144size_t(a, b); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_144size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___144size_t( + s->st, out); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_144size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___144size_t( + s->st, out); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_144size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, + Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___144size_t( + s.st, b); + { + size_t i = (size_t)0U; + Eurydice_slice uu____0 = out[i]; + uint8_t *uu____1 = b[i]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + } +} + +static inline void +libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_144size_t_6uint8_t( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s = + libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)144U; + i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, data, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___slice_n( + uu____1, i0 * (size_t)144U, (size_t)144U, ret); + libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_144size_t( + uu____0, ret); + } + size_t rem = + core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)144U; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; + Eurydice_slice uu____3[1U]; + memcpy(uu____3, data, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___slice_n( + uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, + ret); + libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_144size_t_6uint8_t( + uu____2, ret); + size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); + size_t blocks = outlen / (size_t)144U; + size_t last = outlen - outlen % (size_t)144U; + if (blocks == (size_t)0U) { + libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_144size_t( + &s, out); + } else { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____4 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( + out, (size_t)144U); + Eurydice_slice o0[1U]; + memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o1[1U]; + memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_144size_t( + &s, o0); + core_ops_range_Range__size_t iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range__size_t, core_ops_range_Range__size_t); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, core_option_Option__size_t) + .tag == core_option_None) { + break; + } else { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____5 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( + o1, (size_t)144U); + Eurydice_slice o[1U]; + memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice orest[1U]; + memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_144size_t( + &s, o); + memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); + } + } + if (last < outlen) { + libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_144size_t(s, + o1); + } + } +} + +static inline void libcrux_sha3_portable_keccakx1___144size_t_6uint8_t( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + Eurydice_slice uu____0[1U]; + memcpy(uu____0, data, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_144size_t_6uint8_t( + uu____0, out); +} + +static inline void libcrux_sha3_portable_sha224(Eurydice_slice digest, + Eurydice_slice data) { + Eurydice_slice buf0[1U] = {data}; + Eurydice_slice buf[1U] = {digest}; + libcrux_sha3_portable_keccakx1___144size_t_6uint8_t(buf0, buf); +} + +static inline void libcrux_sha3_portable_keccak_load_block___104size_t( + uint64_t (*s)[5U], Eurydice_slice blocks[1U]) { + for (size_t i = (size_t)0U; i < (size_t)104U / (size_t)8U; i++) { + size_t i0 = i; + uint8_t ret[8U]; + core_result_Result__uint8_t_8size_t__core_array_TryFromSliceError dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_slice_subslice( + blocks[0U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice), + Eurydice_slice, uint8_t[8U], void *); + core_result__core__result__Result_T__E___unwrap__uint8_t_8size_t__core_array_TryFromSliceError( + dst, ret); + uint64_t uu____0 = core_num__u64_9__from_le_bytes(ret); + size_t uu____1 = i0 / (size_t)5U; + size_t uu____2 = i0 % (size_t)5U; + s[uu____1][uu____2] = s[uu____1][uu____2] ^ uu____0; + } +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block___104size_t( + uint64_t (*a)[5U], Eurydice_slice b[1U]) { + uint64_t(*uu____0)[5U] = a; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, b, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak_load_block___104size_t(uu____0, uu____1); +} + +static inline void +libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_104size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice blocks[1U]) { + uint64_t(*uu____0)[5U] = s->st; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block___104size_t( + uu____0, uu____1); + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); +} + +static inline void libcrux_sha3_portable_keccak_load_block_full___104size_t( + uint64_t (*s)[5U], uint8_t blocks[1U][200U]) { + uint64_t(*uu____0)[5U] = s; + Eurydice_slice buf[1U] = {Eurydice_array_to_slice((size_t)200U, blocks[0U], + uint8_t, Eurydice_slice)}; + libcrux_sha3_portable_keccak_load_block___104size_t(uu____0, buf); +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block_full___104size_t( + uint64_t (*a)[5U], uint8_t b[1U][200U]) { + uint64_t(*uu____0)[5U] = a; + uint8_t uu____1[1U][200U]; + memcpy(uu____1, b, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak_load_block_full___104size_t(uu____0, uu____1); +} + +static inline void +libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_104size_t_6uint8_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice last[1U]) { + size_t last_len = core_slice___Slice_T___len(last[0U], uint8_t, size_t); + uint8_t blocks[1U][200U] = {{0U}}; + { + size_t i = (size_t)0U; + Eurydice_slice uu____0 = Eurydice_array_to_subslice( + (size_t)200U, blocks[i], + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)0U, + .end = last_len}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + core_slice___Slice_T___copy_from_slice(uu____0, last[i], uint8_t, void *); + blocks[i][last_len] = 6U; + blocks[i][(size_t)104U - (size_t)1U] = + (uint32_t)blocks[i][(size_t)104U - (size_t)1U] | 128U; + } + uint64_t(*uu____1)[5U] = s->st; + uint8_t uu____2[1U][200U]; + memcpy(uu____2, blocks, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block_full___104size_t( + uu____1, uu____2); + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); +} + +static inline void libcrux_sha3_portable_keccak_store_block___104size_t( + uint64_t (*s)[5U], Eurydice_slice out[1U]) { + for (size_t i = (size_t)0U; i < (size_t)104U / (size_t)8U; i++) { + size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_slice_subslice( + out[0U], + (CLITERAL(core_ops_range_Range__size_t){ + .start = (size_t)8U * i0, .end = (size_t)8U * i0 + (size_t)8U}), + uint8_t, core_ops_range_Range__size_t, Eurydice_slice); + uint8_t ret[8U]; + core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_slice((size_t)8U, ret, uint8_t, Eurydice_slice), + uint8_t, void *); + } +} + +static inline void libcrux_sha3_portable_keccak_store_block_full___104size_t( + uint64_t (*s)[5U], uint8_t ret[1U][200U]) { + uint8_t out[200U] = {0U}; + uint64_t(*uu____0)[5U] = s; + Eurydice_slice buf[1U] = { + Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice)}; + libcrux_sha3_portable_keccak_store_block___104size_t(uu____0, buf); + uint8_t uu____1[200U]; + memcpy(uu____1, out, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[0U], uu____1, (size_t)200U * sizeof(uint8_t)); +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___104size_t( + uint64_t (*a)[5U], uint8_t ret[1U][200U]) { + uint8_t ret0[1U][200U]; + libcrux_sha3_portable_keccak_store_block_full___104size_t(a, ret0); + memcpy(ret, ret0, (size_t)1U * sizeof(uint8_t[200U])); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_104size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___104size_t( + s->st, b); + { + size_t i = (size_t)0U; + Eurydice_slice uu____0 = out[i]; + uint8_t *uu____1 = b[i]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + } +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___104size_t( + uint64_t (*a)[5U], Eurydice_slice b[1U]) { + libcrux_sha3_portable_keccak_store_block___104size_t(a, b); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_104size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___104size_t( + s->st, out); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_104size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block___104size_t( + s->st, out); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_104size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, + Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___104size_t( + s.st, b); + { + size_t i = (size_t)0U; + Eurydice_slice uu____0 = out[i]; + uint8_t *uu____1 = b[i]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + } +} + +static inline void +libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_104size_t_6uint8_t( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s = + libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)104U; + i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, data, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___slice_n( + uu____1, i0 * (size_t)104U, (size_t)104U, ret); + libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_104size_t( + uu____0, ret); + } + size_t rem = + core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)104U; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; + Eurydice_slice uu____3[1U]; + memcpy(uu____3, data, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___slice_n( + uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, + ret); + libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_104size_t_6uint8_t( + uu____2, ret); + size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); + size_t blocks = outlen / (size_t)104U; + size_t last = outlen - outlen % (size_t)104U; + if (blocks == (size_t)0U) { + libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_104size_t( + &s, out); + } else { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____4 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( + out, (size_t)104U); + Eurydice_slice o0[1U]; + memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o1[1U]; + memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_104size_t( + &s, o0); + core_ops_range_Range__size_t iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range__size_t, core_ops_range_Range__size_t); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, core_option_Option__size_t) + .tag == core_option_None) { + break; + } else { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____5 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( + o1, (size_t)104U); + Eurydice_slice o[1U]; + memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice orest[1U]; + memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_104size_t( + &s, o); + memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); + } + } + if (last < outlen) { + libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_104size_t(s, + o1); + } + } +} + +static inline void libcrux_sha3_portable_keccakx1___104size_t_6uint8_t( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + Eurydice_slice uu____0[1U]; + memcpy(uu____0, data, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_104size_t_6uint8_t( + uu____0, out); +} + +static inline void libcrux_sha3_portable_sha384(Eurydice_slice digest, + Eurydice_slice data) { + Eurydice_slice buf0[1U] = {data}; + Eurydice_slice buf[1U] = {digest}; + libcrux_sha3_portable_keccakx1___104size_t_6uint8_t(buf0, buf); +} + +static inline void libcrux_sha3_sha224_ema(Eurydice_slice digest, + Eurydice_slice payload) { + libcrux_sha3_portable_sha224(digest, payload); +} + +static inline void libcrux_sha3_sha224(Eurydice_slice data, uint8_t ret[28U]) { + uint8_t out[28U] = {0U}; + libcrux_sha3_sha224_ema( + Eurydice_array_to_slice((size_t)28U, out, uint8_t, Eurydice_slice), data); + memcpy(ret, out, (size_t)28U * sizeof(uint8_t)); +} + +static inline void libcrux_sha3_sha256_ema(Eurydice_slice digest, + Eurydice_slice payload) { + libcrux_sha3_portable_sha256(digest, payload); +} + +static inline void libcrux_sha3_sha256(Eurydice_slice data, uint8_t ret[32U]) { + uint8_t out[32U] = {0U}; + libcrux_sha3_sha256_ema( + Eurydice_array_to_slice((size_t)32U, out, uint8_t, Eurydice_slice), data); + memcpy(ret, out, (size_t)32U * sizeof(uint8_t)); +} + +static inline void libcrux_sha3_sha384_ema(Eurydice_slice digest, + Eurydice_slice payload) { + libcrux_sha3_portable_sha384(digest, payload); +} + +static inline void libcrux_sha3_sha384(Eurydice_slice data, uint8_t ret[48U]) { + uint8_t out[48U] = {0U}; + libcrux_sha3_sha384_ema( + Eurydice_array_to_slice((size_t)48U, out, uint8_t, Eurydice_slice), data); + memcpy(ret, out, (size_t)48U * sizeof(uint8_t)); +} + +static inline void libcrux_sha3_sha512_ema(Eurydice_slice digest, + Eurydice_slice payload) { + libcrux_sha3_portable_sha512(digest, payload); +} + +static inline void libcrux_sha3_sha512(Eurydice_slice data, uint8_t ret[64U]) { + uint8_t out[64U] = {0U}; + libcrux_sha3_sha512_ema( + Eurydice_array_to_slice((size_t)64U, out, uint8_t, Eurydice_slice), data); + memcpy(ret, out, (size_t)64U * sizeof(uint8_t)); +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block___168size_t( + uint64_t (*a)[5U], Eurydice_slice b[1U]) { + uint64_t(*uu____0)[5U] = a; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, b, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak_load_block___168size_t(uu____0, uu____1); +} + +static inline void +libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice blocks[1U]) { + uint64_t(*uu____0)[5U] = s->st; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___load_block___168size_t( + uu____0, uu____1); + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(s); +} + +static inline void libcrux_sha3_portable_keccak_store_block_full___168size_t( + uint64_t (*s)[5U], uint8_t ret[1U][200U]) { + uint8_t out[200U] = {0U}; + uint64_t(*uu____0)[5U] = s; + Eurydice_slice buf[1U] = { + Eurydice_array_to_slice((size_t)200U, out, uint8_t, Eurydice_slice)}; + libcrux_sha3_portable_keccak_store_block___168size_t(uu____0, buf); + uint8_t uu____1[200U]; + memcpy(uu____1, out, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[0U], uu____1, (size_t)200U * sizeof(uint8_t)); +} + +static inline void +libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___168size_t( + uint64_t (*a)[5U], uint8_t ret[1U][200U]) { + uint8_t ret0[1U][200U]; + libcrux_sha3_portable_keccak_store_block_full___168size_t(a, ret0); + memcpy(ret, ret0, (size_t)1U * sizeof(uint8_t[200U])); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___168size_t( + s->st, b); + { + size_t i = (size_t)0U; + Eurydice_slice uu____0 = out[i]; + uint8_t *uu____1 = b[i]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + } +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s, + Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_keccakf1600__uint64_t_1size_t(&s); + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___store_block_full___168size_t( + s.st, b); + { + size_t i = (size_t)0U; + Eurydice_slice uu____0 = out[i]; + uint8_t *uu____1 = b[i]; + core_ops_range_Range__size_t lit; + lit.start = (size_t)0U; + lit.end = core_slice___Slice_T___len(out[i], uint8_t, size_t); + core_slice___Slice_T___copy_from_slice( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range__size_t, + Eurydice_slice), + uint8_t, void *); + } +} + +static inline void +libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_168size_t_31uint8_t( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t s = + libcrux_sha3_generic_keccak__libcrux_sha3__generic_keccak__KeccakState_T__N__TraitClause_0__1__new__uint64_t_1size_t(); + for (size_t i = (size_t)0U; + i < core_slice___Slice_T___len(data[0U], uint8_t, size_t) / (size_t)168U; + i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____0 = &s; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, data, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___slice_n( + uu____1, i0 * (size_t)168U, (size_t)168U, ret); + libcrux_sha3_generic_keccak_absorb_block__uint64_t_1size_t_168size_t( + uu____0, ret); + } + size_t rem = + core_slice___Slice_T___len(data[0U], uint8_t, size_t) % (size_t)168U; + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *uu____2 = &s; + Eurydice_slice uu____3[1U]; + memcpy(uu____3, data, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___slice_n( + uu____3, core_slice___Slice_T___len(data[0U], uint8_t, size_t) - rem, rem, + ret); + libcrux_sha3_generic_keccak_absorb_final__uint64_t_1size_t_168size_t_31uint8_t( + uu____2, ret); + size_t outlen = core_slice___Slice_T___len(out[0U], uint8_t, size_t); + size_t blocks = outlen / (size_t)168U; + size_t last = outlen - outlen % (size_t)168U; + if (blocks == (size_t)0U) { + libcrux_sha3_generic_keccak_squeeze_first_and_last__uint64_t_1size_t_168size_t( + &s, out); + } else { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____4 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( + out, (size_t)168U); + Eurydice_slice o0[1U]; + memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o1[1U]; + memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_168size_t( + &s, o0); + core_ops_range_Range__size_t iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter( + (CLITERAL(core_ops_range_Range__size_t){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range__size_t, core_ops_range_Range__size_t); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, core_option_Option__size_t) + .tag == core_option_None) { + break; + } else { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____5 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( + o1, (size_t)168U); + Eurydice_slice o[1U]; + memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice orest[1U]; + memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( + &s, o); + memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); + } + } + if (last < outlen) { + libcrux_sha3_generic_keccak_squeeze_last__uint64_t_1size_t_168size_t(s, + o1); + } + } +} + +static inline void libcrux_sha3_portable_keccakx1___168size_t_31uint8_t( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + Eurydice_slice uu____0[1U]; + memcpy(uu____0, data, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_keccak__uint64_t_1size_t_168size_t_31uint8_t( + uu____0, out); +} + +static inline void libcrux_sha3_portable_shake128(Eurydice_slice digest, + Eurydice_slice data) { + Eurydice_slice buf0[1U] = {data}; + Eurydice_slice buf[1U] = {digest}; + libcrux_sha3_portable_keccakx1___168size_t_31uint8_t(buf0, buf); +} + +static const size_t libcrux_sha3_generic_keccak__PI[24U] = { + (size_t)6U, (size_t)12U, (size_t)18U, (size_t)24U, (size_t)3U, + (size_t)9U, (size_t)10U, (size_t)16U, (size_t)22U, (size_t)1U, + (size_t)7U, (size_t)13U, (size_t)19U, (size_t)20U, (size_t)4U, + (size_t)5U, (size_t)11U, (size_t)17U, (size_t)23U, (size_t)2U, + (size_t)8U, (size_t)14U, (size_t)15U, (size_t)21U}; + +static const size_t libcrux_sha3_generic_keccak__ROTC[24U] = { + (size_t)1U, (size_t)62U, (size_t)28U, (size_t)27U, (size_t)36U, + (size_t)44U, (size_t)6U, (size_t)55U, (size_t)20U, (size_t)3U, + (size_t)10U, (size_t)43U, (size_t)25U, (size_t)39U, (size_t)41U, + (size_t)45U, (size_t)15U, (size_t)21U, (size_t)8U, (size_t)18U, + (size_t)2U, (size_t)61U, (size_t)56U, (size_t)14U}; + +static inline void libcrux_sha3_neon_sha224(Eurydice_slice digest, + Eurydice_slice data) { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +static inline void libcrux_sha3_neon_sha384(Eurydice_slice digest, + Eurydice_slice data) { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +static inline void +libcrux_sha3_generic_keccak_squeeze_first_five_blocks__uint64_t_1size_t_168size_t( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out[1U]) { + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____0 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( + out, (size_t)168U); + Eurydice_slice o0[1U]; + memcpy(o0, uu____0.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o10[1U]; + memcpy(o10, uu____0.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block__uint64_t_1size_t_168size_t( + s, o0); + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____1 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( + o10, (size_t)168U); + Eurydice_slice o1[1U]; + memcpy(o1, uu____1.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o20[1U]; + memcpy(o20, uu____1.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( + s, o1); + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____2 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( + o20, (size_t)168U); + Eurydice_slice o2[1U]; + memcpy(o2, uu____2.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o30[1U]; + memcpy(o30, uu____2.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( + s, o2); + K___Eurydice_slice_uint8_t_1size_t__Eurydice_slice_uint8_t_1size_t_ uu____3 = + libcrux_sha3_portable_keccak___libcrux_sha3__traits__internal__KeccakItem_1__usize__for_u64___split_at_mut_n( + o30, (size_t)168U); + Eurydice_slice o3[1U]; + memcpy(o3, uu____3.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o4[1U]; + memcpy(o4, uu____3.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( + s, o3); + libcrux_sha3_generic_keccak_squeeze_next_block__uint64_t_1size_t_168size_t( + s, o4); +} + +static inline void +libcrux_sha3_portable_incremental_shake128_squeeze_first_five_blocks( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *s, + Eurydice_slice out0) { + Eurydice_slice buf[1U] = {out0}; + libcrux_sha3_generic_keccak_squeeze_first_five_blocks__uint64_t_1size_t_168size_t( + s, buf); +} + +static inline libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t +libcrux_sha3_portable___core__clone__Clone_for_libcrux_sha3__portable__KeccakState1___clone( + libcrux_sha3_generic_keccak_KeccakState__uint64_t__1size_t *self) { + return self[0U]; +} + +static inline uint32_t +libcrux_sha3___core__convert__From_libcrux_sha3__Algorithm__for_u32__1__from( + libcrux_sha3_Algorithm v) { + uint32_t uu____0; + switch (v) { + case libcrux_sha3_Sha224: { + uu____0 = 1U; + break; + } + case libcrux_sha3_Sha256: { + uu____0 = 2U; + break; + } + case libcrux_sha3_Sha384: { + uu____0 = 3U; + break; + } + case libcrux_sha3_Sha512: { + uu____0 = 4U; + break; + } + default: { + KRML_HOST_EPRINTF("KaRaMeL incomplete match at %s:%d\n", __FILE__, + __LINE__); + KRML_HOST_EXIT(253U); + } + } + return uu____0; +} + +static inline libcrux_sha3_Algorithm +libcrux_sha3___core__convert__From_u32__for_libcrux_sha3__Algorithm___from( + uint32_t v) { + libcrux_sha3_Algorithm uu____0; + switch (v) { + case 1U: { + uu____0 = libcrux_sha3_Sha224; + break; + } + case 2U: { + uu____0 = libcrux_sha3_Sha256; + break; + } + case 3U: { + uu____0 = libcrux_sha3_Sha384; + break; + } + case 4U: { + uu____0 = libcrux_sha3_Sha512; + break; + } + default: { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); + } + } + return uu____0; +} + +typedef uint8_t libcrux_sha3_Sha3_512Digest[64U]; + +typedef uint8_t libcrux_sha3_Sha3_384Digest[48U]; + +typedef uint8_t libcrux_sha3_Sha3_256Digest[32U]; + +typedef uint8_t libcrux_sha3_Sha3_224Digest[28U]; + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_sha3_portable_H_DEFINED +#endif diff --git a/libcrux-ml-kem/cg/mach b/libcrux-ml-kem/cg/mach new file mode 100755 index 000000000..7fa343011 --- /dev/null +++ b/libcrux-ml-kem/cg/mach @@ -0,0 +1,75 @@ +#! /usr/bin/env python3 + +import os +import argparse +import platform +import subprocess +import sys + + +def shell(command, expect=0, cwd=None, env={}): + subprocess_stdout = subprocess.DEVNULL + + print("Env:", env) + print("Command: ", end="") + for i, word in enumerate(command): + if i == 4: + print("'{}' ".format(word), end="") + else: + print("{} ".format(word), end="") + + print("\nDirectory: {}".format(cwd)) + + os_env = os.environ + os_env.update(env) + + ret = subprocess.run(command, cwd=cwd, env=os_env) + if ret.returncode != expect: + raise Exception("Error {}. Expected {}.".format(ret, expect)) + + +class buildAction(argparse.Action): + def __call__(self, parser, args, values, option_string=None) -> None: + if platform.system() == "Windows": + # On Windows we use MSVC etc. by default. + # There's no multi config here. The type needs to be set when configuring. + cmake_args = [] + if args.release: + cmake_args.append("-DCMAKE_BUILD_TYPE=Release") + shell(["cmake", "-B", "build"] + cmake_args) + else: + # By default we use ninja with a multi config and set the build type + # during the build. + cmake_build_args = [] + if args.release: + cmake_build_args.append("--config Release") + shell(["cmake", "-B", "build", "-GNinja Multi-Config"]) + shell(["cmake", "--build", "build"] + cmake_build_args) + return None + + +def parse_arguments(): + parser = argparse.ArgumentParser(description="Libcrux C build helper.") + subparsers = parser.add_subparsers() + + build_parser = subparsers.add_parser("build", help="Build the C code.") + build_parser.add_argument("build", nargs="*", action=buildAction) + build_parser.add_argument( + "--release", action="store_true", help="Build in relase mode" + ) + + if len(sys.argv) == 1: + parser.print_help(sys.stderr) + sys.exit(1) + + return parser.parse_args() + + +def main(): + # Don't print unnecessary Python stack traces. + sys.tracebacklimit = 0 + parse_arguments() + + +if __name__ == "__main__": + main() diff --git a/libcrux-ml-kem/cg/tests/mlkem768.cc b/libcrux-ml-kem/cg/tests/mlkem768.cc new file mode 100644 index 000000000..925efdf08 --- /dev/null +++ b/libcrux-ml-kem/cg/tests/mlkem768.cc @@ -0,0 +1,515 @@ +/* + * Copyright 2023 Cryspen Sarl + * + * Licensed under the Apache License, Version 2.0 or MIT. + * - http://www.apache.org/licenses/LICENSE-2.0 + * - http://opensource.org/licenses/MIT + */ + +#include +#include +#include + +#include "libcrux_sha3_portable.h" +#include "libcrux_mlkem768_portable.h" + +using namespace std; + +typedef vector bytes; + +template +Eurydice_slice mk_slice(T *x, size_t len) +{ + Eurydice_slice s; + s.ptr = (void *)x; + s.len = len; + return s; +} + +// Not really random +void generate_random(uint8_t *output, uint32_t output_len) +{ + for (size_t i = 0; i < output_len; i++) + { + output[i] = 13; + } +} + +vector +from_hex(const string &hex) +{ + if (hex.length() % 2 == 1) + { + throw invalid_argument("Odd-length hex string"); + } + + int len = static_cast(hex.length()) / 2; + vector out(len); + for (int i = 0; i < len; i += 1) + { + string byte = hex.substr(2 * i, 2); + out[i] = static_cast(strtol(byte.c_str(), nullptr, 16)); + } + + return out; +} + +string +bytes_to_hex(const vector &data) +{ + stringstream hex(ios_base::out); + hex.flags(ios::hex); + for (const auto &byte : data) + { + hex << setw(2) << setfill('0') << int(byte); + } + return hex.str(); +} + +class KAT +{ +public: + bytes key_generation_seed; + bytes sha3_256_hash_of_public_key; + bytes sha3_256_hash_of_secret_key; + bytes encapsulation_seed; + bytes sha3_256_hash_of_ciphertext; + bytes shared_secret; +}; + +vector +read_kats(string path) +{ + ifstream kat_file(path); + nlohmann::json kats_raw; + kat_file >> kats_raw; + + vector kats; + + // Read test group + for (auto &kat_raw : kats_raw.items()) + { + auto kat_raw_value = kat_raw.value(); + + kats.push_back(KAT{ + .key_generation_seed = from_hex(kat_raw_value["key_generation_seed"]), + .sha3_256_hash_of_public_key = + from_hex(kat_raw_value["sha3_256_hash_of_public_key"]), + .sha3_256_hash_of_secret_key = + from_hex(kat_raw_value["sha3_256_hash_of_secret_key"]), + .encapsulation_seed = from_hex(kat_raw_value["encapsulation_seed"]), + .sha3_256_hash_of_ciphertext = + from_hex(kat_raw_value["sha3_256_hash_of_ciphertext"]), + .shared_secret = from_hex(kat_raw_value["shared_secret"]), + }); + } + + return kats; +} + +void modify_ciphertext(uint8_t *ciphertext, size_t ciphertext_size) +{ + uint8_t randomness[3]; + generate_random(randomness, 3); + + uint8_t random_byte = randomness[0]; + if (random_byte == 0) + { + random_byte += 1; + } + + uint16_t random_u16 = (randomness[2] << 8) | randomness[1]; + + uint16_t random_position = random_u16 % ciphertext_size; + + ciphertext[random_position] ^= random_byte; +} + +void modify_secret_key(uint8_t *secret_key, + size_t secret_key_size, + bool modify_implicit_rejection_value) +{ + uint8_t randomness[3]; + generate_random(randomness, 3); + + uint8_t random_byte = randomness[0]; + if (random_byte == 0) + { + random_byte += 1; + } + + uint16_t random_u16 = (randomness[2] << 8) | randomness[1]; + + uint16_t random_position = 0; + + if (modify_implicit_rejection_value == true) + { + random_position = (secret_key_size - 32) + (random_u16 % 32); + } + else + { + random_position = random_u16 % (secret_key_size - 32); + } + + secret_key[random_position] ^= random_byte; +} + +uint8_t * +compute_implicit_rejection_shared_secret(uint8_t *ciphertext, + size_t ciphertext_size, + uint8_t *secret_key, + size_t secret_key_size) +{ + uint8_t *hashInput = new uint8_t[32 + ciphertext_size]; + uint8_t *sharedSecret = new uint8_t[32]; + Eurydice_slice ss; + ss.ptr = (void *)sharedSecret; + ss.len = 32; + + std::copy(secret_key + (secret_key_size - 32), + secret_key + secret_key_size, + hashInput); + std::copy(ciphertext, ciphertext + ciphertext_size, hashInput + 32); + + libcrux_sha3_portable_shake256(ss, mk_slice(hashInput, 32 + ciphertext_size)); + + delete[] hashInput; + return sharedSecret; +} + +TEST(MlKem768TestPortable, ConsistencyTest) +{ + uint8_t randomness[64]; + for (int i = 0; i < 64; i++) + { + randomness[i] = 13; + } + auto key_pair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(randomness); + // cout << "key pair.pk: " << bytes_to_hex(bytes(key_pair.pk.value, key_pair.pk.value + 16U)) << endl; + // cout << "key pair.sk: " << bytes_to_hex(bytes(key_pair.sk.value, key_pair.sk.value + 16U)) << endl; + + auto ctxt = libcrux_ml_kem_mlkem768_portable_encapsulate(&key_pair.pk, randomness); + + // cout << "ctxt: " << bytes_to_hex(bytes(ctxt.fst.value, ctxt.fst.value + 16U)) << endl; + + uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; + libcrux_ml_kem_mlkem768_portable_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + + EXPECT_EQ(0, + memcmp(ctxt.snd, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); +} + +TEST(Kyber768TestPortable, ModifiedCiphertextTest) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + auto key_pair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(randomness); + + generate_random(randomness, 32); + auto ctxt = libcrux_ml_kem_mlkem768_portable_encapsulate(&key_pair.pk, randomness); + + uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; + modify_ciphertext(ctxt.fst.value, + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768); + libcrux_ml_kem_mlkem768_portable_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + + EXPECT_NE(0, + memcmp(ctxt.snd, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + + uint8_t *implicitRejectionSharedSecret = + compute_implicit_rejection_shared_secret( + ctxt.fst.value, + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768, + key_pair.sk.value, + LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768); + + EXPECT_EQ(0, + memcmp(implicitRejectionSharedSecret, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + delete[] implicitRejectionSharedSecret; +} + +TEST(Kyber768TestPortable, ModifiedSecretKeyTest) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + auto key_pair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(randomness); + + generate_random(randomness, 32); + auto ctxt = libcrux_ml_kem_mlkem768_portable_encapsulate(&key_pair.pk, randomness); + + uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; + modify_secret_key( + key_pair.sk.value, LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768, false); + libcrux_ml_kem_mlkem768_portable_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + + EXPECT_NE(0, + memcmp(ctxt.snd, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + + modify_secret_key( + ctxt.snd, LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768, true); + libcrux_ml_kem_mlkem768_portable_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + + uint8_t *implicitRejectionSharedSecret = + compute_implicit_rejection_shared_secret( + ctxt.fst.value, + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768, + key_pair.sk.value, + LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768); + EXPECT_EQ(0, + memcmp(implicitRejectionSharedSecret, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + delete[] implicitRejectionSharedSecret; +} + +TEST(MlKem768TestPortable, NISTKnownAnswerTest) +{ + // XXX: This should be done in a portable way. + auto kats = read_kats("tests/mlkem768_nistkats.json"); + + for (auto kat : kats) + { + auto key_pair = + libcrux_ml_kem_mlkem768_portable_generate_key_pair(kat.key_generation_seed.data()); + + uint8_t pk_hash[32]; + libcrux_sha3_sha256( + mk_slice(key_pair.pk.value, + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE_768), + pk_hash); + EXPECT_EQ(0, memcmp(pk_hash, kat.sha3_256_hash_of_public_key.data(), 32)); + + uint8_t sk_hash[32]; + libcrux_sha3_sha256( + mk_slice(key_pair.sk.value, LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768), sk_hash); + EXPECT_EQ(0, memcmp(sk_hash, kat.sha3_256_hash_of_secret_key.data(), 32)); + + auto ctxt = libcrux_ml_kem_mlkem768_portable_encapsulate( + &key_pair.pk, kat.encapsulation_seed.data()); + uint8_t ct_hash[32]; + libcrux_sha3_sha256( + mk_slice(ctxt.fst.value, + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768), + ct_hash); + EXPECT_EQ(0, memcmp(ct_hash, kat.sha3_256_hash_of_ciphertext.data(), 32)); + EXPECT_EQ(0, + memcmp(ctxt.snd, + kat.shared_secret.data(), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + + uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; + libcrux_ml_kem_mlkem768_portable_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + + EXPECT_EQ(0, + memcmp(ctxt.snd, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + } +} + +#ifdef LIBCRUX_X64 +#include "libcrux_mlkem768_avx2.h" + +TEST(MlKem768TestAvx2, ConsistencyTest) +{ + uint8_t randomness[64]; + for (int i = 0; i < 64; i++) + randomness[i] = 13; + auto key_pair = libcrux_ml_kem_mlkem768_avx2_generate_key_pair(randomness); + auto ctxt = libcrux_ml_kem_mlkem768_avx2_encapsulate(&key_pair.pk, randomness); + + uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; + libcrux_ml_kem_mlkem768_avx2_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + + EXPECT_EQ(0, + memcmp(ctxt.snd, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); +} + +TEST(Kyber768TestAvx2, ModifiedCiphertextTest) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + auto key_pair = libcrux_ml_kem_mlkem768_avx2_generate_key_pair(randomness); + + generate_random(randomness, 32); + auto ctxt = libcrux_ml_kem_mlkem768_avx2_encapsulate(&key_pair.pk, randomness); + + uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; + modify_ciphertext(ctxt.fst.value, + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768); + libcrux_ml_kem_mlkem768_avx2_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + + EXPECT_NE(0, + memcmp(ctxt.snd, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + + uint8_t *implicitRejectionSharedSecret = + compute_implicit_rejection_shared_secret( + ctxt.fst.value, + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768, + key_pair.sk.value, + LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768); + + EXPECT_EQ(0, + memcmp(implicitRejectionSharedSecret, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + delete[] implicitRejectionSharedSecret; +} + +TEST(Kyber768TestAvx2, ModifiedSecretKeyTest) +{ + uint8_t randomness[64]; + generate_random(randomness, 64); + auto key_pair = libcrux_ml_kem_mlkem768_avx2_generate_key_pair(randomness); + + generate_random(randomness, 32); + auto ctxt = libcrux_ml_kem_mlkem768_avx2_encapsulate(&key_pair.pk, randomness); + + uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; + modify_secret_key( + key_pair.sk.value, LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768, false); + libcrux_ml_kem_mlkem768_avx2_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + + EXPECT_NE(0, + memcmp(ctxt.snd, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + + modify_secret_key( + ctxt.snd, LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768, true); + libcrux_ml_kem_mlkem768_avx2_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + + uint8_t *implicitRejectionSharedSecret = + compute_implicit_rejection_shared_secret( + ctxt.fst.value, + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768, + key_pair.sk.value, + LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768); + EXPECT_EQ(0, + memcmp(implicitRejectionSharedSecret, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + delete[] implicitRejectionSharedSecret; +} + +TEST(MlKem768TestAvx2, NISTKnownAnswerTest) +{ + // XXX: This should be done in a portable way. + auto kats = read_kats("tests/mlkem768_nistkats.json"); + + for (auto kat : kats) + { + auto key_pair = libcrux_ml_kem_mlkem768_avx2_generate_key_pair(kat.key_generation_seed.data()); + + uint8_t pk_hash[32]; + libcrux_sha3_sha256( + mk_slice(key_pair.pk.value, + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE_768), + pk_hash); + EXPECT_EQ(0, memcmp(pk_hash, kat.sha3_256_hash_of_public_key.data(), 32)); + + uint8_t sk_hash[32]; + libcrux_sha3_sha256( + mk_slice(key_pair.sk.value, LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768), sk_hash); + EXPECT_EQ(0, memcmp(sk_hash, kat.sha3_256_hash_of_secret_key.data(), 32)); + + auto ctxt = libcrux_ml_kem_mlkem768_avx2_encapsulate( + &key_pair.pk, kat.encapsulation_seed.data()); + uint8_t ct_hash[32]; + libcrux_sha3_sha256( + mk_slice(ctxt.fst.value, + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768), + ct_hash); + EXPECT_EQ(0, memcmp(ct_hash, kat.sha3_256_hash_of_ciphertext.data(), 32)); + EXPECT_EQ(0, + memcmp(ctxt.snd, + kat.shared_secret.data(), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + + uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; + libcrux_ml_kem_mlkem768_avx2_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + + EXPECT_EQ(0, + memcmp(ctxt.snd, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + } +} +#endif // LIBCRUX_X64 + +#ifdef LIBCRUX_AARCH64 +#include "libcrux_mlkem768_neon.h" + +TEST(MlKem768TestNeon, ConsistencyTest) +{ + uint8_t randomness[64]; + for (int i = 0; i < 64; i++) + randomness[i] = 13; + auto key_pair = libcrux_ml_kem_mlkem768_neon_generate_key_pair(randomness); + auto ctxt = libcrux_ml_kem_mlkem768_neon_encapsulate(&key_pair.pk, randomness); + + uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; + libcrux_ml_kem_mlkem768_neon_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + + EXPECT_EQ(0, + memcmp(ctxt.snd, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); +} + +TEST(MlKem768TestNeon, NISTKnownAnswerTest) +{ + // XXX: This should be done in a portable way. + auto kats = read_kats("tests/mlkem768_nistkats.json"); + + for (auto kat : kats) + { + auto key_pair = libcrux_ml_kem_mlkem768_neon_generate_key_pair(kat.key_generation_seed.data()); + + uint8_t pk_hash[32]; + libcrux_sha3_sha256( + mk_slice(key_pair.pk.value, + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE_768), + pk_hash); + EXPECT_EQ(0, memcmp(pk_hash, kat.sha3_256_hash_of_public_key.data(), 32)); + + uint8_t sk_hash[32]; + libcrux_sha3_sha256( + mk_slice(key_pair.sk.value, LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768), sk_hash); + EXPECT_EQ(0, memcmp(sk_hash, kat.sha3_256_hash_of_secret_key.data(), 32)); + + auto ctxt = libcrux_ml_kem_mlkem768_neon_encapsulate( + &key_pair.pk, kat.encapsulation_seed.data()); + uint8_t ct_hash[32]; + libcrux_sha3_sha256( + mk_slice(ctxt.fst.value, + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768), + ct_hash); + EXPECT_EQ(0, memcmp(ct_hash, kat.sha3_256_hash_of_ciphertext.data(), 32)); + EXPECT_EQ(0, + memcmp(ctxt.snd, + kat.shared_secret.data(), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + + uint8_t sharedSecret2[LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE]; + libcrux_ml_kem_mlkem768_neon_decapsulate(&key_pair.sk, &ctxt.fst, sharedSecret2); + + EXPECT_EQ(0, + memcmp(ctxt.snd, + sharedSecret2, + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE)); + } +} +#endif // LIBCRUX_AARCH64 diff --git a/libcrux-ml-kem/cg/tests/mlkem768_nistkats.json b/libcrux-ml-kem/cg/tests/mlkem768_nistkats.json new file mode 100644 index 000000000..6a819f80d --- /dev/null +++ b/libcrux-ml-kem/cg/tests/mlkem768_nistkats.json @@ -0,0 +1,802 @@ +[ + { + "key_generation_seed": "7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2d8626ed79d451140800e03b59b956f8210e556067407d13dc90fa9e8b872bfb8f", + "sha3_256_hash_of_public_key": "d4ec143b50f01423b177895edee22bb739f647ecf85f50bc25ef7b5a725dee86", + "sha3_256_hash_of_secret_key": "245bc1d8cdd4893e4c471e8fccfa7019df0fd10f2d5375f36b4af5f4222aca6a", + "encapsulation_seed": "147c03f7a5bebba406c8fae1874d7f13c80efe79a3a9a874cc09fe76f6997615", + "sha3_256_hash_of_ciphertext": "bb62281b4aacc5a90a5ccdc5cd3dbe3867c502e8e6ec963ab329a9da0a20a75a", + "shared_secret": "729fa06ac93c5efdfbf1272a96cef167a393947ab7dc2d11ed7de8ac3c947fa8" + }, + { + "key_generation_seed": "d60b93492a1d8c1c7ba6fc0b733137f3406cee8110a93f170e7a78658af326d9003271531cf27285b8721ed5cb46853043b346a66cba6cf765f1b0eaa40bf672", + "sha3_256_hash_of_public_key": "2cedad700b675e98641bea57b936bd8befce2d5161e0ef4ef8406e70f1e2c27c", + "sha3_256_hash_of_secret_key": "0a84cc895da138b944accbef3ff1a0004b8a0d8af5d426d2b82ea4c0e585cc6a", + "encapsulation_seed": "cde797df8ce67231f6c5d15811843e01eb2ab84c7490931240822adbddd72046", + "sha3_256_hash_of_ciphertext": "c15158a536d89bf3bafaea44cd442827a82f6eb772849015f3fec68a29d589dc", + "shared_secret": "c00e4ede0a4fa212980e6736686bf73585a0adf8d38fec212c860a0d3d055d1c" + }, + { + "key_generation_seed": "4b622de1350119c45a9f2e2ef3dc5df50a759d138cdfbd64c81cc7cc2f513345e82fcc97ca60ccb27bf6938c975658aeb8b4d37cffbde25d97e561f36c219ade", + "sha3_256_hash_of_public_key": "3dbc65b722a8982d058e27d409f04f744551ecde9015b62607cf67bb8ececbb8", + "sha3_256_hash_of_secret_key": "0ffced333b5d13fff22b81e66d57b6e2a6dba0285fe2a82d5537df51a8d3eac3", + "encapsulation_seed": "f43f68fbd694f0a6d307297110ecd4739876489fdf07eb9b03364e2ed0ff96e9", + "sha3_256_hash_of_ciphertext": "aec80e6fe21e2616352b4c148f9fa0e30986541fb0969df7873b1336b23a8de0", + "shared_secret": "8f50401bc9b1f857fd870902d4065f6cec8cb825db3eb22573c6167442b6e19b" + }, + { + "key_generation_seed": "050d58f9f757edc1e8180e3808b806f5bbb3586db3470b069826d1bb9a4efc2cde950541fd53a8a47aaa8cdfe80d928262a5ef7f8129ec3ef92f78d7cc32ef60", + "sha3_256_hash_of_public_key": "94391b7a41175a41c15cd995ebc69c83b29e4bcea6c186611dc4a79578e37f4c", + "sha3_256_hash_of_secret_key": "e3904266e186b34a397014c95f6d314cd6e1c813348b02e977d0fd21d9bb681b", + "encapsulation_seed": "ea74fbc3c546500ed684bed6fe3c496d3b86d2d6dfaf223969b942e9a8c95e85", + "sha3_256_hash_of_ciphertext": "39fa8e1d0a5e4bb987618734ee4903771886030b2d8bea4b5a9b0cb672ebb279", + "shared_secret": "3221d7b046caccbded38e369625f69bac60c2d7efacad8f24170b10c5d222830" + }, + { + "key_generation_seed": "66b79b844e0c2adad694e0478661ac46fe6b6001f6a71ff8e2f034b1fd8833d3be2d3c64d38269a1ee8660b9a2beaeb9f5ac022e8f0a357feebfd13b06813854", + "sha3_256_hash_of_public_key": "c5dbd68b3a8c148b2e7ac049bb986e14dd1cebfa1cbf3edd6bae85a4d2dda082", + "sha3_256_hash_of_secret_key": "b3fa7958f4b7ccb68712ae948c3f08740c8b89a69e53ad4e9959234e6869d8fe", + "encapsulation_seed": "64efa87a12cb96f98b9b81a7e5128a959c74e5332aaab0444fca7b4a5e5e0216", + "sha3_256_hash_of_ciphertext": "ca9f95c38dc95f51b6b62ec709539f0d1e9fa64e49ce4ad10bbe62868f35cfc5", + "shared_secret": "1d746afc4160c75aaa6c6967f4eee941e09546a039027f05f0f8a483710ac334" + }, + { + "key_generation_seed": "7ec408f52c9aa723d0c41d9987682a5f4ce6c9da7cd0215af60bbaf5484ab353a08ccf451b049fd51d7a9ad77ae14a81569df8c9bd3a8f1ebea86fdcfb823082", + "sha3_256_hash_of_public_key": "62e0447f7b5ae8a806b741ca5c302230b555c3786c11f3eb43894a8f45e3f7b1", + "sha3_256_hash_of_secret_key": "1a3249c268754c86d2e02ba9d87c2b60b220bf2406b71037cfaf6b089477ffb4", + "encapsulation_seed": "8a95d71228acaa5f9ae6f9d9ca8ae55fde296463b41083a39e833e37c4c90f88", + "sha3_256_hash_of_ciphertext": "ec7bb1327a69aeaf626a76d344be1156eac160262128a64477a194805b926233", + "shared_secret": "722fccef7142c46f74eb57a10b13e420d6554e9d18507f660bd1be96d3cebbcc" + }, + { + "key_generation_seed": "c121915bfef6abdfc177dae2f5a24218f9abda2559afc6741b08e0e61ab433eb84ef52db5eaa6df8ec3a0bc5ffa730db0dde8c5f38f266d5c680a78d264a7b96", + "sha3_256_hash_of_public_key": "0c1d832af7b7282d8bd81a2237107ee60d81e28eb64d6a153ae0eaa1a25797c2", + "sha3_256_hash_of_secret_key": "fd6b5d3f120ca009871ca24552a6118917ea882f12f30dc8097f6614d9d36080", + "encapsulation_seed": "90d79d75d0bbb8921cf70d46bab497022a8e750efdc99e5f1bae653275441c7b", + "sha3_256_hash_of_ciphertext": "da36cb6137a777acb4afbc0932811f75ef1d6732031309ae7e2de1543aaf5c2c", + "shared_secret": "ee7c5fb6a63ace944e1eae1bd4b182263d918754c33753b904853551b2b46cb8" + }, + { + "key_generation_seed": "d86634ecf96cc2603761e284c0e36734cedec64e7ff486469e38539c71141c5a99daf37400cfe59841afc412ec97f2929dc84a6f3c36f378ee84ce3e46cd1209", + "sha3_256_hash_of_public_key": "2b757ac0425152bef72ed852ab1eb44f4359499407bb6a020ff843a31657c5fe", + "sha3_256_hash_of_secret_key": "27dbbc7918c31e9ab57808f439c4f4189cc318a62422457f4fed733be959c816", + "encapsulation_seed": "be8a32f97b9a8d596382c02fa2a0eeebc15c083e970ddaa4f2622b91d6718663", + "sha3_256_hash_of_ciphertext": "85efbfd0b096fa921711ea66b17bcf7c9a6240711b38a88830dbd9d716f07195", + "shared_secret": "77cfbdae47854e9e10765cf397eca9ab2bf2b7522817152b22e18b6e09795016" + }, + { + "key_generation_seed": "0610678ff4dc3128e1619f915dc192c220f8fad94da1943b90aaec401683a492da1804ddb5aa9b1c6a47a98f8505a49bae2affde5fe75e69e828e546a6771004", + "sha3_256_hash_of_public_key": "53b9d62e64f9069d9fb94ea2c0806459b201531f4fddd708d162981cc1fb3757", + "sha3_256_hash_of_secret_key": "f4b964b7ab3e09fdf3d91527da06a4d29ef28344709a41739ef56f18bd5b984b", + "encapsulation_seed": "da2cfaf69e25b2a89ff2557bbb6f69e01d8e2e7bb27a7a1ce7e40fead16f33b2", + "sha3_256_hash_of_ciphertext": "379a57a8f19110d5e0d747a2c184877d71f00fea95cd815b4c0e8782b12bec6f", + "shared_secret": "8be7a417efbdd3587c6f82ddd1d29956789d28c2413b8383590c5b80cc53e04a" + }, + { + "key_generation_seed": "d322d56d8ef067ba1f24c92492b9c56df3a6ef54a304adc1b69913766a1ce69756047447b810cc094d400ab204cf9ae71e3afa68b88586ecb6498c68ac0e51b9", + "sha3_256_hash_of_public_key": "9cfeca12dfe978bf0b7ad7271487cf61b2b8f7c60f389f33fc18439a95bcbb63", + "sha3_256_hash_of_secret_key": "a2e37a55c9b80fb423f40585180b011f32402d0320259285b6e278df6c20ba60", + "encapsulation_seed": "511c2ab40782322c06111e144e505328c4e5bfc890a5980a2bbc44aeda4c738b", + "sha3_256_hash_of_ciphertext": "44053f01ecb88811b9ee7a9ddd4234f94507c7cf64b6803b28c54bc605ec4e31", + "shared_secret": "79fcd201101e7e277c1b6cdc4475d63ea1dbc42ab94cf873bf0163c2aab0b5ff" + }, + { + "key_generation_seed": "2f1d8a3bebb34540324b9485fdf3d5be3b858f544abc3fc641b5728cafab03ba8d6c42e7270ee2b77b6045385f3d175984a0e260363166c73b0c70c971644363", + "sha3_256_hash_of_public_key": "9aa64a30bed5aa8300772066ef577f79bf4813e3315a15f2c28b2665e4dc7e2f", + "sha3_256_hash_of_secret_key": "837eb6ce037f235273d7686fd9d01bea14026e0a0f5f943884f18409cc4bc70a", + "encapsulation_seed": "dca92dbec9b260dd97e8886f876862d6effc3b91fcf3fbc986cf56ab93ae79a2", + "sha3_256_hash_of_ciphertext": "02798b5af1a76a2b478ee05c630e62618e5e2d7ee0c411a82ed2bf888706fe28", + "shared_secret": "6c4484b6d7b0a376f52abb1811c712368a9f34bd108ffe7ca31c36a6ec8140f3" + }, + { + "key_generation_seed": "31beda3462627f601cbc56f3ddf4424e1529c04737ef0ef2af6d7401f653b8a1812083bfa3b670e3eaf9b443702fb6db16ac1197656bbd61a8e25ed523b8d1e5", + "sha3_256_hash_of_public_key": "241e5c7b836862d7482d507973ae3fd8dae96eec4ecebcedb68fbda75e04b401", + "sha3_256_hash_of_secret_key": "95c79c2a867b3e8a4e4e545ff626cd49893b8e87eb188ed1516b159a24736c97", + "encapsulation_seed": "57c170e691d7a914a901b9a11c62b8b569b3806427557a9dbac9faa720ec3641", + "sha3_256_hash_of_ciphertext": "cf3b2e2dc822949eb13638299fc2d5102c7132aa6cd54dd7834b13f05a4dece2", + "shared_secret": "8554d6af350f13471cfd45c23882e43dc81d8a094f6299e2ad33ef4c01a32058" + }, + { + "key_generation_seed": "cbdff028766d558af4466ef14043a1a9cf765f7748c63cc09dceb59ab39a4e4d8e9a30597e4b52ffa87a54b83c91d12a5e9c2cd90fcac2c11b3a348240411a4c", + "sha3_256_hash_of_public_key": "6ad1d739f1598a16c608a240cd13dfaf8263d74866315e2898a3431cf19e4685", + "sha3_256_hash_of_secret_key": "1ef733faa4f2cb53cb5d8975aa6797b5f37fd918aeda02178a40584475cdf667", + "encapsulation_seed": "6b5a14e1473abf5a33d44975ca2088bd8fa6fddcb3f80e8fd5c45b9d90c24a5c", + "sha3_256_hash_of_ciphertext": "1706e6983032950b47cb6c8586178b42d515ce929c1434c1a8c9e36d8b4db7a3", + "shared_secret": "f9646f73de3d93d8e5dc5beeaa65a30d8f3a1f8d6392190ee66ff28693fbadfa" + }, + { + "key_generation_seed": "4c04310bea66305c6ca8ba6b8f61ca96257a67663afc11761f13fb5c7b324b6b8aec87a9a79204cee2986867a2906eb851b734b8b22b91d6749b1a5f07c44e3b", + "sha3_256_hash_of_public_key": "9510a2a0b4fcbd414fc61aff04a8df579660d14b13c40ec0470c45f639b65a58", + "sha3_256_hash_of_secret_key": "0bcfa8078582f60e218047d0016437601da8431f34ae6da12921f53958f32819", + "encapsulation_seed": "40e593754e6eddb7f9cf176ba2d5fd1087c90ad377556d0b0f686537b1a3165e", + "sha3_256_hash_of_ciphertext": "f9341d26e39b38a88ddef1708c96ee2068f569a59a4010745730d8290d637718", + "shared_secret": "1ee252e97b69445f7f109187645cd2879f55e10eb8361ab43b3492ff51f01815" + }, + { + "key_generation_seed": "38a0d5f41d7dc1896efd1b45b0485634cef149828751b96087a0a6dd81b4d58aa2acf359556df4a2abaeb9dcee945829beb71185b4d6bd18b76e5668f253383a", + "sha3_256_hash_of_public_key": "cfbe9649d9d1c384baad67b91b2f3e21f2fadd6bb582a0b9cb016051dd82c75a", + "sha3_256_hash_of_secret_key": "09b118f7c4d059baf27284d127d4e85d55b84e4c92bf3127eeb318d2f5765401", + "encapsulation_seed": "c152523abd8248bed40c3827bcf0f8e8127037a55c780695e2c28ea3e041a44c", + "sha3_256_hash_of_ciphertext": "94a8c287238191a107e74e31ec099086d83f198e6b0f3321da4d8f46ce01a0b2", + "shared_secret": "1e1ea5d6a18873c5c7fc8da79093f6d3db5b28fdd0aaa42726ad130c78e9bb88" + }, + { + "key_generation_seed": "97b5665676e59e3538ebadaa8cd50df1f9fda1502d9894c616a946078e56b621df05318b5f655efe36f1b678cf4b875108a18db2fa312261caf839f84bd956c5", + "sha3_256_hash_of_public_key": "a19c2c9c907b129d01cc44a95949121c39534cc98b6d105e60fe519a000cc2ae", + "sha3_256_hash_of_secret_key": "f1c00070780a7a2ac5b57ff3ff765ca75278bb661d1635cac92792f9454fe8ba", + "encapsulation_seed": "ad6466dd59f26b762fb02b19eedf5f79964da68bce0459b91c3a6ee5a7e01183", + "sha3_256_hash_of_ciphertext": "56e0b8ab3b302fae682938a45d9931e092d78877d1f8834bb43cd5c85582a205", + "shared_secret": "24619bb17c912fc992bd8272969cd5b6fd6b030122ee5af9365cac8b38e569fc" + }, + { + "key_generation_seed": "ef99224a03a85a46ef115474ec5b5d620da6795d6efcca4c9135d19958a9de62df7d92dda83e6b2ef4cce08c9134563063068a196d7b1a1a13623e48ae12528e", + "sha3_256_hash_of_public_key": "e4174b6e7542fbe80ab2bc06dfb802f691aff147ff90332d5ea739216c18d872", + "sha3_256_hash_of_secret_key": "f3f3a292f5cf01d6f7266461c9e8cd44bfc8f17e16035ab8d10af8177f389b86", + "encapsulation_seed": "1a4d5dff5847cfb48333e33bb00ca7301b144aa89dcd412ff5a3b1081d775b7f", + "sha3_256_hash_of_ciphertext": "5f878ca21c8c27ae9c41c43aaf1f3a2af62c73296e165c08b88c5b22592867be", + "shared_secret": "a990af801ddcf2009c82fe657fe3f068bae7e6bfc661e3e588354ba7d1b176e6" + }, + { + "key_generation_seed": "b12f6fd965ea9c5b947db80fc60c83d5e232dca82e7263027c19bd62e5a6ff550f6aa3e88f7fa8a96067f8cdaeceeac90c2d0b5e277e56e9c405ec9420c30252", + "sha3_256_hash_of_public_key": "2006a70fa33ff4a65b00553734c5bd8cca0a65eb3a115d96b8aa90f8fdc5f8f4", + "sha3_256_hash_of_secret_key": "7334d4a1755e1e639b3e9eadb5996cd910b55d1de5790469f229231d3bfb1528", + "encapsulation_seed": "34f44ec2092eeaf686f2ea170591a98527cbb03a4fa9477a7aef6b41a54feeb2", + "sha3_256_hash_of_ciphertext": "c2079637916c089b2afb9d6e9c6fa51308ab7720d5c2fca484c34ce614a14fc0", + "shared_secret": "11a2ceaa0c77f0602c4b2be3499e6df6b0339d9de90d04b2b12829f4758afaa5" + }, + { + "key_generation_seed": "9f52af92ca165fdc38788f2b59ba02e01c8281ff7c1e60504688043a5fe814b04f3029e1be4e1c0258c3a22ff5b50b2674cc094ba7018da2a61569845c17d26f", + "sha3_256_hash_of_public_key": "631e1de2556ae65d57e600c21e8e355a4ed586d667177ca0b7545cb5a23d669f", + "sha3_256_hash_of_secret_key": "3d4d2c680a1e6aa83861ad95043ded260e720ae80060320feffa309b4281ba3d", + "encapsulation_seed": "6250c81126572eec2da330271db36ee591f060fc7e53eeefe2e1c476c675fa33", + "sha3_256_hash_of_ciphertext": "2e9d6551050e32e204d7c062a4c18b8abdb91346e9f2c2708776827e0be4c514", + "shared_secret": "7571990ef1ef7e15cc920318fb75fd38c4ceb9abf7a4b1adc2175f99d1a0a275" + }, + { + "key_generation_seed": "851ea90fd3854cbf28fe39fb81f68e4b14345cf0d6eee7ec4ce772513df8410d1c0ec046899a777655233e4e1b5ca44e9afbdc67964bfd5d5e3dbb45e60d03cf", + "sha3_256_hash_of_public_key": "87f3829eff562789b3e19fafec92e4b5f95b45f3786f12d9c24915ca484a49ce", + "sha3_256_hash_of_secret_key": "9aa6c0546cf02085e2b3af65a7d7fd32d0f6d8080e1e7fbff6c39bcf3086ece4", + "encapsulation_seed": "35d470bcc5880872754810dfb3f2796da2fd7f397537146f6488c27804072b34", + "sha3_256_hash_of_ciphertext": "14da42e207477f4383faf4004e58675f0380e7d621421b3c36b877acf3a45d5a", + "shared_secret": "27ba4cb50ae44cd938585e0a4905d76053dd851e5b6af4fd787446079aa5a4ab" + }, + { + "key_generation_seed": "d304c9389cc973477f169788abcb9d511f843219d246a9b587822f422a70c2386590a2e5c7ed86cf2c5c2a898662bc9a81418720bbb632ef9cf0b845ed052d73", + "sha3_256_hash_of_public_key": "699fb2f061a75f111f4a7a60195d9045dc01716b6502cc107cbcedf122e8f619", + "sha3_256_hash_of_secret_key": "421f16805b1ceffcd64128b1296521ef812d3a8f4c5e3875a049f8de456b021a", + "encapsulation_seed": "8d667921c5db401a86fe1c35dfcf164a6bb2ab7400fd6a0b67eafd4a0ed11940", + "sha3_256_hash_of_ciphertext": "b2485ef56c39d468193e387e72794e0ddc9b5404c1a6d90c3b94a5f3e13ba7b4", + "shared_secret": "d17b2738213a98f29ee46747c93308ee7000fa404b9a0c1acf3f89654ca2446e" + }, + { + "key_generation_seed": "89a6e3be304a3518fb82b18ca730f0b359cd6ba90664a493fb4f8edaf965b9c3b6591121e25d64010c25a18676033e1d7278ac5f2d0b43a31f3a4156ae710465", + "sha3_256_hash_of_public_key": "d3413880d082f26986fcf452a84a8da934ed06198b290ada1789e74d9081a9e7", + "sha3_256_hash_of_secret_key": "7b546a42ffe6b65cd9c5b8857c2518f4f8e0bf835c894a68d1743691fc9aad9d", + "encapsulation_seed": "ec750b3939385a3f8df868119dc76f77ca845567ef068de6ada5478a56bc78b6", + "sha3_256_hash_of_ciphertext": "8290f3c4bec7c3b93f3d26e0be3b3fbfdd9c3f5806188fcf0fa1339133f29c7d", + "shared_secret": "954af53b4add522514b34cd2ab96669a76ca13f82aa2fd70826bc8ee790ccefb" + }, + { + "key_generation_seed": "d569b935ce015c85f792f8f7fb0d83c4f53b492959361dd4f75fb764d656450176eae84d11c4528382828f7a689a0d5cff87b8ca0bba97feacb39b935a8788cb", + "sha3_256_hash_of_public_key": "e6eec2929feac2a86c9dacfa6214e2e353fda2d547c3829f5678025ff8418a1a", + "sha3_256_hash_of_secret_key": "5fac243c82807d7357a61023226a7c270525d96932162ca5c09fc8f7b9ec6cb3", + "encapsulation_seed": "74f1d52af09b12c36eb062ea7528550cb4c18a3ce8e4f4ea9fac43ae383bc925", + "sha3_256_hash_of_ciphertext": "f1b10c800a42ae606c72eaad76accf059cccc02299fbd78a5d091f183f6c3f0e", + "shared_secret": "d0bbc576fb1aa43b6e76db0e87bc4ee3fa057c31642b37f3339217a1b041b521" + }, + { + "key_generation_seed": "5cbb141c2763425c274f7404fe530d9116e08c33f9f200a20b011cf563a28990fc9ebbe336dc464489861db8253606971bd0a9008a433ed17752d04023781552", + "sha3_256_hash_of_public_key": "c74f3b7fa6e2ef8ce99508c89cf3c71d666ab065a262581a5fb01b2c9b9444fa", + "sha3_256_hash_of_secret_key": "5c6998a20960109a4c9808f8f8575697b2b8d18c44c7e9dff97585ae43e6004c", + "encapsulation_seed": "4b3a70d85f640d1a2a852fb6fe96704af56a7415a8ee4282e9207bc3a2dc116a", + "sha3_256_hash_of_ciphertext": "e9ef0852ee47744b8c3e12cd728d9017465014eef51edf83a4502cb5218cee20", + "shared_secret": "91fbc37d4749ec6175c12f0d8eb6b6a8621e693c79f85f5cd2f557cafec5e7e9" + }, + { + "key_generation_seed": "293abb6d1c207927945417cf84883ef010823e11b487ed55239e466e83696d0cff8563038aad865a817cab9ce98846ba75be9363718ecf5fea538aea90b2a558", + "sha3_256_hash_of_public_key": "7378ef967195c977d43a50d03205044006715a6a8a8263d717f40170b49e6bd0", + "sha3_256_hash_of_secret_key": "30bd5f16c3f242248a4c4cddc43508bf54535958657bda4dcf105216ddf47eb0", + "encapsulation_seed": "26e38ac804fb5b4d59ddf747715e7e6041d875f99c7b638024b4af82d622da60", + "sha3_256_hash_of_ciphertext": "37843616c8a4f7ea9480740b6624f41650da2bb1664cf228d85d6d71a0624528", + "shared_secret": "d586b441b8eaf7d053cc96b6835f093426677a7c3acc51aaa3ddbb66dd14a623" + }, + { + "key_generation_seed": "74d87c7556f2671f2d666854a4d6e073e69f35421e6e1a428cccea49c37f972ce1fb7456ac0aa1b97068f452cba64ebdc138bcf5d36b0a0fada2a3b374141eb9", + "sha3_256_hash_of_public_key": "16fe956be4601573d72306a251f69bc2181253e2417e178341fd6553303ac189", + "sha3_256_hash_of_secret_key": "873c94f8bee9fe37265d5dc0c5d3bc1c706057c7efb3cd2cd5ca9ba45498d0d1", + "encapsulation_seed": "a319d2b8f114f1acd866478bcdeba6fd164dc4e37b0adfa8d8034afb3e197376", + "sha3_256_hash_of_ciphertext": "cc677a81c73ea5139eed8d85782978d06192715933bc5aef560e737f6d57d0a7", + "shared_secret": "409bfd9102bd4632c6b5d3610eb349fe3e3bc51e73acc78a8e994a070e20e10c" + }, + { + "key_generation_seed": "013bab0212d04ecd54b478daf72748003a25e2cb060ba6cc50bf95c292b8206b9da0c5da5f195b80fbb99c2e8b06926074f3f604b3f6195b5a5b9737876bba72", + "sha3_256_hash_of_public_key": "633bee89571e8fc16151491ea71234ab83289426559f90c67903a36e4afaa6f4", + "sha3_256_hash_of_secret_key": "3c3cff5f49a802cec693efbfc264f6a385210b1eed20f7bc5b07b51839961d14", + "encapsulation_seed": "ff646071b2509e6b75790917e08e4f0b0d9f0116ec6291c0b59eaa4b583ad830", + "sha3_256_hash_of_ciphertext": "6d94a31cff4761e3993308cb3e812a4a7f04f64d02ed3b46b418c2fc16189dfa", + "shared_secret": "5dd151a8015c0b16d79822832ff4cc0da7fd38eb73b7da59bc519d4d2374b808" + }, + { + "key_generation_seed": "ccb073c4b90be0ad746e26fb093b60c70110bd1dcbcddb566a8cffb7b3caf80e71600a8982c350df524cde514431ded7aec23576530894bcbf0ec0bfef0bb64f", + "sha3_256_hash_of_public_key": "3217d034b472a846cd317681c0f36feea187bd40e546dc4ad69c2e67fd9d8303", + "sha3_256_hash_of_secret_key": "1503bc141825d523c9505d34f50dc0a01d7bc91cdaee6b99f4a85a24ce800496", + "encapsulation_seed": "0584270ec26f3b9818e4af074d17b2d51037cc8dfdcbe3b140fa4fed5deebc54", + "sha3_256_hash_of_ciphertext": "a63613ccfd2ecf8aa3adf0103ddd9eeedbde3282443bcf02513b4ab87360cabb", + "shared_secret": "1c729b8e580e124e715f19ea6f2409fc6de741afa3d9919b2b8bf3e54c053b51" + }, + { + "key_generation_seed": "2e889f44e28901e9ac7ca6b2fffcb124c8979401b17064d7e1d51a7e3c3adbfa0e145e44aae52cfc609e6f47fd7a6f6af877190ff52256d0ac5b05b89c3f449f", + "sha3_256_hash_of_public_key": "d1756ecfaeb695001ac490f36c4638151bee98d367fb7adf0e06a470844068af", + "sha3_256_hash_of_secret_key": "a21acea0fd4354eb0c78d47caaf93c9f2434f1cf2d6b2194871ccd98f9522ced", + "encapsulation_seed": "51e05c7b4ca3079781e8293f4eccebeeb2f8c8b4c59468eddb62a21bcb4ab8a3", + "sha3_256_hash_of_ciphertext": "3b322134b37fe8f5d7268fb74d1634ab8b35d456a973f7b0b427fb40a93b6db2", + "shared_secret": "b95ac8b73c703ab1154152b3ac73f054596ed23d3be328fbe20f936ea95fa926" + }, + { + "key_generation_seed": "174aaa36410566dc15a5e62874218d7abdde0b2c0f30d877bb80b1abd5f5a0a450a7a2354f7e5cefa6f4a4e9a1c411eb9364506e9e1204a8acb3cb77fbd2c4ed", + "sha3_256_hash_of_public_key": "1b1b0a8682caf72df2e0a48513a7358edbc77a615d6be6fe2a7145be66b7c509", + "sha3_256_hash_of_secret_key": "3e214f25fbf4d1bb670a87367399e1b2a9da3491cac5a22a2c18dcc44f3f1bae", + "encapsulation_seed": "9eca0fe36c80fc5eba171c3ae66a5b1c923faa50b4521bb055e7bf51005c93df", + "sha3_256_hash_of_ciphertext": "a2cd589c24c4c75bc0a3864dc84a85a7f0f3ac11c8578757f8e94054a7c186aa", + "shared_secret": "8c3851393e5c5997cc95f06da96300f6dd85c041343c98db2e742aaa5f78b298" + }, + { + "key_generation_seed": "351fe4313e2da7fac83d509f3103caf7b4c64a4d458fefdf636785ac361a1390f072d9b5a99f9c7a0a011e4dc10f6b600d611f40bba75071e7bee61d23fd5eda", + "sha3_256_hash_of_public_key": "2c54df6e9020e1e44b11b471dea97a382a2fe8d1042565bcd51ef21cc0884d68", + "sha3_256_hash_of_secret_key": "c6bc9c9e797a02684d3ad8de47919b8d8fdbee09258d084c7a9dc963c80401ac", + "encapsulation_seed": "0c5719261caab51ae66b8c32e21c34e6d86ee4aa127d1b0195663c066497b2e9", + "sha3_256_hash_of_ciphertext": "0cd687f1c3e0d67c46cebf93c1217ddc972ad8662dd05830db350e1292542c1c", + "shared_secret": "4b681fff6a755e1dda908d070f0d9ac610d85c73079c1022fc67d255e36f1f71" + }, + { + "key_generation_seed": "9bc5315580207c6c16dcf3a30c48daf278de12e8c27df6733e62f799068ad23d5a4d0a8a41c4f666854e9b13673071ceb2fd61def9a850c211e7c50071b1ddad", + "sha3_256_hash_of_public_key": "bdcaf7b417da8b8933279b33068f6fda313826c2eec500b224cbe046abeb37a7", + "sha3_256_hash_of_secret_key": "c96e176b19f4135add434d0dd219024587d49fdb649bf470e84d9518bbfa2879", + "encapsulation_seed": "0e59f6f9047c784c1f00b24454aa4f1bd32c92ae7e626549972f86fab90e7e89", + "sha3_256_hash_of_ciphertext": "b38711e358893a864b475f35328b2450fffd5087d631844f7ab0995de2b8310d", + "shared_secret": "bbaa67f1dad879f2fb33bd4ead45aec354bc8f05c7cbea1e433509faac022edf" + }, + { + "key_generation_seed": "d8b907b34d152ff8603b73051f772daa71eb902c47b7e2f070508269d757e02e36b817736cbc5f7b1dd6eef5fe6332fb1a598f3871e5470d440fd2ea631da28a", + "sha3_256_hash_of_public_key": "61e27e954728e2e2e230c94ff009417d7372938e2c29c38af22184eed530fa1f", + "sha3_256_hash_of_secret_key": "8baa58b1d3fab8ec5cee8841c9012506cad40bf58a677adac88f1a6400506d40", + "encapsulation_seed": "a3963ade17d69debbc358dda82c7bebe2c39d25b36813058e7a161542e3f8c2b", + "sha3_256_hash_of_ciphertext": "7d47a21d95483a5845a4fddbb07b3435c29a56b5cf26f5d0abfa21bc39a2f2e6", + "shared_secret": "2c7b983d66978be80250c12bf723eb0300a744e80ad075c903fce95fae9e41a2" + }, + { + "key_generation_seed": "684a29e4e5480a5f2533e1526b5fac8cdf5927f3d85087c71f928c59690eb56575d12195ec32a8686d0600e45d4a7f54219b0d7a3826d193a51b9156ecf2edd6", + "sha3_256_hash_of_public_key": "672e53b28d579974d268132187e7bd72238639c6f2ca154d50d98c74096ec330", + "sha3_256_hash_of_secret_key": "4c72f0a7ef5c3274c49365cca5e6770bc709ef12bdbd4fd7c2eb5faa296cdfe8", + "encapsulation_seed": "97beafabf2c8575586487c7a80e8af5fc50f94b6051c1bc66a5ae9f66be3cea7", + "sha3_256_hash_of_ciphertext": "167b4e8b7517cad82ae0f49795918c4d33c79137a9c3e16000c4c55b30b1d382", + "shared_secret": "bbc58d06cc14f9e96a10acb1789d93b93933f1429cc53a1735b3cd995f086ce7" + }, + { + "key_generation_seed": "d76b3573f596eb286ab5231feec7499686b13021be36cb126c7ebeb9d7030daf248c0a21ea0bb6d6f56f12300e8584d8e9a34e0e6f52227281151ae4c305fb8f", + "sha3_256_hash_of_public_key": "b86d5b13bb8b72a9fb81245ab712f0d10f0e2e09b222143c420e3f2c3acea27b", + "sha3_256_hash_of_secret_key": "c25f2e16a0e6fbf0729e5ee89fbbdd71f00ff9a1abbb00cb47f26e9989eaf678", + "encapsulation_seed": "75461decd34c50d6a094b4a64fb75e5e9479f8f9250d82bb7d729dedeb2d4b65", + "sha3_256_hash_of_ciphertext": "8919940aeb732930c496fa9832b0c09382663accda45be1ee22930c545eb3a37", + "shared_secret": "e045e0391e15a66d6208467078f2ba5e429cc586c410ca6c5f3c032c21761955" + }, + { + "key_generation_seed": "b87439fde81c9e39eebe7cf741c685785532c1dd23e8ef868b9ce7a541010f3d1646460817a0fce5836bdfe124a7448e7adf7b8ecc2652ac6d280e986682df71", + "sha3_256_hash_of_public_key": "85441cbd71c18717e9de7359b920a9a3bb7f32e619806f4e4718c585085be624", + "sha3_256_hash_of_secret_key": "93b65d2df33d3e3ab0d53c1d0a21f3752e2c5962f7d960b888b2a8c495b1b133", + "encapsulation_seed": "2607dcf4fd6ca1c614c21b5e37c24981c32b91c8c3e6955777da8a3f5d9c9335", + "sha3_256_hash_of_ciphertext": "422509b01b8fff9468e867a2b5ebe5d3e27314de5c058b2c79a61ccf464f4df7", + "shared_secret": "0b8584b75838e084839d58c89cb1749e82ec06a0e85464c7546dd96870547d29" + }, + { + "key_generation_seed": "056661b38038da4fdd7426f32a81576c73ed84843b305168a374f934e27a4e1b79238a80dcfd7c992d84b2dffa67493e669243d4fa38c46b090bdf86bc548411", + "sha3_256_hash_of_public_key": "065fb6156acaac591f1bf3ce71c4a046be8c6c55eb9a84d29569bd2b144c73e2", + "sha3_256_hash_of_secret_key": "0121afcc6aeb8be9f1c5b06d5b65cc1c03e9366ed7b85fc511d853c5eee230cc", + "encapsulation_seed": "38c89bbe7145c29e9a831c11431eb9929cb24fb4992db20737e4687d397fd732", + "sha3_256_hash_of_ciphertext": "f1d3b745d86f860e508ad8b6d5c8a72ef833c280ec11e99516f4ead3c42509be", + "shared_secret": "3547a15b5748990a5436bdc4db283738eb7d64bdb6ff566c96f7edec607ccc9b" + }, + { + "key_generation_seed": "a1b52d871612a1c611ae0944f9e71858f35d3bd14f20e96a931720668bdf0a6b1f135cf64b6403e103afae34da038613e2853bbfc36baafa3c6a95347193f37c", + "sha3_256_hash_of_public_key": "ced77d358342759291c2bd225b0bd82d659d28a24bbc5eda8f47975b780cd129", + "sha3_256_hash_of_secret_key": "16e06287bd8d71c78f1657bbd6d5d12c22f6bad7658e68dd849d7751da950860", + "encapsulation_seed": "b2c35e33c72d90182791f0e12a0324f5b216efcab2c8da1bee025dfbe13f4152", + "sha3_256_hash_of_ciphertext": "fdfd351fbb15c92843b44489fee162d40ce2eea4856059731490afda1268b985", + "shared_secret": "852ba9be42763c5a74a75778eb839a3738a8ceed1520b0588f9dccdd91907228" + }, + { + "key_generation_seed": "952b49c803d6d6fba69f4375adce8594847a00bcae2179da49af2aed0423250262d7033947ae42ca53522a65fbafe18d3bc3e0cb66164e9a094fe4b44d8977ed", + "sha3_256_hash_of_public_key": "2fdb7c7e39ce1625c20a13a1c91aa5909d8b03b064d00877dce2415020370c72", + "sha3_256_hash_of_secret_key": "ffdb52b23a9ca4b71ec882031ebcb33a0ecc6731c13c817b24f3a06e48273778", + "encapsulation_seed": "afb7d6dc2b7eb6d84acc080c1be63c98afe7b07786b5801f716444a3e8e64800", + "sha3_256_hash_of_ciphertext": "215d83f872221c5fd4ee4da557e17299dc102c52dba1fc4bc3f8c16805da7f1e", + "shared_secret": "618a8496b8850609c09dd1d18798ee2bfff3ed7ef6f8b8034fffcec98f291d69" + }, + { + "key_generation_seed": "3c815e57e9233e975fa1630208aab206b71ae0db37a7a8789ac683d9f9b2d29801c8e376fdb140ee343106c093af7cb149b316ba79446ceb4e5e0cedb9b164f9", + "sha3_256_hash_of_public_key": "86bb11e7d9c1368fbba34ce3a2f169c2464ef5fbc11f73843c456467b6cdbd4e", + "sha3_256_hash_of_secret_key": "5d46659798d268f1314ad1e7c1735c480301f5877773403966e928bc3fd33d1b", + "encapsulation_seed": "28f5e9dbda122b2cf8f3754fe9e0c73a84ad4b0c093522e0b62cf815d60bbc3c", + "sha3_256_hash_of_ciphertext": "5ff5d6bdb110bac57e58a4e288d056a1384f9823606a42daef2ae82e0b7574b2", + "shared_secret": "cbb8b7a05f48b47d163cf8c2fad32bc586f47f2c2e0911da349f29b1e3286c22" + }, + { + "key_generation_seed": "588760826dcfbd36d9abe6ae44a669bb3ebba6a218eab69e30f18a3bd536576e0e860576285483bb5fd36e2f944d32c4317bebc1e441470c1372046a790d79d4", + "sha3_256_hash_of_public_key": "29253478090cb4d580bc2a912645bc685061e5d4437b3811eda69c865ea9923c", + "sha3_256_hash_of_secret_key": "aadce411f3708e9727e4a7e4e198781e1ef5e8f4c4c14add1e25f5758649e265", + "encapsulation_seed": "b0d713cbef0bb1df70cbb425d1e9373e9f7790fdc7980cc96a240dfc53f1e8e2", + "sha3_256_hash_of_ciphertext": "675039d66fcb631a050a8b24415b50f331350bd6697f9c977eef15c15d4cacca", + "shared_secret": "1eef87404f318351413d52ba8a07cfa5e72f235d6f91afd7fb8ad3e683ce0a55" + }, + { + "key_generation_seed": "47550e9edacb6ddce3d9ab81f6b61080dd4f2693854acb05e0ccc7a4fb6390fbf89d7d99d5c3e0d10d6ef9af054d842375f695abb28e3b8eb495100f04306e92", + "sha3_256_hash_of_public_key": "286de7dc142efe935e84b0aeebbd32d050fd9d8b008a94e59454b19ea401611d", + "sha3_256_hash_of_secret_key": "a6b53edf9efd7fa67a478456a5b6a379876c248f623ea45f4b541a8db00c524e", + "encapsulation_seed": "32bdcdb7059fe27f6409901980c080308951ffd90deffa8317b4d213a5f04495", + "sha3_256_hash_of_ciphertext": "f03d44bd9bdf3bfd486919fec2177b8b685a9981de4cbc2a9e98b7e9b0a528fd", + "shared_secret": "ca2c0bba56645e4fce4b7e38a7bb4b839e754bf2834a302a2614377eddd6ae60" + }, + { + "key_generation_seed": "610afb64be8cc1df288cfb016ee2f44c6c07113de7f6fee071fe0c3fe31c6215cd292e4c5f9e1a55e0489bceffb204d672a6215f4f3980a646d9f880817c52dd", + "sha3_256_hash_of_public_key": "029a2e12c3e6aa668afb5be8a82576813fac7b8e61c5a88aff94ecc2770c585e", + "sha3_256_hash_of_secret_key": "413ae41ee83e17b74ac654c2aca57abe8f8ed0409acf7cc8b301e3d6bb049cfe", + "encapsulation_seed": "4ed7c92d83bd03b2a25b567f17ae55542e2f6a4308ec0f3fe69f8ba5ae24331b", + "sha3_256_hash_of_ciphertext": "e8992f7b7b619c03cb9f0c991e3a9c20f91beb707c177ad4e02a5808d10d8769", + "shared_secret": "9155619e28de6cc0670ce70e0ad270f0e885e5f5f8d6d38426938ae1036d6ffa" + }, + { + "key_generation_seed": "e1953800acaa85ac02a906c72cb8e8d704e8d27820345f88f71e89c1f549afcc8c64c049c6dfc0f1476cffd520b055756162f7ec94243de6b14ac0b9e5fb366c", + "sha3_256_hash_of_public_key": "e3ec3671cc7675a321af8584a0961101c04a432772431e77f5740ba3b2ef488d", + "sha3_256_hash_of_secret_key": "93bf696bf0671c3845c4b246f29701a0978eec5b49de81589009e235903061e0", + "encapsulation_seed": "060ea5d2ed1dd88144a9885e79278590821c22917b55a48920f96b53ebe0e689", + "sha3_256_hash_of_ciphertext": "6634bd840d2dbb01463cfe5b4e3e54d1eabc081cfbdc14d0bc118911ed8d3cce", + "shared_secret": "d1f24383d5b8d0c3c0a6a5f8f7d38ccce13ec179a84b0b09bcda4c9988f3eb4e" + }, + { + "key_generation_seed": "c719f9b2d16399b7326ce4eca30dabefe8fdaab18e9f6df888b0a134ef355570e40771856eb77e4633504899fcb86c6a3d433d0b8d60e26f07bd61f1d4ed69bd", + "sha3_256_hash_of_public_key": "79836213a513bd4cfd42ed281304e3ee4560e4e0c60fa53781f83d5bd2bbea52", + "sha3_256_hash_of_secret_key": "65deb55fea451375ef335e7faac73917d32220fc70c95f371fdb16e712beeb26", + "encapsulation_seed": "10ef9426f8c4a13b52325c5bb4ead4596ecf2c6b5bd2d37d8350e90d4164fdd9", + "sha3_256_hash_of_ciphertext": "ba79883ad64a6f2b256004233d87809a8c390327a23c739334f773507e003aa7", + "shared_secret": "d2dab0b39b7f62de3ca9826f9dd15a4201191a0e0c690d3e52b305a9d3af2d0f" + }, + { + "key_generation_seed": "e9acbb774be970206c3a738e243b420805a509fa59fa902044be2f0d013650d2ded5edaec5de3bf5b4d7c2f2e18e87f499c1968993eff196753db8045e2c8ba8", + "sha3_256_hash_of_public_key": "0c2e803c2872400c49e1bb10232946ab939319e84ff32cd354dc15d082cde5a3", + "sha3_256_hash_of_secret_key": "d37f172803739d074d71a2be32125eb1ba4250128342e34b882fcba38b259248", + "encapsulation_seed": "a4bd30a64cbf29a4e290fa1cc1dfb99e68348713041e4409a1af23c5d80c15c4", + "sha3_256_hash_of_ciphertext": "13d437b2fd9d67ca0699a3dacd977fba5d072fa6b482043d63e8a9548ba6a3fb", + "shared_secret": "6869ca370a496af2dbaa866265d91ba6be54b9686b1b8dd5714f6ba861b0d1e8" + }, + { + "key_generation_seed": "c1b3cbffad4b306f9af0cdd3028876486dbe858875c9b6497fe20172a986c82b1c96249919cedc2369d8d739ab125e0d2ccb82dfebcd90240a545cdfe07511f2", + "sha3_256_hash_of_public_key": "5818ac8d7a38c781e3a0bc43d088e6d391d1d67d9639b260bb6f58a19a57150d", + "sha3_256_hash_of_secret_key": "280e4774d1b2401580216fa70fb24c2c214ac5dc7f3841710a42e14d6aa09663", + "encapsulation_seed": "f4b66a7d3b65b896dfe100b2cad24b175a1168cfd2ae11fd704b835f6bcd311a", + "sha3_256_hash_of_ciphertext": "51eb70249a1abebd5159f1069b1acda2304f25fc9cbd9f4a625b58df448b47dc", + "shared_secret": "502d92b2a7e1804892ffb8ff009987a58f35baa30c0392c83859fde82105a9aa" + }, + { + "key_generation_seed": "ff7495b8575b5a98e4fd21fb4c3e58cbb60f14bef21aa74cf8802e3153f14807bdc370460375a778d1a31d01c42b66367ed8d9e8f84551002f552f0e52102b5d", + "sha3_256_hash_of_public_key": "172cf4f8dace8a96b8f70da966080a5e3f132873ca7544343377a99b65e8147f", + "sha3_256_hash_of_secret_key": "31136804b6c14f3a0a00a3295a5fed8d606369e64d272d432c59d7fe0ccc3e47", + "encapsulation_seed": "1d7b03d3c5eefb8ae5799dc569aa668f1bcb8c86607b089d3530cf61d6380147", + "sha3_256_hash_of_ciphertext": "9b38b66fdfe80acab82bf9577676f6566b4429f78a14f7486b07c96ae7be921b", + "shared_secret": "48eb4b840c0d957f28808e434786c02a8f99d3464ccb3caf91cef4a0f8e70c4f" + }, + { + "key_generation_seed": "bdc3fba1c32751139fc45bacffb3ea97f26573d804a5f27a459293d95190ed8efd5a08f656a6eb8cd20679930a31caa6a6331c4b133a6838c223ef9f769f6246", + "sha3_256_hash_of_public_key": "268b6356f92c57da6dd34494b927e8764adf0ad519612ef0d1b8951e50966c2f", + "sha3_256_hash_of_secret_key": "3bf02cee24670ca40b7280d8047fa147b24c5e286dcae9c24bace9465bb19f61", + "encapsulation_seed": "554f3385b382f4a46314de37ee3885addfc5332bd4038785094e0a832e9e8c2c", + "sha3_256_hash_of_ciphertext": "fe8c3fcee4be152aff29e55f42f2fb1354ae55ccbe38400bc901ca032ede1ef6", + "shared_secret": "f9507f70421be90f21138a1e135329ee8228682cc948a6914ea58624d396df0b" + }, + { + "key_generation_seed": "447f6076a627bbc5ad7773fbfeb14b4ba9ac43a0f8b99fb6dcd5e452aa3c47ec20a7237801f470fcc2bd9fd7bea8322859b850f7882d362947432913dd068c01", + "sha3_256_hash_of_public_key": "4c6d304e0494d88d83b5e3aa5761df3b299551a24f28994d2747b2b08945bead", + "sha3_256_hash_of_secret_key": "5de91ca73756eee74da3cac78a1fb329a02f8587f212bb9bc0b29e0e654a5795", + "encapsulation_seed": "38bf0033b779edf5367d9ebc01c988af90904c560970815837380650e4749eea", + "sha3_256_hash_of_ciphertext": "805ce0ab06c568b614cacbfa4cce5e65929e2846932a90e9418513dd48cf3358", + "shared_secret": "24caabaafe2063f812eaf57c58b6c0376ed8ff778cec1980ee9c3228801a75a5" + }, + { + "key_generation_seed": "2d5df64d62cb07fe630310bb801c658dbf3d97993e68626745de39d37fbfc2b27b534537addaba4ecf14f02ab317d36cb9f0f50222ced7cf029dff8a0d3d2fd9", + "sha3_256_hash_of_public_key": "72be2f5cd569e6229f00014854633f7b278e90af4ea593411909467a03e29cfb", + "sha3_256_hash_of_secret_key": "a68ca31b91491a129af9f280cb4c60c046e7a7ccddf41c9bd98663f8512ca34b", + "encapsulation_seed": "048ea516d0ebbd9f709b47eaac66f344c571cf50f0d01c9466aa061a50b66a24", + "sha3_256_hash_of_ciphertext": "d27a36808f09d6165aefc5d253090027eeff0653268c55a0b3de2a751ec765be", + "shared_secret": "9f734b15fc7dd99bc10d6cc7de5d2c93ac789a5665e508a95d075dffbad25abb" + }, + { + "key_generation_seed": "25056d1b8113bb362dd979d98643d7a7ac9c4f95994c0ba060609b6d07002ff3f48a9254dd40b117941fa35a66bb50296327b725525deef70e128ca8045ec451", + "sha3_256_hash_of_public_key": "0831c75b153fa17d336a79ff6e88ddf485daf7b1b0bcf39d8df15319d52ac67e", + "sha3_256_hash_of_secret_key": "2b983d7cb50880cff761441b6a2c66b7a41642cfd2a8cc297a5df53f0ed1947f", + "encapsulation_seed": "686c921c9db1263e78ae753b1c9c2e7936b8229dca48c0942c56c6bca4f10917", + "sha3_256_hash_of_ciphertext": "0892527da24957468b1b8fab49ad2d7dd6d238eca54624fce6a3c2dbbbe8d194", + "shared_secret": "d27e55f2a1f9ef336c8537f11da9875e03cc7dde8951d81b0740457609654107" + }, + { + "key_generation_seed": "e4d34e12982aeeb1d62fd488d9b9e28557ed3429292239fb4f76fa9098009acae6c45c7fc62329b13c8d29844405db8ff6860de474bf727ecd19e54e6e1a141b", + "sha3_256_hash_of_public_key": "b30cedc4316b63d75b641fbad2f33241a3fc47ab8b3ee1a3ed597e5b04f77c68", + "sha3_256_hash_of_secret_key": "a49a7533c671e533deec55af218ee511c57014070e138c7059853e08c34b0a78", + "encapsulation_seed": "2387772e50059cabda53cb93ba24b19ae529496c03b36584169451525c4a0e7e", + "sha3_256_hash_of_ciphertext": "390b3b6f9a0f9d97ccd452c83bf47416b22fd06b4d8968c44ee6effa7980e68c", + "shared_secret": "ed5903d1cf02861444cad7fc3793b4e1b9b6d0324bf6babfb768bb2f84300086" + }, + { + "key_generation_seed": "cd6a99396eb3539ca663a51e42063a3a262cc1c5a5fce1566f0597b52ad9fa325a3407f591791a5db4578b5972093a95bec3b8e70c1d542c9b5c9789729f8922", + "sha3_256_hash_of_public_key": "ee044dbdf6787ff038dbf9c133557169c62fc1ce2580739369aa87df00b49648", + "sha3_256_hash_of_secret_key": "9e865967f0d1e7d3f6a49f2bb623ced2a7b1408a945e02adbdca35846b70e7b9", + "encapsulation_seed": "155c29c5f0378df0cd0e847a80a07143cf7522fcd880c9229eb9feb1ce340cd2", + "sha3_256_hash_of_ciphertext": "6858db6eafd97259e6d775d881f7a877010179d4f827680426946b9ac4571261", + "shared_secret": "0d301028c1cb31dedc8a702a9e95b7d3589f68a6a1f600af84ae0f543e625361" + }, + { + "key_generation_seed": "6c8c53ed6f65e6b2e324b84364e10de42d1c26a106d4d1c99eee79c78586fb55b9402bf02481ce4b27a52e87feb92c4399c7f2988d40e942e7496ad15ad2aa88", + "sha3_256_hash_of_public_key": "e965ac6995d525e324e8252d8e2c2da909a29b24baca8b68daa5122cb539a474", + "sha3_256_hash_of_secret_key": "91051a381626e9465fc7ab20a1944eca64be461330bda53e7d1838a74597392d", + "encapsulation_seed": "a9cb9a61a3324b1ea5afe693b32784e2871096b2ca14a11acc9577c52359a241", + "sha3_256_hash_of_ciphertext": "42bfb5584610497fbc8080a664139afa534b39a417cb69ab0d2a16c8737eb1cb", + "shared_secret": "354d86b389021a3196b75c6582927b3a005fbfee0951f34d9cd5c8f415fa50f9" + }, + { + "key_generation_seed": "2107204cd995f1df14314d5381f8c5440f09a347502e161cffc0a2ec3dcfbc7324c3da70fe850e80aa818301d60c70f3038153866dcd5d179e22db59b8991bb4", + "sha3_256_hash_of_public_key": "a3d8a85f38cfda38c66ae39b2f9186ef7bc1e0c98e8976a6cbc6c4875d73d7fb", + "sha3_256_hash_of_secret_key": "cf7e797f8f7229a08206034737e54fe46645ab2fabdbfc8662b45a2604876b65", + "encapsulation_seed": "e99fbae8a024ebbbdcef32ce213f6aa942e3eca925e5da4c09975d773b33a175", + "sha3_256_hash_of_ciphertext": "ce7b65856502b280e02a36d906e018c6a23cae99f27ef6d65762c87ddfedff56", + "shared_secret": "3afcfdc446f93a8169024a24fc0383692843cfd6b4854a8e490892fc35aad4cb" + }, + { + "key_generation_seed": "63a925685a8ac5bbd918faa33ac397d1ffbcf99135d9da7c3d6ff7aa4c50af3d3afdb8a246a56ee71465591831c371f2eb87467b0559dedd776ba063ee6d2f93", + "sha3_256_hash_of_public_key": "aa73b40dedd61e6fdaac86971965c03ab14ae69e8130426fdf830bd57d0974ce", + "sha3_256_hash_of_secret_key": "1e7f3f1e5632d1df538b564304f56689742d1f652d8d32f019b45183af68a20e", + "encapsulation_seed": "67a216f37d67f5e74f782f1badbce1cc8c80a6130aec305b421899a4faa0a6c3", + "sha3_256_hash_of_ciphertext": "b6c40fd53bcd9ee1e70bc6783b402ae34c24dec724e63262d8583c90cd10256b", + "shared_secret": "ebba9a8bae936c829c1445c68595da96919041ee3d9b0fe27ca93db691146874" + }, + { + "key_generation_seed": "6a1aee5e708c1b47f02bdacce4f56c860f74fc7cfec1ef3b58285b1c8ad7fec2230e05b7114ff0395cc6634db1eae8258072d09c09f291e92d6620b177dc50d7", + "sha3_256_hash_of_public_key": "cf754f2ee43694865a09ca7beb0deda9b1328fd0abdf30ca5c338e27e8be04b5", + "sha3_256_hash_of_secret_key": "928592604aa44df8f2072f26e9511129f61da0b7f57acb3f6896635a9764ea87", + "encapsulation_seed": "52b19fea232c9154a3e431e9d69cda40013cf2d485c3cd027ad24e645420420b", + "sha3_256_hash_of_ciphertext": "a4b50ad169b436877652a6c64dbbffdd63f53274ddcf58f3c96c3929215aa956", + "shared_secret": "f063c0908deb2e61faa0c4c0f5051b2c8af7265060681df14bacb30f0228b3b3" + }, + { + "key_generation_seed": "6396b328b100e4c7f4bcae69875edea1a1982421558c608c13c592bf7b5d0fef1100ced48add211a5c937b8d6079d8e271af3f949edc61f70e60453aef20dea9", + "sha3_256_hash_of_public_key": "3a842153dee9e035299d7e268c9492d71188f9fb24bdc2dd20c1ddca647a1523", + "sha3_256_hash_of_secret_key": "28ee987bc4ae5a321d2669950dbf87596fc4b35c29f192836005064aa3dadee1", + "encapsulation_seed": "64440adb05db3308b189bf999f9ee16e8ee3a6ccbe11eebf0d3ae4b172da7d2f", + "sha3_256_hash_of_ciphertext": "126b64a28d82d06ca81f7e86d33f4949634924e04528d1142061320eaadcb841", + "shared_secret": "02d2e466e170bf45d3e9d357e2f04c34cda408cf147e9ff7a6e8c715f2c88ace" + }, + { + "key_generation_seed": "a453bcacdd2b0d4646009e5ed451c3c45f08fb827ef733db3c517a9dc1af93e67a3cc8aa3239d4c52ce4c95afdeff6efbfacac10d294edc0e7cf4535059bfdba", + "sha3_256_hash_of_public_key": "da43cae3c4da51d69a57eb87094a03cd3a9c3e6b4ed864cc691a60f0509cc646", + "sha3_256_hash_of_secret_key": "b204cd1c3122b29a3d99cb77e11427fc102375699928c5a6fe816f96bb212627", + "encapsulation_seed": "c8bb46b3a7344ad170c2052fb042b5a3b62e0590562ee82577b1081f6f114d16", + "sha3_256_hash_of_ciphertext": "228dfe300e3fabe4d4e550754ebcbbf72a796209c1d24e7ae93abb79e1cf17dd", + "shared_secret": "6a5b0842c122ab6ee251399492b061d2ab3e40843f4dc01c12fbd5bd545c600c" + }, + { + "key_generation_seed": "47ca2b77c5b717f423222c2730ca5cb9c856bc951d01b2b2c80bd76ccb5539b78f1481d7cab000e33fa07de8dc9627a85e76fabb4428a3376e66300cf12a0787", + "sha3_256_hash_of_public_key": "6533c524a32345eefdadc74a3c6ad7e981832797faf1068955b79f118dff9358", + "sha3_256_hash_of_secret_key": "b9dee52055b1f9a2b25a0c1be4d9f30d2ecd7c5a09f0f5294de2d49a55ac9fe0", + "encapsulation_seed": "2e2b70609f3fe029a14d09d5d659871ac776ce2797a0355f16e2eb68f5613fd1", + "sha3_256_hash_of_ciphertext": "2d7e8fbd6f2257b05eaaa2ca1643c452b4e0b623c9ad72027cca8dd8b7b5b91d", + "shared_secret": "2486c0a6cf17d9635dbca1f8395784cde54dccb7df10fced92183f983478fac1" + }, + { + "key_generation_seed": "aaf6eb40e596a5e3e8218871e708b089240dcbe7fd3641f0e5e41e071ce49107e2f8d320ac3cb0c52efdc753282f092bc39baf4a18783a48ea031a191865eb78", + "sha3_256_hash_of_public_key": "e2f60f27da7f318eb94a74b437f8e0bc9513e9bcc38dad99c174c1d75e0145f1", + "sha3_256_hash_of_secret_key": "68eaa8143a71bd5f6df29b128781e3f2a5fbc5d20534afb223ddcc64bc767f5a", + "encapsulation_seed": "4725dd8fb314bfd8ee23731c2341dbe114606d9abe6434c471b5573e7df193bb", + "sha3_256_hash_of_ciphertext": "b5b2de55cfaea8fe543f67c4f45a69780c3e2d932e56e0b574d9b40b56ddc1f1", + "shared_secret": "85690ee044e4d8e0540ff984775b59bb5134383c4e229e79e37d7d77632fadaa" + }, + { + "key_generation_seed": "6500f32c93415cfdbc0bd31d78d5be95cb9060c8cfa2013955b56f8b6868b322393308641a9a4647f230201e1389624a296b55192a9819fcb19ab77c25f95445", + "sha3_256_hash_of_public_key": "d4bf608793939ecba27dff5889d4d921c583999a57e20a48085ac549573e6abf", + "sha3_256_hash_of_secret_key": "5f9a14a9c41fc228306d79417015408f31bc9c3d97579616bd68a3d3444f9bd2", + "encapsulation_seed": "818d3bb8ebfb32bf464775f7139bac0a5bddce80ec5798595992f9403002cd5d", + "sha3_256_hash_of_ciphertext": "99fb7b7767fa94e74936a6678acfd5a2306b156f90f4608d507768a25403a16f", + "shared_secret": "d179d901a0570bd23aa52570c5c233a2240d4724e81d98c9ceedb74187eb75a6" + }, + { + "key_generation_seed": "7643cef2d62cc5aaeecf754653ea62294cd2208e5bf3ddeea209e3dc45373d49eac9d531a532770837a854b4f5531f6e0c8d6c10183b30d3435498c2dd142951", + "sha3_256_hash_of_public_key": "65f03add3941d22c80d50659f501f8cca1b448d84462ccb93d5f065889484bc0", + "sha3_256_hash_of_secret_key": "e4513cfd1dd2153d30d15b023421cb8e8456e6a40e612847e1713e915a29a87c", + "encapsulation_seed": "c92aa5fb91c980d9cade9ce99d4c75b2ffa7d6a6ff9bd59def1aa701f2a0992b", + "sha3_256_hash_of_ciphertext": "4cd7f0af86623b34c0b137a0516b876daa73ffd65d75871ddc828f86a7e9b224", + "shared_secret": "6d574af7fcb241fed8763b2d0a352870baf85ef686e90eea31f8500c35945ef7" + }, + { + "key_generation_seed": "f8ee95521060c03bb8dacc79f7eb7db640f545f315613a35d447a09e504cb4e13fc3d8392cb53f36ed647364a04e37278a0e0a45b720f4a75c580c9920eba98d", + "sha3_256_hash_of_public_key": "b8a3b8cf4709204a2fdb19889b0022ea655dfd58ff27e17d530510e1eef45793", + "sha3_256_hash_of_secret_key": "1f7cdadf3d4707efe1b7a6173d8f7b8a9f864ab388c3271d79ec424d9da3e896", + "encapsulation_seed": "7e8086a01dc5b3bb9eda25bcc45d27f99874841b97237968495800e007696ac5", + "sha3_256_hash_of_ciphertext": "1ca889a71a087ccee4ee1a178c3c55ce3649583f3db924e5c1003ccabc44091d", + "shared_secret": "b1090cf26276a81c22ef0e4479a4c705fe294d3b892051ddce7eab16495e0783" + }, + { + "key_generation_seed": "b8bd0493a882e3a49b4e0f6256fb1fea0912562fd9ba26ec3d6c9cc12c8973abd7e4b5d8021c486b9c3114d7cbbeb7cd49eba8a61bc2bcae1f1bef30a1daf76d", + "sha3_256_hash_of_public_key": "46fe6c37136273736ccb11df5b6d55debbc087de802404b72a003c5e8c809719", + "sha3_256_hash_of_secret_key": "3177ed170e84ff15fa1e744adc9ce806e431a68f15a7a026c6092bf593dec6a1", + "encapsulation_seed": "bb321ef14d44d8698df879fd52450567657f52a2df8d111185dcd7d4f30a72d4", + "sha3_256_hash_of_ciphertext": "aa9a0ea1823a84bc84649d26e249899437844827fe7c63d4828a5144929fa00a", + "shared_secret": "2fda9fa72321be3a0946d6d914c7ae714b9cc175619ab8abfd1f1fd499e0dc27" + }, + { + "key_generation_seed": "c0407e41ddf48d333978b89bcf2db01e4613425b456249e76a6f25b8a2827bf5b2dca81e3f5f748d23c9d356a2209f6b2d60247b2e45c9808de497f64f124643", + "sha3_256_hash_of_public_key": "a074ed1f76e97d68434ba4af2af0e549204222679e9e643580c35af3cdd247ce", + "sha3_256_hash_of_secret_key": "8f9b3f631d0fb04477846ae09aea725f1cc65b2cdefe2108cdb399c36db9b487", + "encapsulation_seed": "210a423dadd899b810f011794b79aa7f860823ac1962370e791287d3a1afa384", + "sha3_256_hash_of_ciphertext": "a4fb01f55eb2986c1f90cece43330bee1b16d7bda48d617fc94aa14fc540ec4e", + "shared_secret": "23798e8b9eaa0b369842cad83a2bc32206f791229c830d7593b9150161168011" + }, + { + "key_generation_seed": "334382d39164d1989696a2ff77b25a28af8bead9883b5365eb6fcca7c1781cc9aba5068af837be962f439f233593d193ce5e08f7d66efb3389885927b89d2523", + "sha3_256_hash_of_public_key": "26659f74fc9ec372fe18be4ed6aa28b7cd84ad1c0f0115dad011a11d20fda9ed", + "sha3_256_hash_of_secret_key": "5e3f83cb08ff80183879af9ade3631bed2a468e429ad027a5afeafd9a6f66362", + "encapsulation_seed": "bc856afe24213e3d14c3d6f9b89223bbcfb2c890722d770fa3492c1e46d1c302", + "sha3_256_hash_of_ciphertext": "6a4204db4803d26d7b8a769033e047f3b4cb616bf5451b88a1fb3ff219bba9cd", + "shared_secret": "d5c63d2bd297e2d8beb6755d6aefe7234dea8ecfba9acda48e643d89a4b95869" + }, + { + "key_generation_seed": "6995143e8eb8a6e93840f76eec844f67d2b5f75b1839a5040337e61f9806764a0f4dff8e56f68440836a072412a30d851ace2c7c6f02d60e7a8420001a63e6c6", + "sha3_256_hash_of_public_key": "2ca3d8ad2dab1dd8a2f4320658fe6eacabf70d907920593919119cf374516336", + "sha3_256_hash_of_secret_key": "2798448395f6ae3223550e7d5255e6a605b430229f5809b6efd0683a6b9ca402", + "encapsulation_seed": "5fc00f89563e44b24cd67d0ce684effe5731619fd08e7d72e2406eb016afb66b", + "sha3_256_hash_of_ciphertext": "dbd5fc0e1df33ff8af9efd5e281a2b98160f98653803cbd54e3a07292b37fcc7", + "shared_secret": "29d6a229adf49a1139794209307b0ca24be5825b2771809232fb718660162475" + }, + { + "key_generation_seed": "995eff7e0d195c6d0533f3dc194d47e60f9ad14696144cde694d60a95f3e96b4b28f7e7a15a005f92400ce33db073d49b53871594a88fc45e0f94207b5f0f2dc", + "sha3_256_hash_of_public_key": "de62eff56f6b49a156d065d85eaf0aa21ca229a20fa4e1372a410ab1c4ab6e7e", + "sha3_256_hash_of_secret_key": "6766cef3fe644a233caddf208074b58e6e83f8a78aecd00911c29a08f6f0b0f3", + "encapsulation_seed": "ea22a76065db4b565ee1807fbd813b43bde72b0e08407fb867c6a18995025e50", + "sha3_256_hash_of_ciphertext": "4c669e33b0227c9c2040cdacdbcb7d22b9984372587985ed8f860ffc8d037e79", + "shared_secret": "2a56a7a6d5b4c0500ec00a92e322e69be9e93006240889552072482966c54f56" + }, + { + "key_generation_seed": "3e809ec8dd0fec0d911a4e3fac20f70fbb128c5de94dc7184ca7310ae9157a98d8128601c28b1def8d393a0db283229f7c7383152a814e7cefe8ef9d9768c473", + "sha3_256_hash_of_public_key": "66f161d27dc34e1a2f4b98b14a2b221d7eae26a593bfe432487d9994cb480656", + "sha3_256_hash_of_secret_key": "2237f6cbb452d375878b82c474a7c948ff587a5f3ed02bbba1459fa7ff8ef802", + "encapsulation_seed": "e9602b34fe73ad57f4bf6ead99743d645641553a5b9b9bf2e7016629e3e9bd76", + "sha3_256_hash_of_ciphertext": "8a2453a21a031cb8966924607a28882426fab2018826192e9bf833bdd38e0631", + "shared_secret": "ecb62b03f640ae4a9d89685fa0070efa93c24dfcff0d555142f9de25b62f861c" + }, + { + "key_generation_seed": "dbf1c465fff3d9f783bd9ee61a573715e45691147b8904439b5ffaa64f94ff7bb6d75eac6c76ced1b0a025b40a55440712ad8424672e761e9bc400d63812006f", + "sha3_256_hash_of_public_key": "7537e68ccf14e8b7e57090d8f648529dc461ca3950288879e88116acaf57b4a2", + "sha3_256_hash_of_secret_key": "bd8e44337eef01251217c4702c99232c001b33870953473d83a7486fd25484cf", + "encapsulation_seed": "f72b9080a6c051bbdb9b0abc1949034be0f89a9f73fe277ec4d4740c78d04a83", + "sha3_256_hash_of_ciphertext": "6077c60641c03aa8b36213dddf938311ce6b7b8801f967d42713e73249fe7c55", + "shared_secret": "6cc30699701927e07b559d708f93126ed70af254cf37e9056ec9a8d72bfbfc79" + }, + { + "key_generation_seed": "1f7cfd2b70863154e8a69d1758532e86c20cfc763d67c758bd10a13b24e759b5273b38bddc18488024ec90e62a4110129a42a16d2a93c45439888e76008604c6", + "sha3_256_hash_of_public_key": "82f68b15681cca5c2852c18d6e88bcb102a059c1d21936582adb71790cc0a335", + "sha3_256_hash_of_secret_key": "fd483ddc211c5c27f453bca56158e1f8084f075a7b06f5098cc3204427bf8197", + "encapsulation_seed": "f1e5542190db8ecf4b8d617a04fd3783ad0df78bf8dab749afb57db8321d151b", + "sha3_256_hash_of_ciphertext": "5c6cfa16f63b1aa93a2b5edc2f4b14c9782f286f53deedf3153f329a2ae2d57a", + "shared_secret": "250e7f67bb34dd5477471e3a701fb71a8138a1920eb807824380f88a944a6fa3" + }, + { + "key_generation_seed": "3a19577908efd37697b8edc7fdaf47d1bd3ad01a1b77faf794bee5b9c3192a6fa3729672816f3eba84c9638a79676eeac0f22c8a48e0c5d50a26ff0844c66b99", + "sha3_256_hash_of_public_key": "104fbf09445794c0ea0654f5caf70ee09d51c8386d4e1f467b10633c710ac2a4", + "sha3_256_hash_of_secret_key": "73fb93953ae666a9df1bf933ba56b8655ea9e319c0110c78d49f8480ae1aa3fd", + "encapsulation_seed": "74efa414ae171bf60b6f884cb7e5ce12028f49365daccfa23e845d551711660b", + "sha3_256_hash_of_ciphertext": "e51772e769f778067916e81a561ba6f64fae6096a2b4d4b945d9117e7c36e2b1", + "shared_secret": "0210935a18f1add5ebc2e1107bf40a628ef9cf8f6e7cdac81dc0291bb50a5a3f" + }, + { + "key_generation_seed": "ae0f65e29f38804a6759f70f4d01e2aaff7fe1c91ebc4f892dd0de3ab2e68ea5e03ff73e02a217659f53d8c47556bf3d8c94040f630d63605e2d0f923579370c", + "sha3_256_hash_of_public_key": "0f353d6a29813d354471eb8b4c38df93939eb3b1db80ddd1cdd6558a9f2687a3", + "sha3_256_hash_of_secret_key": "8a9edd6278707108652f3a5bc244592cb7a82c24634583ed2d3eb6a176b216b8", + "encapsulation_seed": "0b4c3cffb2ba4380ead13dc0d8acad2356b448a810da1df29f264c44aab6d24f", + "sha3_256_hash_of_ciphertext": "a00c37bd326205575fcbbc100ed54630aa0f2d6dd9e69807d49151ac9a81c429", + "shared_secret": "34169fc520e944f94ff1fa3799db802a4c1b26cb2971bf196259a937ab8362ca" + }, + { + "key_generation_seed": "6084a235f79dd093ef6d185b54e69df33dacee73a9bf2f379004421a10e3a79d9f684fb055ece19459eb464e91e126a7a6e3ed11ccee0046da234d964c985110", + "sha3_256_hash_of_public_key": "12e89c47142418c26396ef0174c02f69dc00022d56494d31af935490edee6385", + "sha3_256_hash_of_secret_key": "bc13b19f01d4cab36dac2154e0fd8fb7d2fa012596363942847f1b0bb3715f90", + "encapsulation_seed": "1c82471dcdfca3a6942061ab4f3d5bf0d197321437c706d9cccccce449447002", + "sha3_256_hash_of_ciphertext": "aed1a4ee810b81cb8ee49ee00e94ff4553f0ad2176fe4d27a09f4e68157fcc3b", + "shared_secret": "b5901e97eb656a09d2dd132528148ad07a0a89f638717eb53516a9ad19aa36bf" + }, + { + "key_generation_seed": "acd1c0217fad5caa4235544dd9de153ab1880ccf4c76f16f236fae4e4bfda04cf03a8abb0a5010f400ae5722a75bdf5a2f6d5b546b34d73857cb1bfc7e587aa7", + "sha3_256_hash_of_public_key": "2fac52ca60594e514333ead02cb1bfa5cd1d9ecda4a0b25ccdfc47ad3f632a85", + "sha3_256_hash_of_secret_key": "2743b7a9dd83a6b9bb5c2685f28b5629b2e31132ac64788a0929557d3449dfc0", + "encapsulation_seed": "46fe60a18124125ab93e0c578f1c02f1bd1301595013001c7f3c2fa56cde294e", + "sha3_256_hash_of_ciphertext": "7a039d19c45cc557036189cbbc63445b3504a689db56845ece99d593f165c6af", + "shared_secret": "df5117706beedfb521f0f021069fe9650d0844194339033de6997dced05268c8" + }, + { + "key_generation_seed": "241191401a63afa750f05662e354dddbc683c776ce3222beb83e3cf913d7ed7ca59b3bd23b49a95bc1fad20070fec930b6060bd827d742b077092e422268e15d", + "sha3_256_hash_of_public_key": "3eb856043b822df9d60b55fccb537afa3cacca9ef50433bde1dd9831e534d192", + "sha3_256_hash_of_secret_key": "398ae3423ba5c6bb05920e83e8939a104c3e4ad91647edc7db1667efe438cbfa", + "encapsulation_seed": "52fb7cb6a633fd2e83f2892bd9441b48fe59ecee6d026f5246fa7f2a5e55ee3b", + "sha3_256_hash_of_ciphertext": "05c9617befed785811fcc44d0fce5ae3a1ec66c4d1217ab42e4b754d0ef6207e", + "shared_secret": "eed6ecb831c881508f99ea115745448a7b312a4fa97f65044ebcede172dee2fa" + }, + { + "key_generation_seed": "b9a6b0c05677e957d41a34ba03bd06f2a9092e31f63389397d7e70fde6409d18e99c0e7b82be89bc3c1eaee6680aa4efd394e40c2b3f30523c8117f7c26a8969", + "sha3_256_hash_of_public_key": "306aed2a804a1c9bad4ab9e59f6126ad7c8633cdd0c2dd9d4c6f639d312ed47b", + "sha3_256_hash_of_secret_key": "88b28cf6fe19424ff82fc2bb096423b71f0cb8cf985af31bc15ceb4ed18a5e62", + "encapsulation_seed": "0f81a5f97082121244403da3feeb734f6084b314b8d94beb11627aa6ad1914e9", + "sha3_256_hash_of_ciphertext": "315ef84926802ecbbb437f8f50927d3a391b55ee6e47dbd19aa9adeebb808008", + "shared_secret": "d6cb77dc96f9ae4bf8b2fc0e277935b3b7b7a59f749ff2c08ad42659dbce386b" + }, + { + "key_generation_seed": "28a96c71577ba00c94f99fe965bc595a26db2b3ca6ab5cf8e443cdd8462b17929c35d165453e5fcdc6f9df64526d9de698f2bd3e6bac6c7fdd86601b9ba5f4a5", + "sha3_256_hash_of_public_key": "9bb3963cc1c5cf2b2d1c6ca76226328ab765a79999ccc71fe98d5bf3b34f51b1", + "sha3_256_hash_of_secret_key": "d8c2492023fb1175a84c19b3ce20f03dd12b1c26b65176d5582c319124bc0e24", + "encapsulation_seed": "31af9345365549ea0360169ed57daf98cc5444799d4c75d9f1f5d615e9df8a91", + "sha3_256_hash_of_ciphertext": "ae36e333ece7ca60c9bc2c4ddd01ca88443fd73bab08502656873b703af8925d", + "shared_secret": "1592f1413331f1871b41ff298bfa669bca667241790370d81163c9050b8ac365" + }, + { + "key_generation_seed": "c08ba2ef8c3a0a043afad931652d7a19e6e8cb670f840de5f1fa03309b2ca9ec5fe6141a25f7ab9f875f79e0a82d6ea5cde5a017ab637d5fdb7c42646a1d71df", + "sha3_256_hash_of_public_key": "6d029bb2121c788b5b6ead7226df664490dae362c4befb615717d81c656b3273", + "sha3_256_hash_of_secret_key": "0f2c7bd16d9289c3c27136df0cb6ebc624e80144cb92e6f0c897f58a53617ac3", + "encapsulation_seed": "774ae54093d694ef40b63b62c73e6c98295f606feb8699807eda1d030ffb996d", + "sha3_256_hash_of_ciphertext": "f8a85f106c6144edf1c7906ec26e292f0390aa9d45a22e67ba2ea018ff565c4d", + "shared_secret": "966f35c6bc47b4525d9af1ba350e8f44ea448cd1d90cf4e9c55ae5878920b7cd" + }, + { + "key_generation_seed": "0e3b30e102d707538c2671060f603bb0b8a014103f132d63b09ece07e4a4c75b11eafeca9e810796c34e8cfce9d59342884456007b01ddd12edce6d10ed87e4c", + "sha3_256_hash_of_public_key": "64c819d9bf66855f6ae70627f04da8378547e5867e2eb9759fe0971efd601c4a", + "sha3_256_hash_of_secret_key": "e85b62236d5c6c691a9076dc58bd5da80999eccc8df973c7d0e7e65d8465ea7d", + "encapsulation_seed": "9f27a47604ab5146caaf0aafe6d149424f8d66e39ba3baf5e6c73b19221b7e21", + "sha3_256_hash_of_ciphertext": "e9149359cc37143b0b565bd413a04f41a7833c5b76012a9263a086ac34071684", + "shared_secret": "aa333af0226492126c6985130ac7df2226a64d6d5c5314ce3f7a99add6696d49" + }, + { + "key_generation_seed": "2478f7d3de6041e7e5cd11c5e2ef483d1aa6218eb126444091535f6ae532fa7311136e2681df2ef881b51a092a9badbe72c9772c169808521c47149578621e28", + "sha3_256_hash_of_public_key": "db315cafbaec2f8a0142f45affff65289e826c9244ab1cb03f9f65df3e3cbcf7", + "sha3_256_hash_of_secret_key": "be98d62e4724c0d960ad4839298d4571f9871033b63bdf10d3b0e589db376ffa", + "encapsulation_seed": "90044031b7597b5e60a4f946b713e8996d0426d2cb013243d9b7d8f8ef159a0f", + "sha3_256_hash_of_ciphertext": "9f9368ba712cfee95f28a808cb2c23116a0c8da3910c0def2ef4e55947d7101b", + "shared_secret": "9535303e6035e30c6605c9e0f10c553dcd73828d8525cb190fea79937e093331" + }, + { + "key_generation_seed": "9d405d3ebdaf35fa8722de431b669722acaaea2fd10b814310b17f78b66147d16ceb14f7662be0c42779459f69a145c0e2ce9f0bd9a0cd1bf32ed5694cc9ae32", + "sha3_256_hash_of_public_key": "c8d853e65b5b118e28b7cb6f0d5d6f282e0ea20fd72f3690a6b232b20a8a55ec", + "sha3_256_hash_of_secret_key": "7a5e854bad628be7b99f524f52a97b0959c0ee67a7a10ad24b970e6e3aeeeb80", + "encapsulation_seed": "a7a31e140891ea37d2b6424b59b1f84f89220f32dcb73e037eb912b389d34a48", + "sha3_256_hash_of_ciphertext": "31b04a4127558df57844413928b29b11547de5afc088d568a962fe080c97f190", + "shared_secret": "0caa79e0054182c15e54159fbe36d9fb09481331a560ccd9714fff81db5615c4" + }, + { + "key_generation_seed": "9a86490f0615f3edf789cb0654066e9ee339cc59f968281f3b89213f83c692edfaeb2ef44d2f608621e831187ce79b2d2f4a20f1568bbe76b0d3d5af36111714", + "sha3_256_hash_of_public_key": "f69bd52cb1d071f1cc7720f949d44f66f40c917eb30f3a4b0eb519ecad2d03dc", + "sha3_256_hash_of_secret_key": "b6ef04e6acbcd1bb072d1cd28412cdb00ee40d04ce5b39442a2efd6756292167", + "encapsulation_seed": "70eb3f791faa91f1f982fa477dbcddeb2c55691c07f93b04cd31b37544c94b42", + "sha3_256_hash_of_ciphertext": "d8fac8ffc3d8dfebe66c219f4189b780d5ba8fe28d5ab79264345639740913b0", + "shared_secret": "744ce1aa5a9c515c6571ad6e2f5985df8434e35e9f714cf3659f184b5db4086f" + }, + { + "key_generation_seed": "6dfd9b575872560c7bdc2732c4a28dac4db04e535eb8e402c3dffd145c09ce47a2985c1c4d203778597947d710dec806e36b0cd949fe460ef141213bfc525e5b", + "sha3_256_hash_of_public_key": "10e01965f9c196d2f5f90ce3ce8f552f8a0d76ba8f5345365392febc50560012", + "sha3_256_hash_of_secret_key": "2b5c6d5fe9b09ab5a027522e699401223ae9d304ac912f1b15f0f647dd9a0a7f", + "encapsulation_seed": "30f4095015ba88b6d969672ca3f438c395dacf7d476ea7a9e805ce932d270a13", + "sha3_256_hash_of_ciphertext": "e8b01628c7d63f16c59e67352399a760581f341ed41535013490502e884733be", + "shared_secret": "726f7d790df4c860a0b2c40de9d62c85d0ff70c704ce5a1b3f6bf1b3e3f66cd8" + }, + { + "key_generation_seed": "6fca9f4e384d8418075cc064c70730801bdb8249899d456a77130d5beeb3662cce7683f8a03d3cf04e46970ff7d6a12494ae12558346dfc8fd9370bf944a0102", + "sha3_256_hash_of_public_key": "7c3991fa7983d0dd6e7157cfb152538466e9d5c3998a2b8ed862162b91ca851c", + "sha3_256_hash_of_secret_key": "72e786018ae9ab8293fa51cb7ca3ff0435e7cccbd5ae02b4680b92c148590265", + "encapsulation_seed": "cf31220f44de862e1719570e1b26e897790159366a385452334fe24cdcae28ba", + "sha3_256_hash_of_ciphertext": "5b2e8a3e38c13b53393c8654e92eeb6251ddbe50de4b3c5203a06977491f2fbc", + "shared_secret": "68f3e22d1b2d8c57bff32160e550becfce535fdcb327394aabeb60eede263213" + }, + { + "key_generation_seed": "e58f71bf175c0550a67e00e0f7b3b7fc36bc2707bf0c93044a492626de36301a7f7054814869cf7625e45647bc1547aff288dbb90699b2ad84893f3b755d9722", + "sha3_256_hash_of_public_key": "8aacd8940ff6fc27f175342be74d48075f8ae9320cae20a41c879c27c1bf815d", + "sha3_256_hash_of_secret_key": "f7399dbf35fcc57a9bff87b0087755faa75267788cd0921b9ebc5cde8b656271", + "encapsulation_seed": "bb5e65669a44e5d5c709bafa98c16ccba6ac2c4ae923334f69a11543eda64f5d", + "sha3_256_hash_of_ciphertext": "aac868f2299bcd272afacf50f1ab0db3d092d33565cffb5645d8b92271e7e893", + "shared_secret": "7f6085840a30c6b1fb9dca782e0c78a2264d54726c04c3127956f131165426c8" + }, + { + "key_generation_seed": "e3fc575ed51513e62aba655d24cd9c8f1c6c848aaffa946c49a53ac3ea59e474d82c2f1bf2e6aebde5660fa73356982e12999d8fdafbb3cb186341d0386dead0", + "sha3_256_hash_of_public_key": "149e0b6b49fe8adba1217c2c57c83f2b8c5f1d92f319e502b184a65869214f75", + "sha3_256_hash_of_secret_key": "6dfa4d29af6a0e8413d5591339c15d2e2cfac3f502f49acca3efb53b53624666", + "encapsulation_seed": "9ddb3aa9c7905d1a438c93bcf78e3e321813580371ab4e1289e2dbf3701972c2", + "sha3_256_hash_of_ciphertext": "ced7a64ce643faebac8ffd39c6a4594732b35f1d6899978ba192b87003d3ad27", + "shared_secret": "96e30641ea4280168da37291a3063342ced8e77b33b5415819938c0bd7264ffc" + }, + { + "key_generation_seed": "470b4943f0fe7fd0d8ec5185aba0d1db09d112934e4fb4787e2bbc6b88466e7b8b2809fd40008be70a6b184981101724bc3d5ec5e1956b510b82fd5ad0668a5a", + "sha3_256_hash_of_public_key": "29b1bff7f12eda28dfedfbf0ac16e27008c9fdc62c35e53b28a312bdc91c40bf", + "sha3_256_hash_of_secret_key": "762a61eb847c017ece920f51d5da7a9036ed8b835bfd7793527321ec635e2fd0", + "encapsulation_seed": "26d90b190a6c3d0d9a86cf66005154e7086749e966e7187c249ccb9329fd3b8b", + "sha3_256_hash_of_ciphertext": "bf49310a35f9ba7994645f12949e658b0dd43d3de76386dc20d08c650522f86c", + "shared_secret": "47e54c85cc0e2503629a8bfdcfe038c3cf692d723d462bab733c7c8e0aa37b02" + }, + { + "key_generation_seed": "6df4385db978d27b27d2aa5e452e4152b36f097503d9581ac3390105c5727e7dc95fa08ed106ce84660e8a4c90bd2b22634e40769aa0090a101c5dddad45edc5", + "sha3_256_hash_of_public_key": "b990059e901097d00e0ebaf40c5d5dab009c66798489d357e760478ce884cce5", + "sha3_256_hash_of_secret_key": "37a044795bd330e4dc60a6d84bc6e99664d1be418b0239661d2ff16d1501573f", + "encapsulation_seed": "7db6d1a129d6123f1f805b79ad3b413012ea86aed42a05e98e7b1f32f9fbbdec", + "sha3_256_hash_of_ciphertext": "329115908d0763110a387c99778e4746861e80367ee90fd821cda9acdb93fd64", + "shared_secret": "8569bd042465a2c4af628425cb102b15ed4f5feee16090e2234f3a884a0fa938" + }, + { + "key_generation_seed": "dbacba825728444921b227cdba54446b3f6881b47be9cd02832f78b023b1bee0e15274a8e2bc08fe818b117ba28c5dfae74d54fcdf6f20052f79be333edc8dde", + "sha3_256_hash_of_public_key": "175eb63c3144108548720ce7ee0f43a9ff3f52a9924efe9f2f59318bb93c86b5", + "sha3_256_hash_of_secret_key": "1993d7639b79f5e4871a7c58a69fec50f96c1424c2c0ee030ac054ae1b88a56f", + "encapsulation_seed": "1d129b27be7384c359d04311fe5c44917d1fde4bfb57314f483ac617edd5ac49", + "sha3_256_hash_of_ciphertext": "8f4225838f2964a986336bacddc40836a98c32cca68c6afcbcf9ef68d9a3760b", + "shared_secret": "c184e0b019c2db772e2c1ca6f97f47478d99cf0c4c5ae1406f51d15815022123" + }, + { + "key_generation_seed": "690eb71fd7052b906eaec09937a8ed374e0b02afa27c2f14399932be5839fad281c38c2cb5cfafac81b96a810ab749b61806b6d54c9f8cf4bf1be0192423288f", + "sha3_256_hash_of_public_key": "9bc32a138a2fb5b6072464172abe0fd97e9eabf357c3fa5391d94a415b53abd3", + "sha3_256_hash_of_secret_key": "3db4ab1393cfc8b1c708cf8efdb1c443c975878898b60182c22af66375cba13a", + "encapsulation_seed": "bbc773ebd2df42c36ae05952d6a64c63a5dfb82ceb3ef4f8d4df3a30ec8c0467", + "sha3_256_hash_of_ciphertext": "f1c85f9530d4471eb1401fcf422a29533738c485a6be25f0b554ebf40b49d49d", + "shared_secret": "6d72e23c8a4cc60b2f14adc788a5c480033bbf6eb111070912bc83ad7b89280b" + }, + { + "key_generation_seed": "32e0ea9089fa928482c0770da545af1bb871a03ce38604138b0d08ea2a10ca2bc06c5bef7b6508409daf847a64c8d30d0974fd3ba7476dc76c46b458a036d884", + "sha3_256_hash_of_public_key": "7ef43a72ef04766f1e899d25c9a005009c788b5faf985123cfb3fb97975de26d", + "sha3_256_hash_of_secret_key": "77431cb18010a604d56fe5a623bed2ffd028a741f176fa09546e9a45a48caa5e", + "encapsulation_seed": "5b17a6adad541efcbf5ae4b0c0452cd2ce32e4f0f8701801c5b63e197c1fcbf4", + "sha3_256_hash_of_ciphertext": "83ddab2e25614544649a1e497b5b21c40a3e154e8a22c270f63cb0c40aa868fd", + "shared_secret": "29e6b1edac0a9aa33066c113167e42c64d70215ed04963d8be2d4c2dcd0f6589" + }, + { + "key_generation_seed": "6fb2ec719f2a0dea152bf3f64b9d148f8ab8ba88f64e61f5db53e12d59f525574f797c007e4061f95c7d56cfc7ee5c49e849dde3fea8f25e7876df2a18515c34", + "sha3_256_hash_of_public_key": "2c0db43f39b672b2cd912f907cf76a0f6fda925eb2d205546431be0b37b20411", + "sha3_256_hash_of_secret_key": "09844e203f4d8fa30728ab388b9d654847febbf5c9cd939cdc11c9c9be24ce9c", + "encapsulation_seed": "61ab87659525de9656af41246f20e1dbe85c24e335e7ecf9493f46168bc14e94", + "sha3_256_hash_of_ciphertext": "a2108ea2c446b566a50c228928893e2e4bde5fafb2184af92eb1314113bde0d6", + "shared_secret": "cfd1b82181543656807880f6e2576f0b095bf84629b3367e9bdede24662ee42e" + }, + { + "key_generation_seed": "527fb88c8bd9a4d6031dad15e63878abd2b559e7e08d61f69e8e78fca964ee6ae32d432b4f9f751bde0496c580a181ffed762aa35454a02d3f1f47ee0394c89c", + "sha3_256_hash_of_public_key": "aae8e61b905723fa092fb95b839f6de3670c39ce0498c27b87d20c24e7f64e22", + "sha3_256_hash_of_secret_key": "3880f7ca8fc33575a7a6d8bb46fec86a3f12e0068630507ed245d8bc278fbe5d", + "encapsulation_seed": "eca2adc3da1fb15f34033405ec08ef2f46163df4bfcccf8842c600ce0bc2026c", + "sha3_256_hash_of_ciphertext": "ec48b3ec403609a0ce2d1268cadda8184ab9629cc5913135ffdecd420eed1aa9", + "shared_secret": "f7331b0a4674969838482b7184fa92e5246f11f5b5e284c3e179effff7eb6329" + }, + { + "key_generation_seed": "ac6fcfaeeef795b6ef9e062f02bf42975fa01e7d91ba832f74e05269a72684d05aeda108ea4d6c6bc0fb958286850422bc357ca67b83c986048e0d0087fa11ec", + "sha3_256_hash_of_public_key": "64e085f67e48f00a7a7f82963e8c67176bff839a54fa1008328c0612f98d83d3", + "sha3_256_hash_of_secret_key": "0bfbc25d9df751f4c30907095eb6d9a75ed07fa23218ad0fffc469f0e55553c2", + "encapsulation_seed": "c4f15bec2d7701339d0ade4835193bea3632edcf89e74992620d9eb623a0d0d4", + "sha3_256_hash_of_ciphertext": "fb74b727ad120c18915dca475f3082cd34ded7ae20a308106384ffb5caa029d3", + "shared_secret": "c89d62938a5caabfd5b30d82ea88aced52ef5f8ec0528e59a654e1f6aff1cc2f" + }, + { + "key_generation_seed": "ba2fb9318d4dbe7488057c33e95e6f054583a2800c41bb83083c330a914a12cfe63f8ffda3565c2424c89b20974b748a65a5aba75133fcb3156dfb6626a83bab", + "sha3_256_hash_of_public_key": "8dab879de09b58d0fc7ade140393ffb5343abbddabdc118fad519b14436a964c", + "sha3_256_hash_of_secret_key": "7c53072fd98ea7bd8c5e873688b1a5650fe7e11c791407ac8c118b7958cf414b", + "encapsulation_seed": "28878249e2ac2b6263422993923a0c8bd05ce56e385ed13c943b03d226856947", + "sha3_256_hash_of_ciphertext": "a1f1579c4ce8eb725e697623321b3d9f55f4b1d0def10b898535ef6614e9923e", + "shared_secret": "204d9272682710b52fb39b1176af3ff737848978770310df0c67996f6cb596c3" + }, + { + "key_generation_seed": "aa6dd1e5799cdf7af9c4fc632b3eb9d51d66e85c8e0a21ec98664fc51ab63c7dfda268813efab5204efa60f78bf81d320d01ac09ac06244f7afbd2d80fd356d9", + "sha3_256_hash_of_public_key": "919a696301240cd6129f66be58e19d99b0d827d9932785cd9ea3d92f7ba54463", + "sha3_256_hash_of_secret_key": "cb1d7301f15951883cc3f287d4dd8fdf5c9b7022f558dff551c2ade5f5065755", + "encapsulation_seed": "17fc65f7fbd7c75ceec421dee84dff5a8cb22764a182db17e0ebe857f54d60eb", + "sha3_256_hash_of_ciphertext": "f02654803493821dd9c2ed23f9e46a36addd5fca0da706bbeeda87a2df9fec4f", + "shared_secret": "76e5f7623e3e867fd12f28dfda4311f7cd90a405b73e994e857f693573fd2b8a" + }, + { + "key_generation_seed": "195d6c86a3df4c21e3007d7f2768b43c74cb3060e0eca77f0a5d3271542b9a84ae77e0f9f21eabd8c0c6eea7767f4e10fde5c2d79b8400bf96b19014b457ec21", + "sha3_256_hash_of_public_key": "cb6d7232426bdbdfdacd373c9190722e7bf342825f7d829185dcc9120588fc76", + "sha3_256_hash_of_secret_key": "a85e24cc2eafdfe40d82f46471112e1359628b9955f3feae9955b48d563ac952", + "encapsulation_seed": "fa0489f3730100609488e951e6aaa15c0f193bc1dbcfcd013bc418d6c507b176", + "sha3_256_hash_of_ciphertext": "17336b9ede3a1c26abe725828a5afbe746035a73dfd4a8fbde5040fbabeb2b8d", + "shared_secret": "874ac966970f29935db73c231e71a3559b2504e5446151b99c199276617b3824" + } +] diff --git a/libcrux-ml-kem/cg/tests/sha3.cc b/libcrux-ml-kem/cg/tests/sha3.cc new file mode 100644 index 000000000..f7419d5b7 --- /dev/null +++ b/libcrux-ml-kem/cg/tests/sha3.cc @@ -0,0 +1,58 @@ + +#include +#include + +#include "libcrux_sha3_portable.h" + +using namespace std; + +typedef vector bytes; + +vector +from_hex(const string& hex) +{ + if (hex.length() % 2 == 1) { + throw invalid_argument("Odd-length hex string"); + } + + int len = static_cast(hex.length()) / 2; + vector out(len); + for (int i = 0; i < len; i += 1) { + string byte = hex.substr(2 * i, 2); + out[i] = static_cast(strtol(byte.c_str(), nullptr, 16)); + } + + return out; +} + +string +bytes_to_hex(const vector& data) +{ + stringstream hex(ios_base::out); + hex.flags(ios::hex); + for (const auto& byte : data) { + hex << setw(2) << setfill('0') << int(byte); + } + return hex.str(); +} + +TEST(Sha3Test, ConsistencyTest) +{ + const char* message = "Hello, World!"; + uint32_t message_size = strlen(message); + + uint8_t digest[32]; + Eurydice_slice input; + input.ptr = (void*) message; + input.len = message_size; + + libcrux_sha3_sha256(input,digest); + + bytes expected_digest = from_hex( + "1af17a664e3fa8e419b8ba05c2a173169df76162a5a286e0c405b460d478f7ef"); + + EXPECT_EQ(strncmp((char*)digest, + (char*)expected_digest.data(), + 32), + 0); +} diff --git a/libcrux-ml-kem/src/ind_cca.rs b/libcrux-ml-kem/src/ind_cca.rs index fd18e20cc..34fcd5bc7 100644 --- a/libcrux-ml-kem/src/ind_cca.rs +++ b/libcrux-ml-kem/src/ind_cca.rs @@ -27,6 +27,7 @@ pub type MlKemSharedSecret = [u8; SHARED_SECRET_SIZE]; /// This module instantiates the functions in this file and multiplexes between /// different implementations at runtime. +#[cfg(not(eurydice))] pub(crate) mod multiplexing; /// This module instantiates the functions in this file for each platform. diff --git a/libcrux-ml-kem/src/lib.rs b/libcrux-ml-kem/src/lib.rs index abf3b7b1c..eab9061cc 100644 --- a/libcrux-ml-kem/src/lib.rs +++ b/libcrux-ml-kem/src/lib.rs @@ -73,8 +73,11 @@ mod types; mod vector; // Variants +#[cfg(feature = "mlkem1024")] pub mod mlkem1024; +#[cfg(feature = "mlkem512")] pub mod mlkem512; +#[cfg(feature = "mlkem768")] pub mod mlkem768; #[cfg(feature = "kyber")] diff --git a/libcrux-ml-kem/src/vector/portable/sampling.rs b/libcrux-ml-kem/src/vector/portable/sampling.rs index b6643d1a8..87dacce97 100644 --- a/libcrux-ml-kem/src/vector/portable/sampling.rs +++ b/libcrux-ml-kem/src/vector/portable/sampling.rs @@ -3,10 +3,10 @@ use crate::vector::FIELD_MODULUS; #[inline(always)] pub(crate) fn rej_sample(a: &[u8], result: &mut [i16]) -> usize { let mut sampled = 0; - for bytes in a.chunks(3) { - let b1 = bytes[0] as i16; - let b2 = bytes[1] as i16; - let b3 = bytes[2] as i16; + for i in 0..a.len() / 3 { + let b1 = a[i * 3 + 0] as i16; + let b2 = a[i * 3 + 1] as i16; + let b3 = a[i * 3 + 2] as i16; let d1 = ((b2 & 0xF) << 8) | b1; let d2 = (b3 << 4) | (b2 >> 4); diff --git a/libcrux-psq/Cargo.toml b/libcrux-psq/Cargo.toml new file mode 100644 index 000000000..e85de5287 --- /dev/null +++ b/libcrux-psq/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "libcrux-psq" +version.workspace = true +authors.workspace = true +license.workspace = true +homepage.workspace = true +edition.workspace = true +repository.workspace = true +readme.workspace = true + +[lib] +path = "src/psq.rs" + +[dependencies] +libcrux-kem = { version = "0.0.2-pre.2", path = "../libcrux-kem" } +libcrux-hkdf = { version = "=0.0.2-pre.2", path = "../libcrux-hkdf" } +libcrux-hmac = { version = "=0.0.2-pre.2", path = "../libcrux-hmac" } +classic-mceliece-rust = { version = "2.0.0", features = [ + "mceliece460896f", + "zeroize", +] } +rand = { version = "0.8" } + +[dev-dependencies] +criterion = "0.5" + +[[bench]] +name = "psq" +harness = false diff --git a/libcrux-psq/README.md b/libcrux-psq/README.md new file mode 100644 index 000000000..c98576bbe --- /dev/null +++ b/libcrux-psq/README.md @@ -0,0 +1,32 @@ +# Post-Quantum Pre-Shared-Key Protocol (PSQ) # + +This crate implements a protocol for agreeing on a pre-shared key such +that the protocol messages are secure against +harvest-now-decrypt-later (HNDL) passive quantum attackers. + +The protocol between initator `A` and receiver `B` roughly works as follows: +``` +A: (ik, enc) <- PQ-KEM(pk_B) + K_0 <- KDF(ik, pk_B || enc || sctxt) + K_m <- KDF(K_0, "Confirmation") + K <- KDF(K_0, "PSK") + mac_ttl <- MAC(K_m, psk_ttl) +A -> B: (enc, psk_ttl, mac_ttl) +``` +Where +* `pk_B` is the receiver's KEM public key, +* `sctx` is context information for the given session of the protocol, +* `psk_ttl` specifies for how long the PSK should be considered valid, and +* `K` is the final PSK that is derived from the decapsulated shared + secret based on the internal KEM. + +The crate implements the protocol based on several different internal +KEMs: + * `X25519`, an elliptic-curve Diffie-Hellman KEM (not post-quantum + secure; for performance comparison) + * `ML-KEM 768`, a lattice-based post-quantum KEM, in the process + of being standardized by NIST + * `Classic McEliece`, a code-based post-quantum KEM & Round 4 + candidate in the NIST PQ competition, + * `XWingKemDraft02`, a hybrid post-quantum KEM, combining `X25519` + and `ML-KEM 768` based KEMs diff --git a/libcrux-psq/benches/psq.rs b/libcrux-psq/benches/psq.rs new file mode 100644 index 000000000..a25a8b343 --- /dev/null +++ b/libcrux-psq/benches/psq.rs @@ -0,0 +1,334 @@ +use classic_mceliece_rust::{decapsulate_boxed, encapsulate_boxed}; +use rand::thread_rng; +use std::time::Duration; + +use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; + +pub fn comparisons_kem_key_generation(c: &mut Criterion) { + let mut rng = thread_rng(); + let mut group = c.benchmark_group("Raw KEM Key Generation"); + group.measurement_time(Duration::from_secs(15)); + + group.bench_function("libcrux ML-KEM-768", |b| { + b.iter(|| { + let _ = libcrux_kem::key_gen(libcrux_kem::Algorithm::MlKem768, &mut rng); + }) + }); + group.bench_function("libcrux X25519", |b| { + b.iter(|| { + let _ = libcrux_kem::key_gen(libcrux_kem::Algorithm::X25519, &mut rng); + }) + }); + group.bench_function("libcrux XWingKemDraft02", |b| { + b.iter(|| { + let _ = libcrux_kem::key_gen(libcrux_kem::Algorithm::XWingKemDraft02, &mut rng); + }) + }); + group.bench_function("classic_mceliece_rust (mceliece460896f)", |b| { + b.iter(|| { + let _ = classic_mceliece_rust::keypair_boxed(&mut rng); + }) + }); +} + +pub fn comparisons_kem_encaps(c: &mut Criterion) { + let mut rng = thread_rng(); + let mut group = c.benchmark_group("Raw KEM Encapsulation"); + group.measurement_time(Duration::from_secs(15)); + + group.bench_function("libcrux ML-KEM-768", |b| { + b.iter_batched( + || libcrux_kem::key_gen(libcrux_kem::Algorithm::MlKem768, &mut rng).unwrap(), + |(_sk, pk)| { + let _ = pk.encapsulate(&mut thread_rng()); + }, + BatchSize::SmallInput, + ) + }); + + group.bench_function("libcrux X25519", |b| { + b.iter_batched( + || libcrux_kem::key_gen(libcrux_kem::Algorithm::X25519, &mut rng).unwrap(), + |(_sk, pk)| { + let _ = pk.encapsulate(&mut thread_rng()); + }, + BatchSize::SmallInput, + ) + }); + + group.bench_function("libcrux XWingKemDraft02", |b| { + b.iter_batched( + || libcrux_kem::key_gen(libcrux_kem::Algorithm::XWingKemDraft02, &mut rng).unwrap(), + |(_sk, pk)| { + let _ = pk.encapsulate(&mut thread_rng()); + }, + BatchSize::SmallInput, + ) + }); + + group.bench_function("classic_mceliece_rust (mceliece460896f)", |b| { + b.iter_batched( + || classic_mceliece_rust::keypair_boxed(&mut rng), + |(pk, _sk)| { + let _ = encapsulate_boxed(&pk, &mut thread_rng()); + }, + BatchSize::SmallInput, + ) + }); +} + +pub fn comparisons_kem_decaps(c: &mut Criterion) { + let mut rng = thread_rng(); + let mut group = c.benchmark_group("Raw KEM Decapsulation"); + group.measurement_time(Duration::from_secs(15)); + + group.bench_function("libcrux ML-KEM-768", |b| { + b.iter_batched( + || { + let (sk, pk) = + libcrux_kem::key_gen(libcrux_kem::Algorithm::MlKem768, &mut rng).unwrap(); + let (_ss, enc) = pk.encapsulate(&mut rng).unwrap(); + (sk, enc) + }, + |(sk, enc)| enc.decapsulate(&sk), + BatchSize::SmallInput, + ) + }); + + group.bench_function("libcrux X25519", |b| { + b.iter_batched( + || { + let (sk, pk) = + libcrux_kem::key_gen(libcrux_kem::Algorithm::X25519, &mut rng).unwrap(); + let (_ss, enc) = pk.encapsulate(&mut rng).unwrap(); + (sk, enc) + }, + |(sk, enc)| enc.decapsulate(&sk), + BatchSize::SmallInput, + ) + }); + + group.bench_function("libcrux XWingKemDraft02", |b| { + b.iter_batched( + || { + let (sk, pk) = + libcrux_kem::key_gen(libcrux_kem::Algorithm::XWingKemDraft02, &mut rng) + .unwrap(); + let (_ss, enc) = pk.encapsulate(&mut rng).unwrap(); + (sk, enc) + }, + |(sk, enc)| enc.decapsulate(&sk), + BatchSize::SmallInput, + ) + }); + + group.bench_function("classic_mceliece_rust (mceliece460896f)", |b| { + b.iter_batched( + || { + let (pk, sk) = classic_mceliece_rust::keypair_boxed(&mut rng); + let (enc, _ss) = encapsulate_boxed(&pk, &mut rng); + (sk, enc) + }, + |(sk, enc)| decapsulate_boxed(&enc, &sk), + BatchSize::SmallInput, + ) + }); +} + +pub fn comparisons_psq_key_generation(c: &mut Criterion) { + let mut rng = thread_rng(); + let mut group = c.benchmark_group("PSK-PQ Key Generation"); + group.measurement_time(Duration::from_secs(15)); + + group.bench_function("libcrux ML-KEM-768", |b| { + b.iter(|| { + let _ = libcrux_psq::generate_key_pair(libcrux_psq::Algorithm::MlKem768, &mut rng); + }) + }); + group.bench_function("libcrux X25519", |b| { + b.iter(|| { + let _ = libcrux_psq::generate_key_pair(libcrux_psq::Algorithm::X25519, &mut rng); + }) + }); + group.bench_function("libcrux XWingKemDraft02", |b| { + b.iter(|| { + let _ = + libcrux_psq::generate_key_pair(libcrux_psq::Algorithm::XWingKemDraft02, &mut rng); + }) + }); + group.bench_function("classic_mceliece_rust (mceliece460896f)", |b| { + b.iter(|| { + let _ = + libcrux_psq::generate_key_pair(libcrux_psq::Algorithm::ClassicMcEliece, &mut rng); + }) + }); +} + +pub fn comparisons_psq_send(c: &mut Criterion) { + let mut rng = thread_rng(); + let mut group = c.benchmark_group("PSK-PQ Pre-Shared Key Send"); + group.measurement_time(Duration::from_secs(15)); + + group.bench_function("libcrux ML-KEM-768", |b| { + b.iter_batched( + || libcrux_psq::generate_key_pair(libcrux_psq::Algorithm::MlKem768, &mut rng).unwrap(), + |(_sk, pk)| { + let _ = pk.send_psk( + b"bench context", + Duration::from_secs(3600), + &mut thread_rng(), + ); + }, + BatchSize::SmallInput, + ) + }); + + group.bench_function("libcrux X25519", |b| { + b.iter_batched( + || libcrux_psq::generate_key_pair(libcrux_psq::Algorithm::X25519, &mut rng).unwrap(), + |(_sk, pk)| { + let _ = pk.send_psk( + b"bench context", + Duration::from_secs(3600), + &mut thread_rng(), + ); + }, + BatchSize::SmallInput, + ) + }); + + group.bench_function("libcrux XWingKemDraft02", |b| { + b.iter_batched( + || { + libcrux_psq::generate_key_pair(libcrux_psq::Algorithm::XWingKemDraft02, &mut rng) + .unwrap() + }, + |(_sk, pk)| { + let _ = pk.send_psk( + b"bench context", + Duration::from_secs(3600), + &mut thread_rng(), + ); + }, + BatchSize::SmallInput, + ) + }); + + group.bench_function("classic_mceliece_rust (mceliece460896f)", |b| { + b.iter_batched( + || { + libcrux_psq::generate_key_pair(libcrux_psq::Algorithm::ClassicMcEliece, &mut rng) + .unwrap() + }, + |(_sk, pk)| { + let _ = pk.send_psk( + b"bench context", + Duration::from_secs(3600), + &mut thread_rng(), + ); + }, + BatchSize::SmallInput, + ) + }); +} + +pub fn comparisons_psq_receive(c: &mut Criterion) { + let mut rng = thread_rng(); + let mut group = c.benchmark_group("PSK-PQ Pre-Shared Key Receive"); + group.measurement_time(Duration::from_secs(15)); + + group.bench_function("libcrux ML-KEM-768", |b| { + b.iter_batched( + || { + let (sk, pk) = + libcrux_psq::generate_key_pair(libcrux_psq::Algorithm::MlKem768, &mut rng) + .unwrap(); + + let (_psk, message) = pk + .send_psk(b"bench context", Duration::from_secs(3600), &mut rng) + .unwrap(); + (pk, sk, message) + }, + |(pk, sk, message)| { + let _ = sk.receive_psk(&pk, &message, b"bench context"); + }, + BatchSize::SmallInput, + ) + }); + + group.bench_function("libcrux X25519", |b| { + b.iter_batched( + || { + let (sk, pk) = + libcrux_psq::generate_key_pair(libcrux_psq::Algorithm::X25519, &mut rng) + .unwrap(); + + let (_psk, message) = pk + .send_psk(b"bench context", Duration::from_secs(3600), &mut rng) + .unwrap(); + (pk, sk, message) + }, + |(pk, sk, message)| { + let _ = sk.receive_psk(&pk, &message, b"bench context"); + }, + BatchSize::SmallInput, + ) + }); + + group.bench_function("libcrux XWingKemDraft02", |b| { + b.iter_batched( + || { + let (sk, pk) = libcrux_psq::generate_key_pair( + libcrux_psq::Algorithm::XWingKemDraft02, + &mut rng, + ) + .unwrap(); + + let (_psk, message) = pk + .send_psk(b"bench context", Duration::from_secs(3600), &mut rng) + .unwrap(); + (pk, sk, message) + }, + |(pk, sk, message)| { + let _ = sk.receive_psk(&pk, &message, b"bench context"); + }, + BatchSize::SmallInput, + ) + }); + + group.bench_function("classic_mceliece_rust (mceliece460896f)", |b| { + b.iter_batched( + || { + let (sk, pk) = libcrux_psq::generate_key_pair( + libcrux_psq::Algorithm::ClassicMcEliece, + &mut rng, + ) + .unwrap(); + + let (_psk, message) = pk + .send_psk(b"bench context", Duration::from_secs(3600), &mut rng) + .unwrap(); + (pk, sk, message) + }, + |(pk, sk, message)| { + let _ = sk.receive_psk(&pk, &message, b"bench context"); + }, + BatchSize::SmallInput, + ) + }); +} + +pub fn comparisons(c: &mut Criterion) { + // Raw KEM operations + comparisons_kem_key_generation(c); + comparisons_kem_encaps(c); + comparisons_kem_decaps(c); + + // PSQ protocol + comparisons_psq_key_generation(c); + comparisons_psq_send(c); + comparisons_psq_receive(c); +} + +criterion_group!(benches, comparisons); +criterion_main!(benches); diff --git a/libcrux-psq/examples/encaps.rs b/libcrux-psq/examples/encaps.rs new file mode 100644 index 000000000..6c26ca3d3 --- /dev/null +++ b/libcrux-psq/examples/encaps.rs @@ -0,0 +1,17 @@ +use std::time::Duration; + +use libcrux_psq::{generate_key_pair, Algorithm}; +use rand::thread_rng; + +fn main() { + let mut rng = thread_rng(); + let mlkem_keypair = generate_key_pair(Algorithm::MlKem768, &mut rng).unwrap(); + + for _ in 0..100_000 { + let _ = core::hint::black_box(mlkem_keypair.1.send_psk( + b"size context", + Duration::from_secs(3600), + &mut rng, + )); + } +} diff --git a/libcrux-psq/examples/sizes.rs b/libcrux-psq/examples/sizes.rs new file mode 100644 index 000000000..b2fbf2e7d --- /dev/null +++ b/libcrux-psq/examples/sizes.rs @@ -0,0 +1,67 @@ +use std::time::Duration; + +use libcrux_psq::*; +use rand::{self, thread_rng}; + +fn main() { + let mut rng = thread_rng(); + let mlkem_keypair = generate_key_pair(Algorithm::MlKem768, &mut rng).unwrap(); + let x25519_keypair = generate_key_pair(Algorithm::X25519, &mut rng).unwrap(); + let xwing_keypair = generate_key_pair(Algorithm::XWingKemDraft02, &mut rng).unwrap(); + let classic_mceliece_keypair = generate_key_pair(Algorithm::ClassicMcEliece, &mut rng).unwrap(); + + let mlkem_message = mlkem_keypair + .1 + .send_psk(b"size context", Duration::from_secs(3600), &mut rng) + .unwrap(); + let x25519_message = x25519_keypair + .1 + .send_psk(b"size context", Duration::from_secs(3600), &mut rng) + .unwrap(); + let xwing_message = xwing_keypair + .1 + .send_psk(b"size context", Duration::from_secs(3600), &mut rng) + .unwrap(); + let classic_mceliece_message = classic_mceliece_keypair + .1 + .send_psk(b"size context", Duration::from_secs(3600), &mut rng) + .unwrap(); + + println!("ML-KEM-768:"); + println!(" Public key size (bytes): {}", mlkem_keypair.1.size()); + println!(" Message size (bytes): {}", mlkem_message.1.size()); + println!( + " including ciphertext size (bytes): {}", + mlkem_message.1.ct_size() + ); + + println!("X25519:"); + println!(" Public key size (bytes): {}", x25519_keypair.1.size()); + println!(" Message size (bytes): {}", x25519_message.1.size()); + println!( + " including ciphertext size (bytes): {}", + x25519_message.1.ct_size() + ); + + println!("XWingKemDraft02:"); + println!(" Public key size (bytes): {}", xwing_keypair.1.size()); + println!(" Message size (bytes): {}", xwing_message.1.size()); + println!( + " including ciphertext size (bytes): {}", + xwing_message.1.ct_size() + ); + + println!("Classic McEliece:"); + println!( + " Public key size (bytes): {}", + classic_mceliece_keypair.1.size() + ); + println!( + " Message size (bytes): {}", + classic_mceliece_message.1.size() + ); + println!( + " including ciphertext size (bytes): {}", + classic_mceliece_message.1.ct_size() + ); +} diff --git a/libcrux-psq/flamegraph.svg b/libcrux-psq/flamegraph.svg new file mode 100644 index 000000000..9a50187c4 --- /dev/null +++ b/libcrux-psq/flamegraph.svg @@ -0,0 +1,491 @@ +Flame Graph Reset ZoomSearch encaps`DYLD-STUB$$memcpy (1 samples, 0.04%)encaps`Hacl_Hash_SHA2_sha256_finish (1 samples, 0.04%)encaps`Hacl_Hash_SHA2_sha256_update_last (1 samples, 0.04%)encaps`Hacl_Hash_SHA2_sha256_update_nblocks (6 samples, 0.22%)encaps`sha256_update (1,169 samples, 42.65%)encaps`sha256_updatelibsystem_c.dylib`__memcpy_chk (2 samples, 0.07%)encaps`Hacl_HMAC_compute_sha2_256 (1,184 samples, 43.20%)encaps`Hacl_HMAC_compute_sha2_256libsystem_platform.dylib`_platform_memmove (1 samples, 0.04%)encaps`Hacl_Hash_SHA2_sha256_update_nblocks (1 samples, 0.04%)libsystem_c.dylib`DYLD-STUB$$mkdtempat_np (1 samples, 0.04%)libsystem_platform.dylib`_platform_memmove (1 samples, 0.04%)encaps`Hacl_HKDF_expand_sha2_256 (1,193 samples, 43.52%)encaps`Hacl_HKDF_expand_sha2_256libsystem_pthread.dylib`___chkstk_darwin (4 samples, 0.15%)encaps`Hacl_Hash_SHA2_sha256_finish (1 samples, 0.04%)encaps`sha256_update (91 samples, 3.32%)enc..libsystem_c.dylib`__memcpy_chk (1 samples, 0.04%)encaps`Hacl_HMAC_compute_sha2_256 (94 samples, 3.43%)enc..libsystem_platform.dylib`_platform_memmove (1 samples, 0.04%)libsystem_malloc.dylib`_nanov2_free (1 samples, 0.04%)libsystem_malloc.dylib`nanov2_malloc (1 samples, 0.04%)libsystem_malloc.dylib`nanov2_realloc (1 samples, 0.04%)libsystem_malloc.dylib`_nanov2_free (1 samples, 0.04%)libsystem_malloc.dylib`szone_realloc (2 samples, 0.07%)libsystem_malloc.dylib`szone_malloc_should_clear (1 samples, 0.04%)libsystem_malloc.dylib`small_malloc_should_clear (1 samples, 0.04%)libsystem_malloc.dylib`_malloc_zone_realloc (8 samples, 0.29%)libsystem_platform.dylib`_platform_memmove (3 samples, 0.11%)libsystem_malloc.dylib`default_zone_realloc (1 samples, 0.04%)libsystem_malloc.dylib`nanov2_realloc (1 samples, 0.04%)encaps`alloc::raw_vec::RawVec<T,A>::reserve::do_reserve_and_handle (11 samples, 0.40%)encaps`alloc::raw_vec::finish_grow (11 samples, 0.40%)libsystem_malloc.dylib`_realloc (11 samples, 0.40%)libsystem_malloc.dylib`szone_size (1 samples, 0.04%)libsystem_malloc.dylib`tiny_size (1 samples, 0.04%)libsystem_malloc.dylib`small_malloc_should_clear (2 samples, 0.07%)encaps`libcrux_kem::Ct::encode (4 samples, 0.15%)libsystem_malloc.dylib`szone_malloc_should_clear (2 samples, 0.07%)libsystem_malloc.dylib`small_malloc_should_clear (2 samples, 0.07%)libsystem_malloc.dylib`small_malloc_from_free_list (1 samples, 0.04%)libsystem_malloc.dylib`small_free_list_remove_ptr_no_clear (1 samples, 0.04%)encaps`<rand_chacha::chacha::ChaCha12Core as rand_core::block::BlockRngCore>::generate (12 samples, 0.44%)encaps`DYLD-STUB$$memcpy (1 samples, 0.04%)encaps`libcrux_ml_kem::ind_cpa::encrypt (1,058 samples, 38.60%)encaps`libcrux_ml_kem::ind_cpa::encryptlibsystem_platform.dylib`_platform_memmove (31 samples, 1.13%)encaps`libcrux_ml_kem::mlkem768::encapsulate (1,365 samples, 49.80%)encaps`libcrux_ml_kem::mlkem768::encapsulatelibsystem_platform.dylib`_platform_memset (21 samples, 0.77%)encaps`libcrux_kem::PublicKey::encapsulate (1,380 samples, 50.35%)encaps`libcrux_kem::PublicKey::encapsulatelibsystem_platform.dylib`_platform_memmove (2 samples, 0.07%)encaps`libcrux_kem::Ss::encode (1 samples, 0.04%)encaps`libcrux_ml_kem::mlkem768::encapsulate (2 samples, 0.07%)libsystem_c.dylib`clock_gettime (5 samples, 0.18%)libsystem_c.dylib`gettimeofday (5 samples, 0.18%)libsystem_kernel.dylib`mach_absolute_time (5 samples, 0.18%)libsystem_malloc.dylib`_malloc_zone_malloc (2 samples, 0.07%)libsystem_malloc.dylib`_nanov2_free (2 samples, 0.07%)libsystem_malloc.dylib`_szone_free (1 samples, 0.04%)libsystem_malloc.dylib`free_small (1 samples, 0.04%)libsystem_malloc.dylib`nanov2_calloc (1 samples, 0.04%)libsystem_platform.dylib`__bzero (1 samples, 0.04%)libsystem_platform.dylib`_platform_memmove (7 samples, 0.26%)libsystem_platform.dylib`_platform_memset (4 samples, 0.15%)encaps`encaps::main (2,716 samples, 99.09%)encaps`encaps::mainlibsystem_pthread.dylib`___chkstk_darwin (2 samples, 0.07%)libsystem_malloc.dylib`_free (1 samples, 0.04%)dyld`start (2,740 samples, 99.96%)dyld`startencaps`main (2,740 samples, 99.96%)encaps`mainencaps`std::sys_common::backtrace::__rust_begin_short_backtrace (2,740 samples, 99.96%)encaps`std::sys_common::backtrace::__rust_begin_short_backtracelibsystem_platform.dylib`_platform_memmove (23 samples, 0.84%)all (2,741 samples, 100%)libsystem_kernel.dylib`__exit (1 samples, 0.04%) \ No newline at end of file diff --git a/libcrux-psq/src/psq.rs b/libcrux-psq/src/psq.rs new file mode 100644 index 000000000..cedb78f80 --- /dev/null +++ b/libcrux-psq/src/psq.rs @@ -0,0 +1,492 @@ +//! # PQ-PSK establishment protocol +//! +//! This crate implements a post-quantum (PQ) pre-shared key (PSK) establishment +//! protocol. + +#![deny(missing_docs)] +use std::time::{Duration, SystemTime}; + +use classic_mceliece_rust::{decapsulate_boxed, encapsulate_boxed}; +use libcrux_hmac::hmac; +use rand::{CryptoRng, Rng}; + +const PSK_LENGTH: usize = 32; +const K0_LENGTH: usize = 32; +const KM_LENGTH: usize = 32; +const MAC_LENGTH: usize = 32; + +const CONFIRMATION_CONTEXT: &[u8] = b"Confirmation"; +const PSK_CONTEXT: &[u8] = b"PSK"; + +type Psk = [u8; PSK_LENGTH]; +type Mac = [u8; MAC_LENGTH]; + +#[derive(Debug)] +/// PSQ Errors. +pub enum Error { + /// An invalid public key was provided + InvalidPublicKey, + /// An invalid private key was provided + InvalidPrivateKey, + /// An error during PSK encapsulation + GenerationError, + /// An error during PSK decapsulation + DerivationError, +} + +/// The algorithm that should be used for the internal KEM. +pub enum Algorithm { + /// An elliptic-curve Diffie-Hellman based KEM (Does not provide post-quantum security) + X25519, + /// ML-KEM 768, a lattice-based post-quantum KEM, as specified in FIPS 203 (Draft) + MlKem768, + /// A code-based post-quantum KEM & Round 4 candidate in the NIST PQ competition (Parameter Set `mceliece460896f`) + ClassicMcEliece, + /// A hybrid post-quantum KEM combining X25519 and ML-KEM 768 + XWingKemDraft02, +} + +enum Ciphertext { + X25519(libcrux_kem::Ct), + MlKem768(libcrux_kem::Ct), + XWingKemDraft02(libcrux_kem::Ct), + ClassicMcEliece(classic_mceliece_rust::Ciphertext), +} + +/// A PSQ public key +pub enum PublicKey<'a> { + /// for use with X25519-based protocol + X25519(libcrux_kem::PublicKey), + /// for use with ML-KEM-768-based protocol + MlKem768(libcrux_kem::PublicKey), + /// for use with hybrid KEM XWingDraft02-based protocol + XWingKemDraft02(libcrux_kem::PublicKey), + /// for use with Classic McEliece-based protocol + ClassicMcEliece(classic_mceliece_rust::PublicKey<'a>), +} + +/// A PSQ private key +pub enum PrivateKey<'a> { + /// for use with X25519-based protocol + X25519(libcrux_kem::PrivateKey), + /// for use with ML-KEM-768-based protocol + MlKem768(libcrux_kem::PrivateKey), + /// for use with hybrid KEM XWingDraft02-based protocol + XWingKemDraft02(libcrux_kem::PrivateKey), + /// for use with Classic McEliece-based protocol + ClassicMcEliece(classic_mceliece_rust::SecretKey<'a>), +} + +enum SharedSecret<'a> { + X25519(libcrux_kem::Ss), + MlKem768(libcrux_kem::Ss), + XWingKemDraft02(libcrux_kem::Ss), + ClassicMcEliece(classic_mceliece_rust::SharedSecret<'a>), +} + +impl SharedSecret<'_> { + fn encode(&self) -> Vec { + match self { + SharedSecret::X25519(ss) => ss.encode(), + SharedSecret::MlKem768(ss) => ss.encode(), + SharedSecret::ClassicMcEliece(ss) => ss.as_ref().to_owned(), + SharedSecret::XWingKemDraft02(ss) => ss.encode(), + } + } +} + +impl Ciphertext { + fn encode(&self) -> Vec { + match self { + Ciphertext::X25519(ct) => ct.encode(), + Ciphertext::MlKem768(ct) => ct.encode(), + Ciphertext::ClassicMcEliece(ct) => ct.as_ref().to_owned(), + Ciphertext::XWingKemDraft02(ct) => ct.encode(), + } + } + fn decapsulate(&self, sk: &PrivateKey) -> Result { + match self { + Ciphertext::X25519(ct) => { + if let PrivateKey::X25519(sk) = sk { + let ss = ct.decapsulate(sk).unwrap(); + Ok(SharedSecret::X25519(ss)) + } else { + Err(Error::InvalidPrivateKey) + } + } + Ciphertext::MlKem768(ct) => { + if let PrivateKey::MlKem768(sk) = sk { + let ss = ct.decapsulate(sk).unwrap(); + Ok(SharedSecret::MlKem768(ss)) + } else { + Err(Error::InvalidPrivateKey) + } + } + Ciphertext::ClassicMcEliece(ct) => { + if let PrivateKey::ClassicMcEliece(sk) = sk { + let ss = decapsulate_boxed(ct, sk); + Ok(SharedSecret::ClassicMcEliece(ss)) + } else { + Err(Error::InvalidPrivateKey) + } + } + Ciphertext::XWingKemDraft02(ct) => { + if let PrivateKey::XWingKemDraft02(sk) = sk { + let ss = ct.decapsulate(sk).unwrap(); + Ok(SharedSecret::XWingKemDraft02(ss)) + } else { + Err(Error::InvalidPrivateKey) + } + } + } + } +} + +impl From for libcrux_kem::Algorithm { + fn from(val: Algorithm) -> Self { + match val { + Algorithm::X25519 => libcrux_kem::Algorithm::X25519, + Algorithm::MlKem768 => libcrux_kem::Algorithm::MlKem768, + Algorithm::ClassicMcEliece => { + unimplemented!("libcrux does not support Classic McEliece") + } + Algorithm::XWingKemDraft02 => libcrux_kem::Algorithm::XWingKemDraft02, + } + } +} + +/// Generate a PSQ key pair. +pub fn generate_key_pair( + alg: Algorithm, + rng: &mut (impl CryptoRng + Rng), +) -> Result<(PrivateKey<'static>, PublicKey<'static>), Error> { + match alg { + Algorithm::X25519 => { + let (sk, pk) = libcrux_kem::key_gen(alg.into(), rng).unwrap(); + Ok((PrivateKey::X25519(sk), PublicKey::X25519(pk))) + } + Algorithm::MlKem768 => { + let (sk, pk) = libcrux_kem::key_gen(alg.into(), rng).unwrap(); + Ok((PrivateKey::MlKem768(sk), PublicKey::MlKem768(pk))) + } + Algorithm::ClassicMcEliece => { + let (pk, sk) = classic_mceliece_rust::keypair_boxed(rng); + Ok(( + PrivateKey::ClassicMcEliece(sk), + PublicKey::ClassicMcEliece(pk), + )) + } + Algorithm::XWingKemDraft02 => { + let (sk, pk) = libcrux_kem::key_gen(alg.into(), rng).unwrap(); + Ok(( + PrivateKey::XWingKemDraft02(sk), + PublicKey::XWingKemDraft02(pk), + )) + } + } +} + +impl PublicKey<'_> { + /// Return the size (in bytes) of the PSQ public key. + pub fn size(&self) -> usize { + self.encode().len() + } + pub(crate) fn encode(&self) -> Vec { + match self { + PublicKey::X25519(k) => k.encode(), + PublicKey::MlKem768(k) => k.encode(), + PublicKey::XWingKemDraft02(k) => k.encode(), + PublicKey::ClassicMcEliece(k) => k.as_ref().to_vec(), + } + } + + /// Use the underlying KEM to encapsulate a shared secret towards the receiver. + pub(crate) fn encapsulate( + &self, + rng: &mut (impl CryptoRng + Rng), + ) -> Result<(SharedSecret, Ciphertext), Error> { + match self { + PublicKey::X25519(pk) => { + let (ss, enc) = pk.encapsulate(rng).unwrap(); + Ok((SharedSecret::X25519(ss), Ciphertext::X25519(enc))) + } + PublicKey::MlKem768(pk) => { + let (ss, enc) = pk.encapsulate(rng).unwrap(); + Ok((SharedSecret::MlKem768(ss), Ciphertext::MlKem768(enc))) + } + PublicKey::ClassicMcEliece(pk) => { + let (enc, ss) = encapsulate_boxed(pk, rng); + Ok(( + SharedSecret::ClassicMcEliece(ss), + Ciphertext::ClassicMcEliece(enc), + )) + } + PublicKey::XWingKemDraft02(pk) => { + let (ss, enc) = pk.encapsulate(rng).unwrap(); + Ok(( + SharedSecret::XWingKemDraft02(ss), + Ciphertext::XWingKemDraft02(enc), + )) + } + } + } + + /// Generate a fresh PSK, and a message encapsulating it for the + /// receiver. + /// + /// The encapsulated PSK is valid for the given duration + /// `psk_ttl`, based on milliseconds since the UNIX epoch until + /// current system time. Parameter `sctx` is used to + /// cryptographically bind the generated PSK to a given outer + /// protocol context and may be considered public. + pub fn send_psk( + &self, + sctx: &[u8], + psk_ttl: Duration, + rng: &mut (impl CryptoRng + Rng), + ) -> Result<(Psk, PskMessage), Error> { + let (ik, enc) = self.encapsulate(rng).map_err(|_| Error::GenerationError)?; + let mut info = self.encode(); + info.extend_from_slice(&enc.encode()); + info.extend_from_slice(sctx); + + let k0 = libcrux_hkdf::expand( + libcrux_hkdf::Algorithm::Sha256, + ik.encode(), + info, + K0_LENGTH, + ) + .map_err(|_| Error::GenerationError)?; + + let km = libcrux_hkdf::expand( + libcrux_hkdf::Algorithm::Sha256, + &k0, + CONFIRMATION_CONTEXT, + KM_LENGTH, + ) + .map_err(|_| Error::GenerationError)?; + + let psk: Psk = libcrux_hkdf::expand( + libcrux_hkdf::Algorithm::Sha256, + &k0, + PSK_CONTEXT, + PSK_LENGTH, + ) + .map_err(|_| Error::GenerationError)? + .try_into() + .expect("should receive the correct number of bytes from HKDF"); + + let now = SystemTime::now(); + let ts = now.duration_since(SystemTime::UNIX_EPOCH).unwrap(); + let ts_seconds = ts.as_secs(); + let ts_subsec_millis = ts.subsec_millis(); + let mut mac_input = ts_seconds.to_be_bytes().to_vec(); + mac_input.extend_from_slice(&ts_subsec_millis.to_be_bytes()); + mac_input.extend_from_slice(&psk_ttl.as_millis().to_be_bytes()); + + let mac: Mac = hmac( + libcrux_hmac::Algorithm::Sha256, + &km, + &mac_input, + Some(MAC_LENGTH), + ) + .try_into() + .expect("should receive the correct number of bytes from HMAC"); + + Ok(( + psk, + PskMessage { + enc, + ts: (ts_seconds, ts_subsec_millis), + psk_ttl, + mac, + }, + )) + } +} + +impl PrivateKey<'_> { + /// Derive a PSK from a PSQ message. + /// + /// Can error, if the given PSQ message is invalid, i.e. beyond + /// its TTL or cryptographically invalid. + pub fn receive_psk( + &self, + pk: &PublicKey, + message: &PskMessage, + sctx: &[u8], + ) -> Result { + let PskMessage { + enc, + ts: (ts_seconds, ts_subsec_millis), + psk_ttl, + mac, + } = message; + + let now = SystemTime::now(); + let ts_since_epoch = + Duration::from_secs(*ts_seconds) + Duration::from_millis((*ts_subsec_millis).into()); + if now.duration_since(SystemTime::UNIX_EPOCH).unwrap() - ts_since_epoch >= *psk_ttl { + Err(Error::DerivationError) + } else { + let ik = enc.decapsulate(self).map_err(|_| Error::DerivationError)?; + + let mut info = pk.encode(); + info.extend_from_slice(&enc.encode()); + info.extend_from_slice(sctx); + + let k0 = libcrux_hkdf::expand( + libcrux_hkdf::Algorithm::Sha256, + ik.encode(), + info, + K0_LENGTH, + ) + .map_err(|_| Error::DerivationError)?; + + let km = libcrux_hkdf::expand( + libcrux_hkdf::Algorithm::Sha256, + &k0, + CONFIRMATION_CONTEXT, + KM_LENGTH, + ) + .map_err(|_| Error::DerivationError)?; + + let mut mac_input = ts_seconds.to_be_bytes().to_vec(); + mac_input.extend_from_slice(&ts_subsec_millis.to_be_bytes()); + mac_input.extend_from_slice(&psk_ttl.as_millis().to_be_bytes()); + + let recomputed_mac: Mac = hmac( + libcrux_hmac::Algorithm::Sha256, + &km, + &mac_input, + Some(MAC_LENGTH), + ) + .try_into() + .expect("should receive the correct number of bytes from HMAC"); + + if recomputed_mac != *mac { + Err(Error::DerivationError) + } else { + let psk: Psk = libcrux_hkdf::expand( + libcrux_hkdf::Algorithm::Sha256, + &k0, + PSK_CONTEXT, + PSK_LENGTH, + ) + .map_err(|_| Error::DerivationError)? + .try_into() + .expect("should receive the correct number of bytes from HKDF"); + + Ok(psk) + } + } + } +} + +/// A message that encapsulates as post-quantum PSK of a certain +/// lifetime, tied to a specific outer protocol context. +pub struct PskMessage { + enc: Ciphertext, + ts: (u64, u32), + psk_ttl: Duration, + mac: Mac, +} + +impl PskMessage { + /// Returns the size (in bytes) of the ciphertext enclosed in the message. + pub fn ct_size(&self) -> usize { + self.enc.encode().len() + } + /// Returns the total size (in bytes) of the message. + pub fn size(&self) -> usize { + self.ct_size() + + MAC_LENGTH // self.mac.len() + + 8 // self.ts.to_be_bytes().len() + + 8 // self.psk_ttl.num_milliseconds().to_be_bytes().len() + } +} + +#[cfg(test)] +mod tests { + use std::thread::sleep; + + use super::*; + + #[test] + fn simple_x25519() { + let mut rng = rand::thread_rng(); + let (sk, pk) = generate_key_pair(Algorithm::X25519, &mut rng).unwrap(); + let sctx = b"test context"; + let (psk_initiator, message) = pk + .send_psk(sctx, Duration::from_secs(2 * 3600), &mut rng) + .unwrap(); + + let psk_responder = sk.receive_psk(&pk, &message, sctx).unwrap(); + assert_eq!(psk_initiator, psk_responder); + } + + #[test] + #[should_panic] + fn zero_ttl() { + let mut rng = rand::thread_rng(); + let (sk, pk) = generate_key_pair(Algorithm::X25519, &mut rng).unwrap(); + let sctx = b"test context"; + let (_psk_initiator, message) = + pk.send_psk(sctx, Duration::from_secs(0), &mut rng).unwrap(); + + let _psk_responder = sk.receive_psk(&pk, &message, sctx).unwrap(); + } + + #[test] + #[should_panic] + fn expired_timestamp() { + let mut rng = rand::thread_rng(); + let (sk, pk) = generate_key_pair(Algorithm::X25519, &mut rng).unwrap(); + let sctx = b"test context"; + let (_psk_initiator, message) = + pk.send_psk(sctx, Duration::from_secs(1), &mut rng).unwrap(); + + sleep(Duration::from_secs(2)); + + let _psk_responder = sk.receive_psk(&pk, &message, sctx).unwrap(); + } + + #[test] + fn simple_mlkem768() { + let mut rng = rand::thread_rng(); + let (sk, pk) = generate_key_pair(Algorithm::MlKem768, &mut rng).unwrap(); + let sctx = b"test context"; + let (psk_initiator, message) = pk + .send_psk(sctx, Duration::from_secs(2 * 3600), &mut rng) + .unwrap(); + + let psk_responder = sk.receive_psk(&pk, &message, sctx).unwrap(); + assert_eq!(psk_initiator, psk_responder); + } + + #[test] + fn simple_xwing() { + let mut rng = rand::thread_rng(); + let (sk, pk) = generate_key_pair(Algorithm::XWingKemDraft02, &mut rng).unwrap(); + let sctx = b"test context"; + let (psk_initiator, message) = pk + .send_psk(sctx, Duration::from_secs(2 * 3600), &mut rng) + .unwrap(); + + let psk_responder = sk.receive_psk(&pk, &message, sctx).unwrap(); + assert_eq!(psk_initiator, psk_responder); + } + + #[test] + fn simple_classic_mceliece() { + let mut rng = rand::thread_rng(); + let (sk, pk) = generate_key_pair(Algorithm::ClassicMcEliece, &mut rng).unwrap(); + let sctx = b"test context"; + let (psk_initiator, message) = pk + .send_psk(sctx, Duration::from_secs(2 * 3600), &mut rng) + .unwrap(); + + let psk_responder = sk.receive_psk(&pk, &message, sctx).unwrap(); + assert_eq!(psk_initiator, psk_responder); + } +} diff --git a/libcrux-sha3/src/lib.rs b/libcrux-sha3/src/lib.rs index 5ec1e2605..ae6d2aa10 100644 --- a/libcrux-sha3/src/lib.rs +++ b/libcrux-sha3/src/lib.rs @@ -288,7 +288,7 @@ pub mod neon { #[inline(always)] pub fn sha224(digest: &mut [u8], data: &[u8]) { #[cfg(not(feature = "simd128"))] - unimplemented!("The target architecture does not support neon instructions."); + unimplemented!(); #[cfg(feature = "simd128")] { let mut dummy = [0u8; 28]; @@ -301,7 +301,7 @@ pub mod neon { #[inline(always)] pub fn sha256(digest: &mut [u8], data: &[u8]) { #[cfg(not(feature = "simd128"))] - unimplemented!("The target architecture does not support neon instructions."); + unimplemented!(); #[cfg(feature = "simd128")] { let mut dummy = [0u8; 32]; @@ -314,7 +314,7 @@ pub mod neon { #[inline(always)] pub fn sha384(digest: &mut [u8], data: &[u8]) { #[cfg(not(feature = "simd128"))] - unimplemented!("The target architecture does not support neon instructions."); + unimplemented!(); #[cfg(feature = "simd128")] { let mut dummy = [0u8; 48]; @@ -327,7 +327,7 @@ pub mod neon { #[inline(always)] pub fn sha512(digest: &mut [u8], data: &[u8]) { #[cfg(not(feature = "simd128"))] - unimplemented!("The target architecture does not support neon instructions."); + unimplemented!(); #[cfg(feature = "simd128")] { let mut dummy = [0u8; 64]; @@ -340,7 +340,7 @@ pub mod neon { #[inline(always)] pub fn shake128(digest: &mut [u8; LEN], data: &[u8]) { #[cfg(not(feature = "simd128"))] - unimplemented!("The target architecture does not support neon instructions."); + unimplemented!(); #[cfg(feature = "simd128")] { let mut dummy = [0u8; LEN]; @@ -353,7 +353,7 @@ pub mod neon { #[inline(always)] pub fn shake256(digest: &mut [u8; LEN], data: &[u8]) { #[cfg(not(feature = "simd128"))] - unimplemented!("The target architecture does not support neon instructions."); + unimplemented!(); #[cfg(feature = "simd128")] { let mut dummy = [0u8; LEN]; @@ -374,7 +374,7 @@ pub mod neon { pub fn shake256(input0: &[u8], input1: &[u8], out0: &mut [u8], out1: &mut [u8]) { // TODO: make argument ordering consistent #[cfg(not(feature = "simd128"))] - unimplemented!("The target architecture does not support neon instructions."); + unimplemented!(); #[cfg(feature = "simd128")] keccakx2::<136, 0x1fu8>([input0, input1], [out0, out1]); } @@ -435,7 +435,7 @@ pub mod neon { #[inline(always)] pub fn shake128_init() -> KeccakState2 { #[cfg(not(feature = "simd128"))] - unimplemented!("The target architecture does not support neon instructions."); + unimplemented!(); // XXX: These functions could alternatively implement the same with // the portable implementation // { @@ -453,7 +453,7 @@ pub mod neon { #[allow(unused_variables)] pub fn shake128_absorb_final(s: &mut KeccakState2, data0: &[u8], data1: &[u8]) { #[cfg(not(feature = "simd128"))] - unimplemented!("The target architecture does not support neon instructions."); + unimplemented!(); // XXX: These functions could alternatively implement the same with // the portable implementation // { @@ -504,7 +504,7 @@ pub mod neon { out1: &mut [u8], ) { #[cfg(not(feature = "simd128"))] - unimplemented!("The target architecture does not support neon instructions."); + unimplemented!(); // XXX: These functions could alternatively implement the same with // the portable implementation // { @@ -583,7 +583,7 @@ pub mod neon { out1: &mut [u8], ) { #[cfg(not(feature = "simd128"))] - unimplemented!("The target architecture does not support neon instructions."); + unimplemented!(); // XXX: These functions could alternatively implement the same with // the portable implementation // { @@ -679,7 +679,7 @@ pub mod avx2 { out3: &mut [u8], ) { #[cfg(not(feature = "simd256"))] - unimplemented!("The target architecture does not support neon instructions."); + unimplemented!(); // XXX: These functions could alternatively implement the same with // the portable implementation // #[cfg(feature = "simd128")] @@ -785,7 +785,7 @@ pub mod avx2 { #[inline(always)] pub fn shake128_init() -> KeccakState4 { #[cfg(not(feature = "simd256"))] - unimplemented!("The target architecture does not support neon instructions."); + unimplemented!(); // XXX: These functions could alternatively implement the same with // the portable implementation // #[cfg(feature = "simd128")] @@ -818,7 +818,7 @@ pub mod avx2 { data3: &[u8], ) { #[cfg(not(feature = "simd256"))] - unimplemented!("The target architecture does not support neon instructions."); + unimplemented!(); // XXX: These functions could alternatively implement the same with // the portable implementation // #[cfg(feature = "simd128")] @@ -887,7 +887,7 @@ pub mod avx2 { out3: &mut [u8], ) { #[cfg(not(feature = "simd256"))] - unimplemented!("The target architecture does not support neon instructions."); + unimplemented!(); // XXX: These functions could alternatively implement the same with // the portable implementation // #[cfg(feature = "simd128")] @@ -981,7 +981,7 @@ pub mod avx2 { out3: &mut [u8], ) { #[cfg(not(feature = "simd256"))] - unimplemented!("The target architecture does not support neon instructions."); + unimplemented!(); // XXX: These functions could alternatively implement the same with // the portable implementation // #[cfg(feature = "simd128")]