Add experimental support for hybrid post-quantum key exchange
authordjm <djm@openbsd.org>
Mon, 2 Sep 2024 12:13:56 +0000 (12:13 +0000)
committerdjm <djm@openbsd.org>
Mon, 2 Sep 2024 12:13:56 +0000 (12:13 +0000)
ML-KEM768 with ECDH/X25519 from the Internet-draft:
https://datatracker.ietf.org/doc/html/draft-kampanakis-curdle-ssh-pq-ke-03

This is based on previous patches from markus@ but adapted to use the
final FIPS203 standard ML-KEM using a formally-verified implementation
from libcrux.

Note this key exchange method is still a draft and thus subject to
change. It is therefore disabled by default; set MLKEM=yes to build it.
We're making it available now to make it easy for other SSH
implementations to test against it.

ok markus@ deraadt@

14 files changed:
usr.bin/ssh/Makefile.inc
usr.bin/ssh/crypto_api.h
usr.bin/ssh/kex-names.c
usr.bin/ssh/kex.h
usr.bin/ssh/kexc25519.c
usr.bin/ssh/kexgen.c
usr.bin/ssh/kexmlkem768x25519.c [new file with mode: 0644]
usr.bin/ssh/libcrux_mlkem768_sha3.h [new file with mode: 0644]
usr.bin/ssh/mlkem768.sh [new file with mode: 0755]
usr.bin/ssh/monitor.c
usr.bin/ssh/ssh-keyscan.c
usr.bin/ssh/ssh_api.c
usr.bin/ssh/sshconnect2.c
usr.bin/ssh/sshd-session.c

index bd7697d..4b7b302 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: Makefile.inc,v 1.94 2024/06/17 08:30:29 djm Exp $
+#      $OpenBSD: Makefile.inc,v 1.95 2024/09/02 12:13:56 djm Exp $
 
 .include <bsd.own.mk>
 
@@ -38,6 +38,8 @@ WARNINGS=yes
 OPENSSL?=      yes
 ZLIB?=         yes
 DSAKEY?=       no
+# NB. experimental; Internet-draft subject to change.
+MLKEM?=                no
 
 .if (${OPENSSL:L} == "yes")
 CFLAGS+=       -DWITH_OPENSSL
@@ -51,6 +53,10 @@ CFLAGS+=     -DWITH_ZLIB
 CFLAGS+=       -DWITH_DSA
 .endif
 
+.if (${MLKEM:L} == "yes")
+CFLAGS+=       -DWITH_MLKEM
+.endif
+
 CFLAGS+=       -DENABLE_PKCS11
 .ifndef NOPIC
 CFLAGS+=       -DHAVE_DLOPEN
@@ -80,6 +86,9 @@ SRCS_KEX+=    smult_curve25519_ref.c
 SRCS_KEX+=     kexgen.c
 SRCS_KEX+=     kexsntrup761x25519.c
 SRCS_KEX+=     sntrup761.c
+.if (${MLKEM:L} == "yes")
+SRCS_KEX+=     kexmlkem768x25519.c
+.endif
 
 SRCS_KEY+=     sshkey.c
 SRCS_KEY+=     cipher.c
index 5f427aa..2cedfac 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: crypto_api.h,v 1.8 2023/01/15 23:05:32 djm Exp $ */
+/* $OpenBSD: crypto_api.h,v 1.9 2024/09/02 12:13:56 djm Exp $ */
 
 /*
  * Assembled from generated headers and source files by Markus Friedl.
@@ -49,4 +49,9 @@ int   crypto_kem_sntrup761_dec(unsigned char *k,
     const unsigned char *cstr, const unsigned char *sk);
 int    crypto_kem_sntrup761_keypair(unsigned char *pk, unsigned char *sk);
 
+#define crypto_kem_mlkem768_PUBLICKEYBYTES 1184
+#define crypto_kem_mlkem768_SECRETKEYBYTES 2400
+#define crypto_kem_mlkem768_CIPHERTEXTBYTES 1088
+#define crypto_kem_mlkem768_BYTES 32
+
 #endif /* crypto_api_h */
index 82ff373..cb21819 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex-names.c,v 1.2 2024/08/22 23:11:30 djm Exp $ */
+/* $OpenBSD: kex-names.c,v 1.3 2024/09/02 12:13:56 djm Exp $ */
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
  *
@@ -72,6 +72,10 @@ static const struct kexalg kexalgs[] = {
            SSH_DIGEST_SHA512 },
        { KEX_SNTRUP761X25519_SHA512_OLD, KEX_KEM_SNTRUP761X25519_SHA512, 0,
            SSH_DIGEST_SHA512 },
+#ifdef WITH_MLKEM
+       { KEX_MLKEM768X25519_SHA256, KEX_KEM_MLKEM768X25519_SHA256, 0,
+           SSH_DIGEST_SHA256 },
+#endif
        { NULL, 0, -1, -1},
 };
 
index 19f6f78..e11ea86 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.h,v 1.125 2024/08/23 04:51:00 deraadt Exp $ */
+/* $OpenBSD: kex.h,v 1.126 2024/09/02 12:13:56 djm Exp $ */
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
@@ -57,6 +57,7 @@
 #define        KEX_CURVE25519_SHA256_OLD       "curve25519-sha256@libssh.org"
 #define        KEX_SNTRUP761X25519_SHA512      "sntrup761x25519-sha512"
 #define        KEX_SNTRUP761X25519_SHA512_OLD  "sntrup761x25519-sha512@openssh.com"
+#define        KEX_MLKEM768X25519_SHA256       "mlkem768x25519-sha256"
 
 #define COMP_NONE      0
 #define COMP_DELAYED   2
@@ -94,6 +95,7 @@ enum kex_exchange {
        KEX_ECDH_SHA2,
        KEX_C25519_SHA256,
        KEX_KEM_SNTRUP761X25519_SHA512,
+       KEX_KEM_MLKEM768X25519_SHA256,
        KEX_MAX
 };
 
@@ -172,6 +174,7 @@ struct kex {
        u_char c25519_client_key[CURVE25519_SIZE]; /* 25519 + KEM */
        u_char c25519_client_pubkey[CURVE25519_SIZE]; /* 25519 */
        u_char sntrup761_client_key[crypto_kem_sntrup761_SECRETKEYBYTES]; /* KEM */
+       u_char mlkem768_client_key[crypto_kem_mlkem768_SECRETKEYBYTES]; /* KEM */
        struct sshbuf *client_pub;
 };
 
@@ -238,6 +241,12 @@ int         kex_kem_sntrup761x25519_enc(struct kex *, const struct sshbuf *,
 int     kex_kem_sntrup761x25519_dec(struct kex *, const struct sshbuf *,
     struct sshbuf **);
 
+int     kex_kem_mlkem768x25519_keypair(struct kex *);
+int     kex_kem_mlkem768x25519_enc(struct kex *, const struct sshbuf *,
+    struct sshbuf **, struct sshbuf **);
+int     kex_kem_mlkem768x25519_dec(struct kex *, const struct sshbuf *,
+    struct sshbuf **);
+
 int     kex_dh_keygen(struct kex *);
 int     kex_dh_compute_key(struct kex *, BIGNUM *, struct sshbuf *);
 
index 7835a80..0e71bec 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexc25519.c,v 1.17 2019/01/21 10:40:11 djm Exp $ */
+/* $OpenBSD: kexc25519.c,v 1.18 2024/09/02 12:13:56 djm Exp $ */
 /*
  * Copyright (c) 2019 Markus Friedl.  All rights reserved.
  * Copyright (c) 2010 Damien Miller.  All rights reserved.
@@ -69,7 +69,7 @@ kexc25519_shared_key_ext(const u_char key[CURVE25519_SIZE],
                return SSH_ERR_KEY_INVALID_EC_VALUE;
 
 #ifdef DEBUG_KEXECDH
-       dump_digest("shared secret", shared_key, CURVE25519_SIZE);
+       dump_digest("shared secret 25519", shared_key, CURVE25519_SIZE);
 #endif
        if (raw)
                r = sshbuf_put(out, shared_key, CURVE25519_SIZE);
index e7534f5..7968897 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexgen.c,v 1.8 2021/12/19 22:08:06 djm Exp $ */
+/* $OpenBSD: kexgen.c,v 1.9 2024/09/02 12:13:56 djm Exp $ */
 /*
  * Copyright (c) 2019 Markus Friedl.  All rights reserved.
  *
@@ -117,6 +117,11 @@ kex_gen_client(struct ssh *ssh)
        case KEX_KEM_SNTRUP761X25519_SHA512:
                r = kex_kem_sntrup761x25519_keypair(kex);
                break;
+#ifdef WITH_MLKEM
+       case KEX_KEM_MLKEM768X25519_SHA256:
+               r = kex_kem_mlkem768x25519_keypair(kex);
+               break;
+#endif
        default:
                r = SSH_ERR_INVALID_ARGUMENT;
                break;
@@ -189,6 +194,12 @@ input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh)
                r = kex_kem_sntrup761x25519_dec(kex, server_blob,
                    &shared_secret);
                break;
+#ifdef WITH_MLKEM
+       case KEX_KEM_MLKEM768X25519_SHA256:
+               r = kex_kem_mlkem768x25519_dec(kex, server_blob,
+                   &shared_secret);
+               break;
+#endif
        default:
                r = SSH_ERR_INVALID_ARGUMENT;
                break;
@@ -240,6 +251,8 @@ out:
        explicit_bzero(kex->c25519_client_key, sizeof(kex->c25519_client_key));
        explicit_bzero(kex->sntrup761_client_key,
            sizeof(kex->sntrup761_client_key));
+       explicit_bzero(kex->mlkem768_client_key,
+           sizeof(kex->mlkem768_client_key));
        sshbuf_free(server_host_key_blob);
        free(signature);
        sshbuf_free(tmp);
@@ -307,6 +320,12 @@ input_kex_gen_init(int type, u_int32_t seq, struct ssh *ssh)
                r = kex_kem_sntrup761x25519_enc(kex, client_pubkey,
                    &server_pubkey, &shared_secret);
                break;
+#ifdef WITH_MLKEM
+       case KEX_KEM_MLKEM768X25519_SHA256:
+               r = kex_kem_mlkem768x25519_enc(kex, client_pubkey,
+                   &server_pubkey, &shared_secret);
+               break;
+#endif
        default:
                r = SSH_ERR_INVALID_ARGUMENT;
                break;
diff --git a/usr.bin/ssh/kexmlkem768x25519.c b/usr.bin/ssh/kexmlkem768x25519.c
new file mode 100644 (file)
index 0000000..26563e2
--- /dev/null
@@ -0,0 +1,252 @@
+/* $OpenBSD: kexmlkem768x25519.c,v 1.1 2024/09/02 12:13:56 djm Exp $ */
+/*
+ * Copyright (c) 2023 Markus Friedl.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <signal.h>
+
+#include "sshkey.h"
+#include "kex.h"
+#include "sshbuf.h"
+#include "digest.h"
+#include "ssherr.h"
+#include "log.h"
+
+#include "libcrux_mlkem768_sha3.h"
+
+int
+kex_kem_mlkem768x25519_keypair(struct kex *kex)
+{
+       struct sshbuf *buf = NULL;
+       u_char rnd[LIBCRUX_ML_KEM_KEY_PAIR_PRNG_LEN], *cp = NULL;
+       size_t need;
+       int r = SSH_ERR_INTERNAL_ERROR;
+       struct libcrux_mlkem768_keypair keypair;
+
+       if ((buf = sshbuf_new()) == NULL)
+               return SSH_ERR_ALLOC_FAIL;
+       need = crypto_kem_mlkem768_PUBLICKEYBYTES + CURVE25519_SIZE;
+       if ((r = sshbuf_reserve(buf, need, &cp)) != 0)
+               goto out;
+       arc4random_buf(rnd, sizeof(rnd));
+       keypair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(rnd);
+       memcpy(cp, keypair.pk.value, crypto_kem_mlkem768_PUBLICKEYBYTES);
+       memcpy(kex->mlkem768_client_key, keypair.sk.value,
+           sizeof(kex->mlkem768_client_key));
+#ifdef DEBUG_KEXECDH
+       dump_digest("client public key mlkem768:", cp,
+           crypto_kem_mlkem768_PUBLICKEYBYTES);
+#endif
+       cp += crypto_kem_mlkem768_PUBLICKEYBYTES;
+       kexc25519_keygen(kex->c25519_client_key, cp);
+#ifdef DEBUG_KEXECDH
+       dump_digest("client public key c25519:", cp, CURVE25519_SIZE);
+#endif
+       /* success */
+       r = 0;
+       kex->client_pub = buf;
+       buf = NULL;
+ out:
+       explicit_bzero(&keypair, sizeof(keypair));
+       explicit_bzero(rnd, sizeof(rnd));
+       sshbuf_free(buf);
+       return r;
+}
+
+int
+kex_kem_mlkem768x25519_enc(struct kex *kex,
+   const struct sshbuf *client_blob, struct sshbuf **server_blobp,
+   struct sshbuf **shared_secretp)
+{
+       struct sshbuf *server_blob = NULL;
+       struct sshbuf *buf = NULL;
+       const u_char *client_pub;
+       u_char rnd[LIBCRUX_ML_KEM_ENC_PRNG_LEN];
+       u_char server_pub[CURVE25519_SIZE], server_key[CURVE25519_SIZE];
+       u_char hash[SSH_DIGEST_MAX_LENGTH];
+       size_t need;
+       int r = SSH_ERR_INTERNAL_ERROR;
+       struct libcrux_mlkem768_enc_result enc;
+       struct libcrux_mlkem768_pk mlkem_pub;
+
+       *server_blobp = NULL;
+       *shared_secretp = NULL;
+       memset(&mlkem_pub, 0, sizeof(mlkem_pub));
+
+       /* client_blob contains both KEM and ECDH client pubkeys */
+       need = crypto_kem_mlkem768_PUBLICKEYBYTES + CURVE25519_SIZE;
+       if (sshbuf_len(client_blob) != need) {
+               r = SSH_ERR_SIGNATURE_INVALID;
+               goto out;
+       }
+       client_pub = sshbuf_ptr(client_blob);
+#ifdef DEBUG_KEXECDH
+       dump_digest("client public key mlkem768:", client_pub,
+           crypto_kem_mlkem768_PUBLICKEYBYTES);
+       dump_digest("client public key 25519:",
+           client_pub + crypto_kem_mlkem768_PUBLICKEYBYTES,
+           CURVE25519_SIZE);
+#endif
+       /* check public key validity */
+       memcpy(mlkem_pub.value, client_pub, crypto_kem_mlkem768_PUBLICKEYBYTES);
+       if (!libcrux_ml_kem_mlkem768_portable_validate_public_key(&mlkem_pub)) {
+               r = SSH_ERR_SIGNATURE_INVALID;
+               goto out;
+       }
+
+       /* allocate buffer for concatenation of KEM key and ECDH shared key */
+       /* the buffer will be hashed and the result is the shared secret */
+       if ((buf = sshbuf_new()) == NULL) {
+               r = SSH_ERR_ALLOC_FAIL;
+               goto out;
+       }
+       /* allocate space for encrypted KEM key and ECDH pub key */
+       if ((server_blob = sshbuf_new()) == NULL) {
+               r = SSH_ERR_ALLOC_FAIL;
+               goto out;
+       }
+       /* generate and encrypt KEM key with client key */
+       arc4random_buf(rnd, sizeof(rnd));
+       enc = libcrux_ml_kem_mlkem768_portable_encapsulate(&mlkem_pub, rnd);
+       /* generate ECDH key pair, store server pubkey after ciphertext */
+       kexc25519_keygen(server_key, server_pub);
+       if ((r = sshbuf_put(buf, enc.snd, sizeof(enc.snd))) != 0 ||
+           (r = sshbuf_put(server_blob, enc.fst.value, sizeof(enc.fst.value))) != 0 ||
+           (r = sshbuf_put(server_blob, server_pub, sizeof(server_pub))) != 0)
+               goto out;
+       /* append ECDH shared key */
+       client_pub += crypto_kem_mlkem768_PUBLICKEYBYTES;
+       if ((r = kexc25519_shared_key_ext(server_key, client_pub, buf, 1)) < 0)
+               goto out;
+       if ((r = ssh_digest_buffer(kex->hash_alg, buf, hash, sizeof(hash))) != 0)
+               goto out;
+#ifdef DEBUG_KEXECDH
+       dump_digest("server public key 25519:", server_pub, CURVE25519_SIZE);
+       dump_digest("server cipher text:",
+           enc.fst.value, sizeof(enc.fst.value));
+       dump_digest("server kem key:", enc.snd, sizeof(enc.snd));
+       dump_digest("concatenation of KEM key and ECDH shared key:",
+           sshbuf_ptr(buf), sshbuf_len(buf));
+#endif
+       /* string-encoded hash is resulting shared secret */
+       sshbuf_reset(buf);
+       if ((r = sshbuf_put_string(buf, hash,
+           ssh_digest_bytes(kex->hash_alg))) != 0)
+               goto out;
+#ifdef DEBUG_KEXECDH
+       dump_digest("encoded shared secret:", sshbuf_ptr(buf), sshbuf_len(buf));
+#endif
+       /* success */
+       r = 0;
+       *server_blobp = server_blob;
+       *shared_secretp = buf;
+       server_blob = NULL;
+       buf = NULL;
+ out:
+       explicit_bzero(hash, sizeof(hash));
+       explicit_bzero(server_key, sizeof(server_key));
+       explicit_bzero(rnd, sizeof(rnd));
+       explicit_bzero(&enc, sizeof(enc));
+       sshbuf_free(server_blob);
+       sshbuf_free(buf);
+       return r;
+}
+
+int
+kex_kem_mlkem768x25519_dec(struct kex *kex,
+    const struct sshbuf *server_blob, struct sshbuf **shared_secretp)
+{
+       struct sshbuf *buf = NULL;
+       u_char mlkem_key[crypto_kem_mlkem768_BYTES];
+       const u_char *ciphertext, *server_pub;
+       u_char hash[SSH_DIGEST_MAX_LENGTH];
+       size_t need;
+       int r;
+       struct libcrux_mlkem768_sk mlkem_priv;
+       struct libcrux_mlkem768_ciphertext mlkem_ciphertext;
+
+       *shared_secretp = NULL;
+       memset(&mlkem_priv, 0, sizeof(mlkem_priv));
+       memset(&mlkem_ciphertext, 0, sizeof(mlkem_ciphertext));
+
+       need = crypto_kem_mlkem768_CIPHERTEXTBYTES + CURVE25519_SIZE;
+       if (sshbuf_len(server_blob) != need) {
+               r = SSH_ERR_SIGNATURE_INVALID;
+               goto out;
+       }
+       ciphertext = sshbuf_ptr(server_blob);
+       server_pub = ciphertext + crypto_kem_mlkem768_CIPHERTEXTBYTES;
+       /* hash concatenation of KEM key and ECDH shared key */
+       if ((buf = sshbuf_new()) == NULL) {
+               r = SSH_ERR_ALLOC_FAIL;
+               goto out;
+       }
+       memcpy(mlkem_priv.value, kex->mlkem768_client_key,
+           sizeof(kex->mlkem768_client_key));
+       memcpy(mlkem_ciphertext.value, ciphertext,
+           sizeof(mlkem_ciphertext.value));
+#ifdef DEBUG_KEXECDH
+       dump_digest("server cipher text:", mlkem_ciphertext.value,
+           sizeof(mlkem_ciphertext.value));
+       dump_digest("server public key c25519:", server_pub, CURVE25519_SIZE);
+#endif
+       libcrux_ml_kem_mlkem768_portable_decapsulate(&mlkem_priv,
+           &mlkem_ciphertext, mlkem_key);
+       if ((r = sshbuf_put(buf, mlkem_key, sizeof(mlkem_key))) != 0)
+               goto out;
+       if ((r = kexc25519_shared_key_ext(kex->c25519_client_key, server_pub,
+           buf, 1)) < 0)
+               goto out;
+       if ((r = ssh_digest_buffer(kex->hash_alg, buf,
+           hash, sizeof(hash))) != 0)
+               goto out;
+#ifdef DEBUG_KEXECDH
+       dump_digest("client kem key:", mlkem_key, sizeof(mlkem_key));
+       dump_digest("concatenation of KEM key and ECDH shared key:",
+           sshbuf_ptr(buf), sshbuf_len(buf));
+#endif
+       sshbuf_reset(buf);
+       if ((r = sshbuf_put_string(buf, hash,
+           ssh_digest_bytes(kex->hash_alg))) != 0)
+               goto out;
+#ifdef DEBUG_KEXECDH
+       dump_digest("encoded shared secret:", sshbuf_ptr(buf), sshbuf_len(buf));
+#endif
+       /* success */
+       r = 0;
+       *shared_secretp = buf;
+       buf = NULL;
+ out:
+       explicit_bzero(hash, sizeof(hash));
+       explicit_bzero(&mlkem_priv, sizeof(mlkem_priv));
+       explicit_bzero(&mlkem_ciphertext, sizeof(mlkem_ciphertext));
+       explicit_bzero(mlkem_key, sizeof(mlkem_key));
+       sshbuf_free(buf);
+       return r;
+}
diff --git a/usr.bin/ssh/libcrux_mlkem768_sha3.h b/usr.bin/ssh/libcrux_mlkem768_sha3.h
new file mode 100644 (file)
index 0000000..a82d60e
--- /dev/null
@@ -0,0 +1,12332 @@
+/*  $OpenBSD: libcrux_mlkem768_sha3.h,v 1.1 2024/09/02 12:13:56 djm Exp $ */
+/* Extracted from libcrux revision 84c5d87b3092c59294345aa269ceefe0eb97cc35 */
+
+/*
+ * MIT License
+ *
+ * Copyright (c) 2024 Cryspen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#if !defined(__GNUC__) || (__GNUC__ < 2)
+# define __attribute__(x)
+#endif
+#define KRML_MUSTINLINE inline
+#define KRML_NOINLINE __attribute__((noinline, unused))
+#define KRML_HOST_EPRINTF(...)
+#define KRML_HOST_EXIT(x) fatal_f("internal error")
+
+/* from libcrux/libcrux-ml-kem/cg/eurydice_glue.h */
+/*
+ * SPDX-FileCopyrightText: 2024 Eurydice Contributors
+ * SPDX-FileCopyrightText: 2024 Cryspen Sarl <info@cryspen.com>
+ *
+ * SPDX-License-Identifier: MIT or Apache-2.0
+ */
+
+#pragma once
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+
+// SLICES, ARRAYS, ETC.
+
+// The MSVC C++ compiler does not support compound literals.
+// This CLITERAL is used to turn `(type){...}` into `type{...}` when using a C++
+// compiler.
+#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.
+//
+// Empty slices have `len == 0` and `ptr` always needs to be valid pointer that
+// is not NULL (otherwise the construction in EURYDICE_SLICE computes `NULL +
+// start`).
+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) (((t_ptr_t)s.ptr)[i])
+#define Eurydice_slice_subslice(s, r, t, _) \
+  EURYDICE_SLICE((t *)s.ptr, r.start, r.end)
+// Variant for when the start and end indices are statically known (i.e., the
+// range argument `r` is a literal).
+#define Eurydice_slice_subslice2(s, start, end, t) \
+  EURYDICE_SLICE((t *)s.ptr, start, end)
+#define Eurydice_slice_subslice_to(s, subslice_end_pos, t, _) \
+  EURYDICE_SLICE((t *)s.ptr, 0, subslice_end_pos)
+#define Eurydice_slice_subslice_from(s, subslice_start_pos, t, _) \
+  EURYDICE_SLICE((t *)s.ptr, subslice_start_pos, s.len)
+#define Eurydice_array_to_slice(end, x, 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, _) \
+  EURYDICE_SLICE((t *)x, r.start, r.end)
+// Same as above, variant for when start and end are statically known
+#define Eurydice_array_to_subslice2(x, start, end, t) \
+  EURYDICE_SLICE((t *)x, start, end)
+#define Eurydice_array_to_subslice_to(_size, x, r, t, _range_t) \
+  EURYDICE_SLICE((t *)x, 0, r)
+#define Eurydice_array_to_subslice_from(size, x, r, t, _range_t) \
+  EURYDICE_SLICE((t *)x, r, size)
+#define Eurydice_slice_len(s, t) EURYDICE_SLICE_LEN(s, t)
+#define Eurydice_slice_copy(dst, src, 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 TryFromSliceError uint8_t
+
+#define Eurydice_array_eq(sz, a1, a2, t, _) \
+  (memcmp(a1, a2, sz * sizeof(t)) == 0)
+#define core_array_equality___core__cmp__PartialEq__Array_U__N___for__Array_T__N____eq( \
+    sz, a1, a2, t, _, _ret_t)                                                           \
+  Eurydice_array_eq(sz, a1, a2, t, _)
+#define core_array_equality___core__cmp__PartialEq__0___Slice_U____for__Array_T__N___3__eq( \
+    sz, a1, a2, t, _, _ret_t)                                                               \
+  Eurydice_array_eq(sz, a1, ((a2)->ptr), t, _)
+
+#define Eurydice_slice_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 Eurydice_slice_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)                      \
+  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]) {
+  memcpy(buf, &v, sizeof(v));
+}
+static inline uint64_t core_num__u64_9__from_le_bytes(uint8_t buf[8]) {
+  uint64_t v;
+  memcpy(&v, buf, sizeof(v));
+  return v;
+}
+
+static inline uint32_t core_num__u32_8__from_le_bytes(uint8_t buf[4]) {
+  uint32_t v;
+  memcpy(&v, buf, sizeof(v));
+  return v;
+}
+
+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;
+}
+
+// ITERATORS
+
+#define Eurydice_range_iter_next(iter_ptr, t, ret_t) \
+  (((iter_ptr)->start == (iter_ptr)->end)            \
+       ? (CLITERAL(ret_t){.tag = None})              \
+       : (CLITERAL(ret_t){.tag = 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__1__into_iter \
+  Eurydice_into_iter
+
+#if defined(__cplusplus)
+}
+#endif
+
+/* from libcrux/libcrux-ml-kem/cg/libcrux_core.h */
+/*
+ * SPDX-FileCopyrightText: 2024 Cryspen Sarl <info@cryspen.com>
+ *
+ * SPDX-License-Identifier: MIT or Apache-2.0
+ *
+ * This code was generated with the following revisions:
+ * Charon: 6b5e110342a771a3e1c739b10294b1778e4be8b4
+ * Eurydice: 31be7d65ca5d6acdacfb33652e478d24dd85c1cb
+ * Karamel: 3205d3365ea2790b02368f79fcee38e38d0b5908
+ * F*: a32b316e521fa4f239b610ec8f1d15e78d62cbe8-dirty
+ * Libcrux: 4ad532b206174114dd4140b718e7794a28fc59ee
+ */
+
+#ifndef __libcrux_core_H
+#define __libcrux_core_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/**
+A monomorphic instance of core.ops.range.Range
+with types size_t
+
+*/
+typedef struct core_ops_range_Range_b3_s {
+  size_t start;
+  size_t end;
+} core_ops_range_Range_b3;
+
+#define Ok 0
+#define Err 1
+
+typedef uint8_t Result_86_tags;
+
+#define None 0
+#define Some 1
+
+typedef uint8_t Option_ef_tags;
+
+/**
+A monomorphic instance of core.option.Option
+with types size_t
+
+*/
+typedef struct Option_b3_s {
+  Option_ef_tags tag;
+  size_t f0;
+} Option_b3;
+
+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);
+
+#define LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE ((size_t)32U)
+
+#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;
+
+/**
+A monomorphic instance of core.result.Result
+with types uint8_t[24size_t], core_array_TryFromSliceError
+
+*/
+typedef struct Result_6f_s {
+  Result_86_tags tag;
+  union {
+    uint8_t case_Ok[24U];
+    TryFromSliceError case_Err;
+  } val;
+} Result_6f;
+
+/**
+This function found in impl {core::result::Result<T, E>}
+*/
+/**
+A monomorphic instance of core.result.unwrap_41
+with types uint8_t[24size_t], core_array_TryFromSliceError
+
+*/
+static inline void unwrap_41_1c(Result_6f self, uint8_t ret[24U]) {
+  if (self.tag == 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);
+  }
+}
+
+/**
+A monomorphic instance of core.result.Result
+with types uint8_t[20size_t], core_array_TryFromSliceError
+
+*/
+typedef struct Result_7a_s {
+  Result_86_tags tag;
+  union {
+    uint8_t case_Ok[20U];
+    TryFromSliceError case_Err;
+  } val;
+} Result_7a;
+
+/**
+This function found in impl {core::result::Result<T, E>}
+*/
+/**
+A monomorphic instance of core.result.unwrap_41
+with types uint8_t[20size_t], core_array_TryFromSliceError
+
+*/
+static inline void unwrap_41_34(Result_7a self, uint8_t ret[20U]) {
+  if (self.tag == 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);
+  }
+}
+
+/**
+A monomorphic instance of core.result.Result
+with types uint8_t[10size_t], core_array_TryFromSliceError
+
+*/
+typedef struct Result_cd_s {
+  Result_86_tags tag;
+  union {
+    uint8_t case_Ok[10U];
+    TryFromSliceError case_Err;
+  } val;
+} Result_cd;
+
+/**
+This function found in impl {core::result::Result<T, E>}
+*/
+/**
+A monomorphic instance of core.result.unwrap_41
+with types uint8_t[10size_t], core_array_TryFromSliceError
+
+*/
+static inline void unwrap_41_e8(Result_cd self, uint8_t ret[10U]) {
+  if (self.tag == 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 Eurydice_slice_uint8_t_4size_t__x2_s {
+  Eurydice_slice fst[4U];
+  Eurydice_slice snd[4U];
+} Eurydice_slice_uint8_t_4size_t__x2;
+
+typedef struct libcrux_ml_kem_mlkem768_MlKem768Ciphertext_s {
+  uint8_t value[1088U];
+} libcrux_ml_kem_mlkem768_MlKem768Ciphertext;
+
+/**
+ A reference to the raw byte slice.
+*/
+/**
+This function found in impl {libcrux_ml_kem::types::MlKemCiphertext<SIZE>#6}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.types.as_slice_d4
+with const generics
+- SIZE= 1088
+*/
+static inline uint8_t *libcrux_ml_kem_types_as_slice_d4_1d(
+    libcrux_ml_kem_mlkem768_MlKem768Ciphertext *self) {
+  return self->value;
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.types.MlKemPublicKey
+with const generics
+- $1184size_t
+*/
+typedef struct libcrux_ml_kem_types_MlKemPublicKey_15_s {
+  uint8_t value[1184U];
+} libcrux_ml_kem_types_MlKemPublicKey_15;
+
+/**
+This function found in impl {(core::convert::From<@Array<u8, SIZE>> for
+libcrux_ml_kem::types::MlKemPublicKey<SIZE>)#14}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.types.from_b6
+with const generics
+- SIZE= 1184
+*/
+static inline libcrux_ml_kem_types_MlKemPublicKey_15
+libcrux_ml_kem_types_from_b6_da(uint8_t value[1184U]) {
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_value[1184U];
+  memcpy(copy_of_value, value, (size_t)1184U * sizeof(uint8_t));
+  libcrux_ml_kem_types_MlKemPublicKey_15 lit;
+  memcpy(lit.value, copy_of_value, (size_t)1184U * sizeof(uint8_t));
+  return lit;
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.types.MlKemPrivateKey
+with const generics
+- $2400size_t
+*/
+typedef struct libcrux_ml_kem_types_MlKemPrivateKey_55_s {
+  uint8_t value[2400U];
+} libcrux_ml_kem_types_MlKemPrivateKey_55;
+
+typedef struct libcrux_ml_kem_mlkem768_MlKem768KeyPair_s {
+  libcrux_ml_kem_types_MlKemPrivateKey_55 sk;
+  libcrux_ml_kem_types_MlKemPublicKey_15 pk;
+} libcrux_ml_kem_mlkem768_MlKem768KeyPair;
+
+/**
+ Create a new [`MlKemKeyPair`] from the secret and public key.
+*/
+/**
+This function found in impl
+{libcrux_ml_kem::types::MlKemKeyPair<PRIVATE_KEY_SIZE, PUBLIC_KEY_SIZE>}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.types.from_17
+with const generics
+- PRIVATE_KEY_SIZE= 2400
+- PUBLIC_KEY_SIZE= 1184
+*/
+static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair
+libcrux_ml_kem_types_from_17_35(libcrux_ml_kem_types_MlKemPrivateKey_55 sk,
+                                libcrux_ml_kem_types_MlKemPublicKey_15 pk) {
+  return (
+      CLITERAL(libcrux_ml_kem_mlkem768_MlKem768KeyPair){.sk = sk, .pk = pk});
+}
+
+/**
+This function found in impl {(core::convert::From<@Array<u8, SIZE>> for
+libcrux_ml_kem::types::MlKemPrivateKey<SIZE>)#8}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.types.from_05
+with const generics
+- SIZE= 2400
+*/
+static inline libcrux_ml_kem_types_MlKemPrivateKey_55
+libcrux_ml_kem_types_from_05_f2(uint8_t value[2400U]) {
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_value[2400U];
+  memcpy(copy_of_value, value, (size_t)2400U * sizeof(uint8_t));
+  libcrux_ml_kem_types_MlKemPrivateKey_55 lit;
+  memcpy(lit.value, copy_of_value, (size_t)2400U * sizeof(uint8_t));
+  return lit;
+}
+
+/**
+A monomorphic instance of core.result.Result
+with types uint8_t[32size_t], core_array_TryFromSliceError
+
+*/
+typedef struct Result_00_s {
+  Result_86_tags tag;
+  union {
+    uint8_t case_Ok[32U];
+    TryFromSliceError case_Err;
+  } val;
+} Result_00;
+
+/**
+This function found in impl {core::result::Result<T, E>}
+*/
+/**
+A monomorphic instance of core.result.unwrap_41
+with types uint8_t[32size_t], core_array_TryFromSliceError
+
+*/
+static inline void unwrap_41_83(Result_00 self, uint8_t ret[32U]) {
+  if (self.tag == Ok) {
+    uint8_t f0[32U];
+    memcpy(f0, self.val.case_Ok, (size_t)32U * sizeof(uint8_t));
+    memcpy(ret, f0, (size_t)32U * sizeof(uint8_t));
+  } else {
+    KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__,
+                      "unwrap not Ok");
+    KRML_HOST_EXIT(255U);
+  }
+}
+
+/**
+A monomorphic instance of K.
+with types libcrux_ml_kem_types_MlKemCiphertext[[$1088size_t]],
+uint8_t[32size_t]
+
+*/
+typedef struct tuple_3c_s {
+  libcrux_ml_kem_mlkem768_MlKem768Ciphertext fst;
+  uint8_t snd[32U];
+} tuple_3c;
+
+/**
+This function found in impl {(core::convert::From<@Array<u8, SIZE>> for
+libcrux_ml_kem::types::MlKemCiphertext<SIZE>)#2}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.types.from_01
+with const generics
+- SIZE= 1088
+*/
+static inline libcrux_ml_kem_mlkem768_MlKem768Ciphertext
+libcrux_ml_kem_types_from_01_9f(uint8_t value[1088U]) {
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_value[1088U];
+  memcpy(copy_of_value, value, (size_t)1088U * sizeof(uint8_t));
+  libcrux_ml_kem_mlkem768_MlKem768Ciphertext lit;
+  memcpy(lit.value, copy_of_value, (size_t)1088U * sizeof(uint8_t));
+  return lit;
+}
+
+/**
+ A reference to the raw byte slice.
+*/
+/**
+This function found in impl {libcrux_ml_kem::types::MlKemPublicKey<SIZE>#18}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.types.as_slice_cb
+with const generics
+- SIZE= 1184
+*/
+static inline uint8_t *libcrux_ml_kem_types_as_slice_cb_50(
+    libcrux_ml_kem_types_MlKemPublicKey_15 *self) {
+  return self->value;
+}
+
+/**
+ Pad the `slice` with `0`s at the end.
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.utils.into_padded_array
+with const generics
+- LEN= 33
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_utils_into_padded_array_ea2(
+    Eurydice_slice slice, uint8_t ret[33U]) {
+  uint8_t out[33U] = {0U};
+  uint8_t *uu____0 = out;
+  Eurydice_slice_copy(
+      Eurydice_array_to_subslice2(uu____0, (size_t)0U,
+                                  Eurydice_slice_len(slice, uint8_t), uint8_t),
+      slice, uint8_t);
+  memcpy(ret, out, (size_t)33U * sizeof(uint8_t));
+}
+
+/**
+ Pad the `slice` with `0`s at the end.
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.utils.into_padded_array
+with const generics
+- LEN= 34
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_utils_into_padded_array_ea1(
+    Eurydice_slice slice, uint8_t ret[34U]) {
+  uint8_t out[34U] = {0U};
+  uint8_t *uu____0 = out;
+  Eurydice_slice_copy(
+      Eurydice_array_to_subslice2(uu____0, (size_t)0U,
+                                  Eurydice_slice_len(slice, uint8_t), uint8_t),
+      slice, uint8_t);
+  memcpy(ret, out, (size_t)34U * sizeof(uint8_t));
+}
+
+/**
+This function found in impl {(core::convert::AsRef<@Slice<u8>> for
+libcrux_ml_kem::types::MlKemCiphertext<SIZE>)#1}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.types.as_ref_00
+with const generics
+- SIZE= 1088
+*/
+static inline Eurydice_slice libcrux_ml_kem_types_as_ref_00_24(
+    libcrux_ml_kem_mlkem768_MlKem768Ciphertext *self) {
+  return Eurydice_array_to_slice((size_t)1088U, self->value, uint8_t);
+}
+
+/**
+ Pad the `slice` with `0`s at the end.
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.utils.into_padded_array
+with const generics
+- LEN= 1120
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_utils_into_padded_array_ea0(
+    Eurydice_slice slice, uint8_t ret[1120U]) {
+  uint8_t out[1120U] = {0U};
+  uint8_t *uu____0 = out;
+  Eurydice_slice_copy(
+      Eurydice_array_to_subslice2(uu____0, (size_t)0U,
+                                  Eurydice_slice_len(slice, uint8_t), uint8_t),
+      slice, uint8_t);
+  memcpy(ret, out, (size_t)1120U * sizeof(uint8_t));
+}
+
+/**
+ Pad the `slice` with `0`s at the end.
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.utils.into_padded_array
+with const generics
+- LEN= 64
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_utils_into_padded_array_ea(
+    Eurydice_slice slice, uint8_t ret[64U]) {
+  uint8_t out[64U] = {0U};
+  uint8_t *uu____0 = out;
+  Eurydice_slice_copy(
+      Eurydice_array_to_subslice2(uu____0, (size_t)0U,
+                                  Eurydice_slice_len(slice, uint8_t), uint8_t),
+      slice, uint8_t);
+  memcpy(ret, out, (size_t)64U * sizeof(uint8_t));
+}
+
+/**
+A monomorphic instance of core.result.Result
+with types int16_t[16size_t], core_array_TryFromSliceError
+
+*/
+typedef struct Result_c0_s {
+  Result_86_tags tag;
+  union {
+    int16_t case_Ok[16U];
+    TryFromSliceError case_Err;
+  } val;
+} Result_c0;
+
+/**
+This function found in impl {core::result::Result<T, E>}
+*/
+/**
+A monomorphic instance of core.result.unwrap_41
+with types int16_t[16size_t], core_array_TryFromSliceError
+
+*/
+static inline void unwrap_41_f9(Result_c0 self, int16_t ret[16U]) {
+  if (self.tag == 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);
+  }
+}
+
+/**
+A monomorphic instance of core.result.Result
+with types uint8_t[8size_t], core_array_TryFromSliceError
+
+*/
+typedef struct Result_56_s {
+  Result_86_tags tag;
+  union {
+    uint8_t case_Ok[8U];
+    TryFromSliceError case_Err;
+  } val;
+} Result_56;
+
+/**
+This function found in impl {core::result::Result<T, E>}
+*/
+/**
+A monomorphic instance of core.result.unwrap_41
+with types uint8_t[8size_t], core_array_TryFromSliceError
+
+*/
+static inline void unwrap_41_ac(Result_56 self, uint8_t ret[8U]) {
+  if (self.tag == 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 Eurydice_slice_uint8_t_x2_s {
+  Eurydice_slice fst;
+  Eurydice_slice snd;
+} Eurydice_slice_uint8_t_x2;
+
+typedef struct Eurydice_slice_uint8_t_1size_t__x2_s {
+  Eurydice_slice fst[1U];
+  Eurydice_slice snd[1U];
+} Eurydice_slice_uint8_t_1size_t__x2;
+
+#if defined(__cplusplus)
+}
+#endif
+
+#define __libcrux_core_H_DEFINED
+#endif
+
+/* from libcrux/libcrux-ml-kem/cg/libcrux_ct_ops.h */
+/*
+ * SPDX-FileCopyrightText: 2024 Cryspen Sarl <info@cryspen.com>
+ *
+ * SPDX-License-Identifier: MIT or Apache-2.0
+ *
+ * This code was generated with the following revisions:
+ * Charon: 6b5e110342a771a3e1c739b10294b1778e4be8b4
+ * Eurydice: 31be7d65ca5d6acdacfb33652e478d24dd85c1cb
+ * Karamel: 3205d3365ea2790b02368f79fcee38e38d0b5908
+ * F*: a32b316e521fa4f239b610ec8f1d15e78d62cbe8-dirty
+ * Libcrux: 4ad532b206174114dd4140b718e7794a28fc59ee
+ */
+
+#ifndef __libcrux_ct_ops_H
+#define __libcrux_ct_ops_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/**
+ Return 1 if `value` is not zero and 0 otherwise.
+*/
+static inline uint8_t libcrux_ml_kem_constant_time_ops_inz(uint8_t value) {
+  uint16_t value0 = (uint16_t)value;
+  uint16_t result = (((uint32_t)value0 |
+                      (uint32_t)core_num__u16_7__wrapping_add(~value0, 1U)) &
+                     0xFFFFU) >>
+                        8U &
+                    1U;
+  return (uint8_t)result;
+}
+
+static KRML_NOINLINE uint8_t
+libcrux_ml_kem_constant_time_ops_is_non_zero(uint8_t value) {
+  return libcrux_ml_kem_constant_time_ops_inz(value);
+}
+
+/**
+ Return 1 if the bytes of `lhs` and `rhs` do not exactly
+ match and 0 otherwise.
+*/
+static inline uint8_t libcrux_ml_kem_constant_time_ops_compare(
+    Eurydice_slice lhs, Eurydice_slice rhs) {
+  uint8_t r = 0U;
+  for (size_t i = (size_t)0U; i < Eurydice_slice_len(lhs, uint8_t); i++) {
+    size_t i0 = i;
+    r = (uint32_t)r |
+        ((uint32_t)Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *) ^
+         (uint32_t)Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *));
+  }
+  return libcrux_ml_kem_constant_time_ops_is_non_zero(r);
+}
+
+static KRML_NOINLINE uint8_t
+libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time(
+    Eurydice_slice lhs, Eurydice_slice rhs) {
+  return libcrux_ml_kem_constant_time_ops_compare(lhs, rhs);
+}
+
+/**
+ If `selector` is not zero, return the bytes in `rhs`; return the bytes in
+ `lhs` otherwise.
+*/
+static inline void libcrux_ml_kem_constant_time_ops_select_ct(
+    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;
+    out[i0] = ((uint32_t)Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *) &
+               (uint32_t)mask) |
+              ((uint32_t)Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *) &
+               (uint32_t)~mask);
+  }
+  memcpy(ret, out, (size_t)32U * sizeof(uint8_t));
+}
+
+static KRML_NOINLINE 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]) {
+  libcrux_ml_kem_constant_time_ops_select_ct(lhs, rhs, selector, ret);
+}
+
+static inline void
+libcrux_ml_kem_constant_time_ops_compare_ciphertexts_select_shared_secret_in_constant_time(
+    Eurydice_slice lhs_c, Eurydice_slice rhs_c, Eurydice_slice lhs_s,
+    Eurydice_slice rhs_s, uint8_t ret[32U]) {
+  uint8_t selector =
+      libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time(
+          lhs_c, rhs_c);
+  uint8_t ret0[32U];
+  libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time(
+      lhs_s, rhs_s, selector, ret0);
+  memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t));
+}
+
+#if defined(__cplusplus)
+}
+#endif
+
+#define __libcrux_ct_ops_H_DEFINED
+#endif
+
+/* from libcrux/libcrux-ml-kem/cg/libcrux_sha3_portable.h */
+/*
+ * SPDX-FileCopyrightText: 2024 Cryspen Sarl <info@cryspen.com>
+ *
+ * SPDX-License-Identifier: MIT or Apache-2.0
+ *
+ * This code was generated with the following revisions:
+ * Charon: 6b5e110342a771a3e1c739b10294b1778e4be8b4
+ * Eurydice: 31be7d65ca5d6acdacfb33652e478d24dd85c1cb
+ * Karamel: 3205d3365ea2790b02368f79fcee38e38d0b5908
+ * F*: a32b316e521fa4f239b610ec8f1d15e78d62cbe8-dirty
+ * Libcrux: 4ad532b206174114dd4140b718e7794a28fc59ee
+ */
+
+#ifndef __libcrux_sha3_portable_H
+#define __libcrux_sha3_portable_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+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};
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+static KRML_MUSTINLINE uint64_t libcrux_sha3_portable_keccak_zero_5a(void) {
+  return 0ULL;
+}
+
+static KRML_MUSTINLINE 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;
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+static KRML_MUSTINLINE uint64_t libcrux_sha3_portable_keccak_xor5_5a(
+    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);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left
+with const generics
+- LEFT= 1
+- RIGHT= 63
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_rotate_left_cb(uint64_t x) {
+  return x << (uint32_t)(int32_t)1 | x >> (uint32_t)(int32_t)63;
+}
+
+static KRML_MUSTINLINE 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_cb(b);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_rotate_left1_and_xor_5a(uint64_t a, uint64_t b) {
+  return libcrux_sha3_portable_keccak__vrax1q_u64(a, b);
+}
+
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak__vbcaxq_u64(uint64_t a, uint64_t b, uint64_t c) {
+  return a ^ (b & ~c);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+static KRML_MUSTINLINE uint64_t libcrux_sha3_portable_keccak_and_not_xor_5a(
+    uint64_t a, uint64_t b, uint64_t c) {
+  return libcrux_sha3_portable_keccak__vbcaxq_u64(a, b, c);
+}
+
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak__veorq_n_u64(uint64_t a, uint64_t c) {
+  return a ^ c;
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_xor_constant_5a(uint64_t a, uint64_t c) {
+  return libcrux_sha3_portable_keccak__veorq_n_u64(a, c);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_xor_5a(uint64_t a, uint64_t b) {
+  return a ^ b;
+}
+
+static KRML_MUSTINLINE 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_subslice2(a[0U], start, start + len, uint8_t);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_slice_n_5a(
+    Eurydice_slice a[1U], size_t start, size_t len, Eurydice_slice ret[1U]) {
+  /* Passing arrays by value in Rust generates a copy in C */
+  Eurydice_slice copy_of_a[1U];
+  memcpy(copy_of_a, a, (size_t)1U * sizeof(Eurydice_slice));
+  Eurydice_slice ret0[1U];
+  libcrux_sha3_portable_keccak_slice_1(copy_of_a, start, len, ret0);
+  memcpy(ret, ret0, (size_t)1U * sizeof(Eurydice_slice));
+}
+
+static KRML_MUSTINLINE Eurydice_slice_uint8_t_1size_t__x2
+libcrux_sha3_portable_keccak_split_at_mut_1(Eurydice_slice out[1U],
+                                            size_t mid) {
+  Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at_mut(
+      out[0U], mid, uint8_t, Eurydice_slice_uint8_t_x2);
+  Eurydice_slice out00 = uu____0.fst;
+  Eurydice_slice out01 = uu____0.snd;
+  Eurydice_slice_uint8_t_1size_t__x2 lit;
+  lit.fst[0U] = out00;
+  lit.snd[0U] = out01;
+  return lit;
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+static KRML_MUSTINLINE Eurydice_slice_uint8_t_1size_t__x2
+libcrux_sha3_portable_keccak_split_at_mut_n_5a(Eurydice_slice a[1U],
+                                               size_t mid) {
+  return libcrux_sha3_portable_keccak_split_at_mut_1(a, mid);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.KeccakState
+with types uint64_t
+with const generics
+- $1size_t
+*/
+typedef struct libcrux_sha3_generic_keccak_KeccakState_48_s {
+  uint64_t st[5U][5U];
+} libcrux_sha3_generic_keccak_KeccakState_48;
+
+/**
+ Create a new Shake128 x4 state.
+*/
+/**
+This function found in impl {libcrux_sha3::generic_keccak::KeccakState<T,
+N>[TraitClause@0]#1}
+*/
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.new_1e
+with types uint64_t
+with const generics
+- N= 1
+*/
+static KRML_MUSTINLINE libcrux_sha3_generic_keccak_KeccakState_48
+libcrux_sha3_generic_keccak_new_1e_f4(void) {
+  libcrux_sha3_generic_keccak_KeccakState_48 lit;
+  lit.st[0U][0U] = libcrux_sha3_portable_keccak_zero_5a();
+  lit.st[0U][1U] = libcrux_sha3_portable_keccak_zero_5a();
+  lit.st[0U][2U] = libcrux_sha3_portable_keccak_zero_5a();
+  lit.st[0U][3U] = libcrux_sha3_portable_keccak_zero_5a();
+  lit.st[0U][4U] = libcrux_sha3_portable_keccak_zero_5a();
+  lit.st[1U][0U] = libcrux_sha3_portable_keccak_zero_5a();
+  lit.st[1U][1U] = libcrux_sha3_portable_keccak_zero_5a();
+  lit.st[1U][2U] = libcrux_sha3_portable_keccak_zero_5a();
+  lit.st[1U][3U] = libcrux_sha3_portable_keccak_zero_5a();
+  lit.st[1U][4U] = libcrux_sha3_portable_keccak_zero_5a();
+  lit.st[2U][0U] = libcrux_sha3_portable_keccak_zero_5a();
+  lit.st[2U][1U] = libcrux_sha3_portable_keccak_zero_5a();
+  lit.st[2U][2U] = libcrux_sha3_portable_keccak_zero_5a();
+  lit.st[2U][3U] = libcrux_sha3_portable_keccak_zero_5a();
+  lit.st[2U][4U] = libcrux_sha3_portable_keccak_zero_5a();
+  lit.st[3U][0U] = libcrux_sha3_portable_keccak_zero_5a();
+  lit.st[3U][1U] = libcrux_sha3_portable_keccak_zero_5a();
+  lit.st[3U][2U] = libcrux_sha3_portable_keccak_zero_5a();
+  lit.st[3U][3U] = libcrux_sha3_portable_keccak_zero_5a();
+  lit.st[3U][4U] = libcrux_sha3_portable_keccak_zero_5a();
+  lit.st[4U][0U] = libcrux_sha3_portable_keccak_zero_5a();
+  lit.st[4U][1U] = libcrux_sha3_portable_keccak_zero_5a();
+  lit.st[4U][2U] = libcrux_sha3_portable_keccak_zero_5a();
+  lit.st[4U][3U] = libcrux_sha3_portable_keccak_zero_5a();
+  lit.st[4U][4U] = libcrux_sha3_portable_keccak_zero_5a();
+  return lit;
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.load_block
+with const generics
+- RATE= 72
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_2c(
+    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 uu____0[8U];
+    Result_56 dst;
+    Eurydice_slice_to_array2(
+        &dst,
+        Eurydice_slice_subslice2(blocks[0U], (size_t)8U * i0,
+                                 (size_t)8U * i0 + (size_t)8U, uint8_t),
+        Eurydice_slice, uint8_t[8U]);
+    unwrap_41_ac(dst, uu____0);
+    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] ^ core_num__u64_9__from_le_bytes(uu____0);
+  }
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.load_block_5a
+with const generics
+- RATE= 72
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_5a_b8(
+    uint64_t (*a)[5U], Eurydice_slice b[1U]) {
+  uint64_t(*uu____0)[5U] = a;
+  /* Passing arrays by value in Rust generates a copy in C */
+  Eurydice_slice copy_of_b[1U];
+  memcpy(copy_of_b, b, (size_t)1U * sizeof(Eurydice_slice));
+  libcrux_sha3_portable_keccak_load_block_2c(uu____0, copy_of_b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left
+with const generics
+- LEFT= 36
+- RIGHT= 28
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_rotate_left_cb0(uint64_t x) {
+  return x << (uint32_t)(int32_t)36 | x >> (uint32_t)(int32_t)28;
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64
+with const generics
+- LEFT= 36
+- RIGHT= 28
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak__vxarq_u64_42(uint64_t a, uint64_t b) {
+  uint64_t ab = a ^ b;
+  return libcrux_sha3_portable_keccak_rotate_left_cb0(ab);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a
+with const generics
+- LEFT= 36
+- RIGHT= 28
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb(uint64_t a, uint64_t b) {
+  return libcrux_sha3_portable_keccak__vxarq_u64_42(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left
+with const generics
+- LEFT= 3
+- RIGHT= 61
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_rotate_left_cb1(uint64_t x) {
+  return x << (uint32_t)(int32_t)3 | x >> (uint32_t)(int32_t)61;
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64
+with const generics
+- LEFT= 3
+- RIGHT= 61
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak__vxarq_u64_420(uint64_t a, uint64_t b) {
+  uint64_t ab = a ^ b;
+  return libcrux_sha3_portable_keccak_rotate_left_cb1(ab);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a
+with const generics
+- LEFT= 3
+- RIGHT= 61
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb0(uint64_t a, uint64_t b) {
+  return libcrux_sha3_portable_keccak__vxarq_u64_420(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left
+with const generics
+- LEFT= 41
+- RIGHT= 23
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_rotate_left_cb2(uint64_t x) {
+  return x << (uint32_t)(int32_t)41 | x >> (uint32_t)(int32_t)23;
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64
+with const generics
+- LEFT= 41
+- RIGHT= 23
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak__vxarq_u64_421(uint64_t a, uint64_t b) {
+  uint64_t ab = a ^ b;
+  return libcrux_sha3_portable_keccak_rotate_left_cb2(ab);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a
+with const generics
+- LEFT= 41
+- RIGHT= 23
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb1(uint64_t a, uint64_t b) {
+  return libcrux_sha3_portable_keccak__vxarq_u64_421(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left
+with const generics
+- LEFT= 18
+- RIGHT= 46
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_rotate_left_cb3(uint64_t x) {
+  return x << (uint32_t)(int32_t)18 | x >> (uint32_t)(int32_t)46;
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64
+with const generics
+- LEFT= 18
+- RIGHT= 46
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak__vxarq_u64_422(uint64_t a, uint64_t b) {
+  uint64_t ab = a ^ b;
+  return libcrux_sha3_portable_keccak_rotate_left_cb3(ab);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a
+with const generics
+- LEFT= 18
+- RIGHT= 46
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb2(uint64_t a, uint64_t b) {
+  return libcrux_sha3_portable_keccak__vxarq_u64_422(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64
+with const generics
+- LEFT= 1
+- RIGHT= 63
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak__vxarq_u64_423(uint64_t a, uint64_t b) {
+  uint64_t ab = a ^ b;
+  return libcrux_sha3_portable_keccak_rotate_left_cb(ab);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a
+with const generics
+- LEFT= 1
+- RIGHT= 63
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb3(uint64_t a, uint64_t b) {
+  return libcrux_sha3_portable_keccak__vxarq_u64_423(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left
+with const generics
+- LEFT= 44
+- RIGHT= 20
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_rotate_left_cb4(uint64_t x) {
+  return x << (uint32_t)(int32_t)44 | x >> (uint32_t)(int32_t)20;
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64
+with const generics
+- LEFT= 44
+- RIGHT= 20
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak__vxarq_u64_424(uint64_t a, uint64_t b) {
+  uint64_t ab = a ^ b;
+  return libcrux_sha3_portable_keccak_rotate_left_cb4(ab);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a
+with const generics
+- LEFT= 44
+- RIGHT= 20
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb4(uint64_t a, uint64_t b) {
+  return libcrux_sha3_portable_keccak__vxarq_u64_424(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left
+with const generics
+- LEFT= 10
+- RIGHT= 54
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_rotate_left_cb5(uint64_t x) {
+  return x << (uint32_t)(int32_t)10 | x >> (uint32_t)(int32_t)54;
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64
+with const generics
+- LEFT= 10
+- RIGHT= 54
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak__vxarq_u64_425(uint64_t a, uint64_t b) {
+  uint64_t ab = a ^ b;
+  return libcrux_sha3_portable_keccak_rotate_left_cb5(ab);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a
+with const generics
+- LEFT= 10
+- RIGHT= 54
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb5(uint64_t a, uint64_t b) {
+  return libcrux_sha3_portable_keccak__vxarq_u64_425(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left
+with const generics
+- LEFT= 45
+- RIGHT= 19
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_rotate_left_cb6(uint64_t x) {
+  return x << (uint32_t)(int32_t)45 | x >> (uint32_t)(int32_t)19;
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64
+with const generics
+- LEFT= 45
+- RIGHT= 19
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak__vxarq_u64_426(uint64_t a, uint64_t b) {
+  uint64_t ab = a ^ b;
+  return libcrux_sha3_portable_keccak_rotate_left_cb6(ab);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a
+with const generics
+- LEFT= 45
+- RIGHT= 19
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb6(uint64_t a, uint64_t b) {
+  return libcrux_sha3_portable_keccak__vxarq_u64_426(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left
+with const generics
+- LEFT= 2
+- RIGHT= 62
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_rotate_left_cb7(uint64_t x) {
+  return x << (uint32_t)(int32_t)2 | x >> (uint32_t)(int32_t)62;
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64
+with const generics
+- LEFT= 2
+- RIGHT= 62
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak__vxarq_u64_427(uint64_t a, uint64_t b) {
+  uint64_t ab = a ^ b;
+  return libcrux_sha3_portable_keccak_rotate_left_cb7(ab);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a
+with const generics
+- LEFT= 2
+- RIGHT= 62
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb7(uint64_t a, uint64_t b) {
+  return libcrux_sha3_portable_keccak__vxarq_u64_427(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left
+with const generics
+- LEFT= 62
+- RIGHT= 2
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_rotate_left_cb8(uint64_t x) {
+  return x << (uint32_t)(int32_t)62 | x >> (uint32_t)(int32_t)2;
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64
+with const generics
+- LEFT= 62
+- RIGHT= 2
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak__vxarq_u64_428(uint64_t a, uint64_t b) {
+  uint64_t ab = a ^ b;
+  return libcrux_sha3_portable_keccak_rotate_left_cb8(ab);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a
+with const generics
+- LEFT= 62
+- RIGHT= 2
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb8(uint64_t a, uint64_t b) {
+  return libcrux_sha3_portable_keccak__vxarq_u64_428(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left
+with const generics
+- LEFT= 6
+- RIGHT= 58
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_rotate_left_cb9(uint64_t x) {
+  return x << (uint32_t)(int32_t)6 | x >> (uint32_t)(int32_t)58;
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64
+with const generics
+- LEFT= 6
+- RIGHT= 58
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak__vxarq_u64_429(uint64_t a, uint64_t b) {
+  uint64_t ab = a ^ b;
+  return libcrux_sha3_portable_keccak_rotate_left_cb9(ab);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a
+with const generics
+- LEFT= 6
+- RIGHT= 58
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb9(uint64_t a, uint64_t b) {
+  return libcrux_sha3_portable_keccak__vxarq_u64_429(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left
+with const generics
+- LEFT= 43
+- RIGHT= 21
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_rotate_left_cb10(uint64_t x) {
+  return x << (uint32_t)(int32_t)43 | x >> (uint32_t)(int32_t)21;
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64
+with const generics
+- LEFT= 43
+- RIGHT= 21
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak__vxarq_u64_4210(uint64_t a, uint64_t b) {
+  uint64_t ab = a ^ b;
+  return libcrux_sha3_portable_keccak_rotate_left_cb10(ab);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a
+with const generics
+- LEFT= 43
+- RIGHT= 21
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb10(uint64_t a, uint64_t b) {
+  return libcrux_sha3_portable_keccak__vxarq_u64_4210(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left
+with const generics
+- LEFT= 15
+- RIGHT= 49
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_rotate_left_cb11(uint64_t x) {
+  return x << (uint32_t)(int32_t)15 | x >> (uint32_t)(int32_t)49;
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64
+with const generics
+- LEFT= 15
+- RIGHT= 49
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak__vxarq_u64_4211(uint64_t a, uint64_t b) {
+  uint64_t ab = a ^ b;
+  return libcrux_sha3_portable_keccak_rotate_left_cb11(ab);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a
+with const generics
+- LEFT= 15
+- RIGHT= 49
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb11(uint64_t a, uint64_t b) {
+  return libcrux_sha3_portable_keccak__vxarq_u64_4211(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left
+with const generics
+- LEFT= 61
+- RIGHT= 3
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_rotate_left_cb12(uint64_t x) {
+  return x << (uint32_t)(int32_t)61 | x >> (uint32_t)(int32_t)3;
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64
+with const generics
+- LEFT= 61
+- RIGHT= 3
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak__vxarq_u64_4212(uint64_t a, uint64_t b) {
+  uint64_t ab = a ^ b;
+  return libcrux_sha3_portable_keccak_rotate_left_cb12(ab);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a
+with const generics
+- LEFT= 61
+- RIGHT= 3
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb12(uint64_t a, uint64_t b) {
+  return libcrux_sha3_portable_keccak__vxarq_u64_4212(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left
+with const generics
+- LEFT= 28
+- RIGHT= 36
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_rotate_left_cb13(uint64_t x) {
+  return x << (uint32_t)(int32_t)28 | x >> (uint32_t)(int32_t)36;
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64
+with const generics
+- LEFT= 28
+- RIGHT= 36
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak__vxarq_u64_4213(uint64_t a, uint64_t b) {
+  uint64_t ab = a ^ b;
+  return libcrux_sha3_portable_keccak_rotate_left_cb13(ab);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a
+with const generics
+- LEFT= 28
+- RIGHT= 36
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb13(uint64_t a, uint64_t b) {
+  return libcrux_sha3_portable_keccak__vxarq_u64_4213(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left
+with const generics
+- LEFT= 55
+- RIGHT= 9
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_rotate_left_cb14(uint64_t x) {
+  return x << (uint32_t)(int32_t)55 | x >> (uint32_t)(int32_t)9;
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64
+with const generics
+- LEFT= 55
+- RIGHT= 9
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak__vxarq_u64_4214(uint64_t a, uint64_t b) {
+  uint64_t ab = a ^ b;
+  return libcrux_sha3_portable_keccak_rotate_left_cb14(ab);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a
+with const generics
+- LEFT= 55
+- RIGHT= 9
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb14(uint64_t a, uint64_t b) {
+  return libcrux_sha3_portable_keccak__vxarq_u64_4214(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left
+with const generics
+- LEFT= 25
+- RIGHT= 39
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_rotate_left_cb15(uint64_t x) {
+  return x << (uint32_t)(int32_t)25 | x >> (uint32_t)(int32_t)39;
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64
+with const generics
+- LEFT= 25
+- RIGHT= 39
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak__vxarq_u64_4215(uint64_t a, uint64_t b) {
+  uint64_t ab = a ^ b;
+  return libcrux_sha3_portable_keccak_rotate_left_cb15(ab);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a
+with const generics
+- LEFT= 25
+- RIGHT= 39
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb15(uint64_t a, uint64_t b) {
+  return libcrux_sha3_portable_keccak__vxarq_u64_4215(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left
+with const generics
+- LEFT= 21
+- RIGHT= 43
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_rotate_left_cb16(uint64_t x) {
+  return x << (uint32_t)(int32_t)21 | x >> (uint32_t)(int32_t)43;
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64
+with const generics
+- LEFT= 21
+- RIGHT= 43
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak__vxarq_u64_4216(uint64_t a, uint64_t b) {
+  uint64_t ab = a ^ b;
+  return libcrux_sha3_portable_keccak_rotate_left_cb16(ab);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a
+with const generics
+- LEFT= 21
+- RIGHT= 43
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb16(uint64_t a, uint64_t b) {
+  return libcrux_sha3_portable_keccak__vxarq_u64_4216(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left
+with const generics
+- LEFT= 56
+- RIGHT= 8
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_rotate_left_cb17(uint64_t x) {
+  return x << (uint32_t)(int32_t)56 | x >> (uint32_t)(int32_t)8;
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64
+with const generics
+- LEFT= 56
+- RIGHT= 8
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak__vxarq_u64_4217(uint64_t a, uint64_t b) {
+  uint64_t ab = a ^ b;
+  return libcrux_sha3_portable_keccak_rotate_left_cb17(ab);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a
+with const generics
+- LEFT= 56
+- RIGHT= 8
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb17(uint64_t a, uint64_t b) {
+  return libcrux_sha3_portable_keccak__vxarq_u64_4217(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left
+with const generics
+- LEFT= 27
+- RIGHT= 37
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_rotate_left_cb18(uint64_t x) {
+  return x << (uint32_t)(int32_t)27 | x >> (uint32_t)(int32_t)37;
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64
+with const generics
+- LEFT= 27
+- RIGHT= 37
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak__vxarq_u64_4218(uint64_t a, uint64_t b) {
+  uint64_t ab = a ^ b;
+  return libcrux_sha3_portable_keccak_rotate_left_cb18(ab);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a
+with const generics
+- LEFT= 27
+- RIGHT= 37
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb18(uint64_t a, uint64_t b) {
+  return libcrux_sha3_portable_keccak__vxarq_u64_4218(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left
+with const generics
+- LEFT= 20
+- RIGHT= 44
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_rotate_left_cb19(uint64_t x) {
+  return x << (uint32_t)(int32_t)20 | x >> (uint32_t)(int32_t)44;
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64
+with const generics
+- LEFT= 20
+- RIGHT= 44
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak__vxarq_u64_4219(uint64_t a, uint64_t b) {
+  uint64_t ab = a ^ b;
+  return libcrux_sha3_portable_keccak_rotate_left_cb19(ab);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a
+with const generics
+- LEFT= 20
+- RIGHT= 44
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb19(uint64_t a, uint64_t b) {
+  return libcrux_sha3_portable_keccak__vxarq_u64_4219(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left
+with const generics
+- LEFT= 39
+- RIGHT= 25
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_rotate_left_cb20(uint64_t x) {
+  return x << (uint32_t)(int32_t)39 | x >> (uint32_t)(int32_t)25;
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64
+with const generics
+- LEFT= 39
+- RIGHT= 25
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak__vxarq_u64_4220(uint64_t a, uint64_t b) {
+  uint64_t ab = a ^ b;
+  return libcrux_sha3_portable_keccak_rotate_left_cb20(ab);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a
+with const generics
+- LEFT= 39
+- RIGHT= 25
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb20(uint64_t a, uint64_t b) {
+  return libcrux_sha3_portable_keccak__vxarq_u64_4220(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left
+with const generics
+- LEFT= 8
+- RIGHT= 56
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_rotate_left_cb21(uint64_t x) {
+  return x << (uint32_t)(int32_t)8 | x >> (uint32_t)(int32_t)56;
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64
+with const generics
+- LEFT= 8
+- RIGHT= 56
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak__vxarq_u64_4221(uint64_t a, uint64_t b) {
+  uint64_t ab = a ^ b;
+  return libcrux_sha3_portable_keccak_rotate_left_cb21(ab);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a
+with const generics
+- LEFT= 8
+- RIGHT= 56
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb21(uint64_t a, uint64_t b) {
+  return libcrux_sha3_portable_keccak__vxarq_u64_4221(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left
+with const generics
+- LEFT= 14
+- RIGHT= 50
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_rotate_left_cb22(uint64_t x) {
+  return x << (uint32_t)(int32_t)14 | x >> (uint32_t)(int32_t)50;
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64
+with const generics
+- LEFT= 14
+- RIGHT= 50
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak__vxarq_u64_4222(uint64_t a, uint64_t b) {
+  uint64_t ab = a ^ b;
+  return libcrux_sha3_portable_keccak_rotate_left_cb22(ab);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a
+with const generics
+- LEFT= 14
+- RIGHT= 50
+*/
+static KRML_MUSTINLINE uint64_t
+libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb22(uint64_t a, uint64_t b) {
+  return libcrux_sha3_portable_keccak__vxarq_u64_4222(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.theta_rho
+with types uint64_t
+with const generics
+- N= 1
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_theta_rho_16(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s) {
+  uint64_t c[5U] = {
+      libcrux_sha3_portable_keccak_xor5_5a(s->st[0U][0U], s->st[1U][0U],
+                                           s->st[2U][0U], s->st[3U][0U],
+                                           s->st[4U][0U]),
+      libcrux_sha3_portable_keccak_xor5_5a(s->st[0U][1U], s->st[1U][1U],
+                                           s->st[2U][1U], s->st[3U][1U],
+                                           s->st[4U][1U]),
+      libcrux_sha3_portable_keccak_xor5_5a(s->st[0U][2U], s->st[1U][2U],
+                                           s->st[2U][2U], s->st[3U][2U],
+                                           s->st[4U][2U]),
+      libcrux_sha3_portable_keccak_xor5_5a(s->st[0U][3U], s->st[1U][3U],
+                                           s->st[2U][3U], s->st[3U][3U],
+                                           s->st[4U][3U]),
+      libcrux_sha3_portable_keccak_xor5_5a(s->st[0U][4U], s->st[1U][4U],
+                                           s->st[2U][4U], s->st[3U][4U],
+                                           s->st[4U][4U])};
+  uint64_t uu____0 = libcrux_sha3_portable_keccak_rotate_left1_and_xor_5a(
+      c[((size_t)0U + (size_t)4U) % (size_t)5U],
+      c[((size_t)0U + (size_t)1U) % (size_t)5U]);
+  uint64_t uu____1 = libcrux_sha3_portable_keccak_rotate_left1_and_xor_5a(
+      c[((size_t)1U + (size_t)4U) % (size_t)5U],
+      c[((size_t)1U + (size_t)1U) % (size_t)5U]);
+  uint64_t uu____2 = libcrux_sha3_portable_keccak_rotate_left1_and_xor_5a(
+      c[((size_t)2U + (size_t)4U) % (size_t)5U],
+      c[((size_t)2U + (size_t)1U) % (size_t)5U]);
+  uint64_t uu____3 = libcrux_sha3_portable_keccak_rotate_left1_and_xor_5a(
+      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____0, uu____1, uu____2, uu____3,
+                    libcrux_sha3_portable_keccak_rotate_left1_and_xor_5a(
+                        c[((size_t)4U + (size_t)4U) % (size_t)5U],
+                        c[((size_t)4U + (size_t)1U) % (size_t)5U])};
+  s->st[0U][0U] = libcrux_sha3_portable_keccak_xor_5a(s->st[0U][0U], t[0U]);
+  s->st[1U][0U] =
+      libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb(s->st[1U][0U], t[0U]);
+  s->st[2U][0U] =
+      libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb0(s->st[2U][0U], t[0U]);
+  s->st[3U][0U] =
+      libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb1(s->st[3U][0U], t[0U]);
+  s->st[4U][0U] =
+      libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb2(s->st[4U][0U], t[0U]);
+  s->st[0U][1U] =
+      libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb3(s->st[0U][1U], t[1U]);
+  s->st[1U][1U] =
+      libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb4(s->st[1U][1U], t[1U]);
+  s->st[2U][1U] =
+      libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb5(s->st[2U][1U], t[1U]);
+  s->st[3U][1U] =
+      libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb6(s->st[3U][1U], t[1U]);
+  s->st[4U][1U] =
+      libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb7(s->st[4U][1U], t[1U]);
+  s->st[0U][2U] =
+      libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb8(s->st[0U][2U], t[2U]);
+  s->st[1U][2U] =
+      libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb9(s->st[1U][2U], t[2U]);
+  s->st[2U][2U] =
+      libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb10(s->st[2U][2U], t[2U]);
+  s->st[3U][2U] =
+      libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb11(s->st[3U][2U], t[2U]);
+  s->st[4U][2U] =
+      libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb12(s->st[4U][2U], t[2U]);
+  s->st[0U][3U] =
+      libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb13(s->st[0U][3U], t[3U]);
+  s->st[1U][3U] =
+      libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb14(s->st[1U][3U], t[3U]);
+  s->st[2U][3U] =
+      libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb15(s->st[2U][3U], t[3U]);
+  s->st[3U][3U] =
+      libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb16(s->st[3U][3U], t[3U]);
+  s->st[4U][3U] =
+      libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb17(s->st[4U][3U], t[3U]);
+  s->st[0U][4U] =
+      libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb18(s->st[0U][4U], t[4U]);
+  s->st[1U][4U] =
+      libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb19(s->st[1U][4U], t[4U]);
+  s->st[2U][4U] =
+      libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb20(s->st[2U][4U], t[4U]);
+  s->st[3U][4U] =
+      libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb21(s->st[3U][4U], t[4U]);
+  uint64_t uu____27 =
+      libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb22(s->st[4U][4U], t[4U]);
+  s->st[4U][4U] = uu____27;
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.pi
+with types uint64_t
+with const generics
+- N= 1
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_pi_1d(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s) {
+  uint64_t old[5U][5U];
+  memcpy(old, s->st, (size_t)5U * sizeof(uint64_t[5U]));
+  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];
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.chi
+with types uint64_t
+with const generics
+- N= 1
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_chi_12(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s) {
+  uint64_t old[5U][5U];
+  memcpy(old, s->st, (size_t)5U * sizeof(uint64_t[5U]));
+  for (size_t i0 = (size_t)0U; i0 < (size_t)5U; i0++) {
+    size_t i1 = i0;
+    for (size_t i = (size_t)0U; i < (size_t)5U; i++) {
+      size_t j = i;
+      s->st[i1][j] = libcrux_sha3_portable_keccak_and_not_xor_5a(
+          s->st[i1][j], old[i1][(j + (size_t)2U) % (size_t)5U],
+          old[i1][(j + (size_t)1U) % (size_t)5U]);
+    }
+  }
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.iota
+with types uint64_t
+with const generics
+- N= 1
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_iota_62(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, size_t i) {
+  s->st[0U][0U] = libcrux_sha3_portable_keccak_xor_constant_5a(
+      s->st[0U][0U], libcrux_sha3_generic_keccak_ROUNDCONSTANTS[i]);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.keccakf1600
+with types uint64_t
+with const generics
+- N= 1
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_keccakf1600_21(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s) {
+  for (size_t i = (size_t)0U; i < (size_t)24U; i++) {
+    size_t i0 = i;
+    libcrux_sha3_generic_keccak_theta_rho_16(s);
+    libcrux_sha3_generic_keccak_pi_1d(s);
+    libcrux_sha3_generic_keccak_chi_12(s);
+    libcrux_sha3_generic_keccak_iota_62(s, i0);
+  }
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.absorb_block
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 72
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_block_df(
+    libcrux_sha3_generic_keccak_KeccakState_48 *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_load_block_5a_b8(uu____0, uu____1);
+  libcrux_sha3_generic_keccak_keccakf1600_21(s);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full
+with const generics
+- RATE= 72
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_df(
+    uint64_t (*s)[5U], uint8_t blocks[1U][200U]) {
+  Eurydice_slice buf[1U] = {
+      Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t)};
+  libcrux_sha3_portable_keccak_load_block_2c(s, buf);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full_5a
+with const generics
+- RATE= 72
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_5a_d2(
+    uint64_t (*a)[5U], uint8_t b[1U][200U]) {
+  uint64_t(*uu____0)[5U] = a;
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_b[1U][200U];
+  memcpy(copy_of_b, b, (size_t)1U * sizeof(uint8_t[200U]));
+  libcrux_sha3_portable_keccak_load_block_full_df(uu____0, copy_of_b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 72
+- DELIM= 6
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_c7(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice last[1U]) {
+  size_t last_len = Eurydice_slice_len(last[0U], uint8_t);
+  uint8_t blocks[1U][200U] = {{0U}};
+  for (size_t i = (size_t)0U; i < (size_t)1U; i++) {
+    size_t i0 = i;
+    if (last_len > (size_t)0U) {
+      Eurydice_slice uu____0 = Eurydice_array_to_subslice2(
+          blocks[i0], (size_t)0U, last_len, uint8_t);
+      Eurydice_slice_copy(uu____0, last[i0], uint8_t);
+    }
+    blocks[i0][last_len] = 6U;
+    size_t uu____1 = i0;
+    size_t uu____2 = (size_t)72U - (size_t)1U;
+    blocks[uu____1][uu____2] = (uint32_t)blocks[uu____1][uu____2] | 128U;
+  }
+  uint64_t(*uu____3)[5U] = s->st;
+  uint8_t uu____4[1U][200U];
+  memcpy(uu____4, blocks, (size_t)1U * sizeof(uint8_t[200U]));
+  libcrux_sha3_portable_keccak_load_block_full_5a_d2(uu____3, uu____4);
+  libcrux_sha3_generic_keccak_keccakf1600_21(s);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.store_block
+with const generics
+- RATE= 72
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_58(
+    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_subslice2(
+        out[0U], (size_t)8U * i0, (size_t)8U * i0 + (size_t)8U, uint8_t);
+    uint8_t ret[8U];
+    core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret);
+    Eurydice_slice_copy(
+        uu____0, Eurydice_array_to_slice((size_t)8U, ret, uint8_t), uint8_t);
+  }
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full
+with const generics
+- RATE= 72
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_full_2d(
+    uint64_t (*s)[5U], uint8_t ret[1U][200U]) {
+  uint8_t out[200U] = {0U};
+  Eurydice_slice buf[1U] = {
+      Eurydice_array_to_slice((size_t)200U, out, uint8_t)};
+  libcrux_sha3_portable_keccak_store_block_58(s, buf);
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_out[200U];
+  memcpy(copy_of_out, out, (size_t)200U * sizeof(uint8_t));
+  memcpy(ret[0U], copy_of_out, (size_t)200U * sizeof(uint8_t));
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full_5a
+with const generics
+- RATE= 72
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_full_5a_29(
+    uint64_t (*a)[5U], uint8_t ret[1U][200U]) {
+  libcrux_sha3_portable_keccak_store_block_full_2d(a, ret);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_and_last
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 72
+*/
+static KRML_MUSTINLINE void
+libcrux_sha3_generic_keccak_squeeze_first_and_last_c5(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) {
+  uint8_t b[1U][200U];
+  libcrux_sha3_portable_keccak_store_block_full_5a_29(s->st, b);
+  for (size_t i = (size_t)0U; i < (size_t)1U; i++) {
+    size_t i0 = i;
+    Eurydice_slice uu____0 = out[i0];
+    uint8_t *uu____1 = b[i0];
+    core_ops_range_Range_b3 lit;
+    lit.start = (size_t)0U;
+    lit.end = Eurydice_slice_len(out[i0], uint8_t);
+    Eurydice_slice_copy(
+        uu____0,
+        Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t,
+                                   core_ops_range_Range_b3),
+        uint8_t);
+  }
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.store_block_5a
+with const generics
+- RATE= 72
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_5a_59(
+    uint64_t (*a)[5U], Eurydice_slice b[1U]) {
+  libcrux_sha3_portable_keccak_store_block_58(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_block
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 72
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_first_block_84(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) {
+  libcrux_sha3_portable_keccak_store_block_5a_59(s->st, out);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_next_block
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 72
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_next_block_fc(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) {
+  libcrux_sha3_generic_keccak_keccakf1600_21(s);
+  libcrux_sha3_portable_keccak_store_block_5a_59(s->st, out);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_last
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 72
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_last_cf(
+    libcrux_sha3_generic_keccak_KeccakState_48 s, Eurydice_slice out[1U]) {
+  libcrux_sha3_generic_keccak_keccakf1600_21(&s);
+  uint8_t b[1U][200U];
+  libcrux_sha3_portable_keccak_store_block_full_5a_29(s.st, b);
+  for (size_t i = (size_t)0U; i < (size_t)1U; i++) {
+    size_t i0 = i;
+    Eurydice_slice uu____0 = out[i0];
+    uint8_t *uu____1 = b[i0];
+    core_ops_range_Range_b3 lit;
+    lit.start = (size_t)0U;
+    lit.end = Eurydice_slice_len(out[i0], uint8_t);
+    Eurydice_slice_copy(
+        uu____0,
+        Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t,
+                                   core_ops_range_Range_b3),
+        uint8_t);
+  }
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.keccak
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 72
+- DELIM= 6
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_keccak_e9(
+    Eurydice_slice data[1U], Eurydice_slice out[1U]) {
+  libcrux_sha3_generic_keccak_KeccakState_48 s =
+      libcrux_sha3_generic_keccak_new_1e_f4();
+  for (size_t i = (size_t)0U;
+       i < Eurydice_slice_len(data[0U], uint8_t) / (size_t)72U; i++) {
+    size_t i0 = i;
+    libcrux_sha3_generic_keccak_KeccakState_48 *uu____0 = &s;
+    /* Passing arrays by value in Rust generates a copy in C */
+    Eurydice_slice copy_of_data[1U];
+    memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice));
+    Eurydice_slice ret[1U];
+    libcrux_sha3_portable_keccak_slice_n_5a(copy_of_data, i0 * (size_t)72U,
+                                            (size_t)72U, ret);
+    libcrux_sha3_generic_keccak_absorb_block_df(uu____0, ret);
+  }
+  size_t rem = Eurydice_slice_len(data[0U], uint8_t) % (size_t)72U;
+  libcrux_sha3_generic_keccak_KeccakState_48 *uu____2 = &s;
+  /* Passing arrays by value in Rust generates a copy in C */
+  Eurydice_slice copy_of_data[1U];
+  memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice));
+  Eurydice_slice ret[1U];
+  libcrux_sha3_portable_keccak_slice_n_5a(
+      copy_of_data, Eurydice_slice_len(data[0U], uint8_t) - rem, rem, ret);
+  libcrux_sha3_generic_keccak_absorb_final_c7(uu____2, ret);
+  size_t outlen = Eurydice_slice_len(out[0U], uint8_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_c5(&s, out);
+  } else {
+    Eurydice_slice_uint8_t_1size_t__x2 uu____4 =
+        libcrux_sha3_portable_keccak_split_at_mut_n_5a(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_84(&s, o0);
+    core_ops_range_Range_b3 iter =
+        core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter(
+            (CLITERAL(core_ops_range_Range_b3){.start = (size_t)1U,
+                                               .end = blocks}),
+            core_ops_range_Range_b3, core_ops_range_Range_b3);
+    while (true) {
+      if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next(
+              &iter, size_t, Option_b3)
+              .tag == None) {
+        break;
+      } else {
+        Eurydice_slice_uint8_t_1size_t__x2 uu____5 =
+            libcrux_sha3_portable_keccak_split_at_mut_n_5a(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_fc(&s, o);
+        memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice));
+      }
+    }
+    if (last < outlen) {
+      libcrux_sha3_generic_keccak_squeeze_last_cf(s, o1);
+    }
+  }
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable.keccakx1
+with const generics
+- RATE= 72
+- DELIM= 6
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccakx1_ce(
+    Eurydice_slice data[1U], Eurydice_slice out[1U]) {
+  /* Passing arrays by value in Rust generates a copy in C */
+  Eurydice_slice copy_of_data[1U];
+  memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice));
+  libcrux_sha3_generic_keccak_keccak_e9(copy_of_data, out);
+}
+
+/**
+ A portable SHA3 512 implementation.
+*/
+static KRML_MUSTINLINE 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_ce(buf0, buf);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.load_block
+with const generics
+- RATE= 136
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_2c0(
+    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 uu____0[8U];
+    Result_56 dst;
+    Eurydice_slice_to_array2(
+        &dst,
+        Eurydice_slice_subslice2(blocks[0U], (size_t)8U * i0,
+                                 (size_t)8U * i0 + (size_t)8U, uint8_t),
+        Eurydice_slice, uint8_t[8U]);
+    unwrap_41_ac(dst, uu____0);
+    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] ^ core_num__u64_9__from_le_bytes(uu____0);
+  }
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.load_block_5a
+with const generics
+- RATE= 136
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_5a_b80(
+    uint64_t (*a)[5U], Eurydice_slice b[1U]) {
+  uint64_t(*uu____0)[5U] = a;
+  /* Passing arrays by value in Rust generates a copy in C */
+  Eurydice_slice copy_of_b[1U];
+  memcpy(copy_of_b, b, (size_t)1U * sizeof(Eurydice_slice));
+  libcrux_sha3_portable_keccak_load_block_2c0(uu____0, copy_of_b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.absorb_block
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 136
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_block_df0(
+    libcrux_sha3_generic_keccak_KeccakState_48 *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_load_block_5a_b80(uu____0, uu____1);
+  libcrux_sha3_generic_keccak_keccakf1600_21(s);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full
+with const generics
+- RATE= 136
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_df0(
+    uint64_t (*s)[5U], uint8_t blocks[1U][200U]) {
+  Eurydice_slice buf[1U] = {
+      Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t)};
+  libcrux_sha3_portable_keccak_load_block_2c0(s, buf);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full_5a
+with const generics
+- RATE= 136
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_5a_d20(
+    uint64_t (*a)[5U], uint8_t b[1U][200U]) {
+  uint64_t(*uu____0)[5U] = a;
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_b[1U][200U];
+  memcpy(copy_of_b, b, (size_t)1U * sizeof(uint8_t[200U]));
+  libcrux_sha3_portable_keccak_load_block_full_df0(uu____0, copy_of_b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 136
+- DELIM= 6
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_c70(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice last[1U]) {
+  size_t last_len = Eurydice_slice_len(last[0U], uint8_t);
+  uint8_t blocks[1U][200U] = {{0U}};
+  for (size_t i = (size_t)0U; i < (size_t)1U; i++) {
+    size_t i0 = i;
+    if (last_len > (size_t)0U) {
+      Eurydice_slice uu____0 = Eurydice_array_to_subslice2(
+          blocks[i0], (size_t)0U, last_len, uint8_t);
+      Eurydice_slice_copy(uu____0, last[i0], uint8_t);
+    }
+    blocks[i0][last_len] = 6U;
+    size_t uu____1 = i0;
+    size_t uu____2 = (size_t)136U - (size_t)1U;
+    blocks[uu____1][uu____2] = (uint32_t)blocks[uu____1][uu____2] | 128U;
+  }
+  uint64_t(*uu____3)[5U] = s->st;
+  uint8_t uu____4[1U][200U];
+  memcpy(uu____4, blocks, (size_t)1U * sizeof(uint8_t[200U]));
+  libcrux_sha3_portable_keccak_load_block_full_5a_d20(uu____3, uu____4);
+  libcrux_sha3_generic_keccak_keccakf1600_21(s);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.store_block
+with const generics
+- RATE= 136
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_580(
+    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_subslice2(
+        out[0U], (size_t)8U * i0, (size_t)8U * i0 + (size_t)8U, uint8_t);
+    uint8_t ret[8U];
+    core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret);
+    Eurydice_slice_copy(
+        uu____0, Eurydice_array_to_slice((size_t)8U, ret, uint8_t), uint8_t);
+  }
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full
+with const generics
+- RATE= 136
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_full_2d0(
+    uint64_t (*s)[5U], uint8_t ret[1U][200U]) {
+  uint8_t out[200U] = {0U};
+  Eurydice_slice buf[1U] = {
+      Eurydice_array_to_slice((size_t)200U, out, uint8_t)};
+  libcrux_sha3_portable_keccak_store_block_580(s, buf);
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_out[200U];
+  memcpy(copy_of_out, out, (size_t)200U * sizeof(uint8_t));
+  memcpy(ret[0U], copy_of_out, (size_t)200U * sizeof(uint8_t));
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full_5a
+with const generics
+- RATE= 136
+*/
+static KRML_MUSTINLINE void
+libcrux_sha3_portable_keccak_store_block_full_5a_290(uint64_t (*a)[5U],
+                                                     uint8_t ret[1U][200U]) {
+  libcrux_sha3_portable_keccak_store_block_full_2d0(a, ret);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_and_last
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 136
+*/
+static KRML_MUSTINLINE void
+libcrux_sha3_generic_keccak_squeeze_first_and_last_c50(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) {
+  uint8_t b[1U][200U];
+  libcrux_sha3_portable_keccak_store_block_full_5a_290(s->st, b);
+  for (size_t i = (size_t)0U; i < (size_t)1U; i++) {
+    size_t i0 = i;
+    Eurydice_slice uu____0 = out[i0];
+    uint8_t *uu____1 = b[i0];
+    core_ops_range_Range_b3 lit;
+    lit.start = (size_t)0U;
+    lit.end = Eurydice_slice_len(out[i0], uint8_t);
+    Eurydice_slice_copy(
+        uu____0,
+        Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t,
+                                   core_ops_range_Range_b3),
+        uint8_t);
+  }
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.store_block_5a
+with const generics
+- RATE= 136
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_5a_590(
+    uint64_t (*a)[5U], Eurydice_slice b[1U]) {
+  libcrux_sha3_portable_keccak_store_block_580(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_block
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 136
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_first_block_840(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) {
+  libcrux_sha3_portable_keccak_store_block_5a_590(s->st, out);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_next_block
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 136
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_next_block_fc0(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) {
+  libcrux_sha3_generic_keccak_keccakf1600_21(s);
+  libcrux_sha3_portable_keccak_store_block_5a_590(s->st, out);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_last
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 136
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_last_cf0(
+    libcrux_sha3_generic_keccak_KeccakState_48 s, Eurydice_slice out[1U]) {
+  libcrux_sha3_generic_keccak_keccakf1600_21(&s);
+  uint8_t b[1U][200U];
+  libcrux_sha3_portable_keccak_store_block_full_5a_290(s.st, b);
+  for (size_t i = (size_t)0U; i < (size_t)1U; i++) {
+    size_t i0 = i;
+    Eurydice_slice uu____0 = out[i0];
+    uint8_t *uu____1 = b[i0];
+    core_ops_range_Range_b3 lit;
+    lit.start = (size_t)0U;
+    lit.end = Eurydice_slice_len(out[i0], uint8_t);
+    Eurydice_slice_copy(
+        uu____0,
+        Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t,
+                                   core_ops_range_Range_b3),
+        uint8_t);
+  }
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.keccak
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 136
+- DELIM= 6
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_keccak_e90(
+    Eurydice_slice data[1U], Eurydice_slice out[1U]) {
+  libcrux_sha3_generic_keccak_KeccakState_48 s =
+      libcrux_sha3_generic_keccak_new_1e_f4();
+  for (size_t i = (size_t)0U;
+       i < Eurydice_slice_len(data[0U], uint8_t) / (size_t)136U; i++) {
+    size_t i0 = i;
+    libcrux_sha3_generic_keccak_KeccakState_48 *uu____0 = &s;
+    /* Passing arrays by value in Rust generates a copy in C */
+    Eurydice_slice copy_of_data[1U];
+    memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice));
+    Eurydice_slice ret[1U];
+    libcrux_sha3_portable_keccak_slice_n_5a(copy_of_data, i0 * (size_t)136U,
+                                            (size_t)136U, ret);
+    libcrux_sha3_generic_keccak_absorb_block_df0(uu____0, ret);
+  }
+  size_t rem = Eurydice_slice_len(data[0U], uint8_t) % (size_t)136U;
+  libcrux_sha3_generic_keccak_KeccakState_48 *uu____2 = &s;
+  /* Passing arrays by value in Rust generates a copy in C */
+  Eurydice_slice copy_of_data[1U];
+  memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice));
+  Eurydice_slice ret[1U];
+  libcrux_sha3_portable_keccak_slice_n_5a(
+      copy_of_data, Eurydice_slice_len(data[0U], uint8_t) - rem, rem, ret);
+  libcrux_sha3_generic_keccak_absorb_final_c70(uu____2, ret);
+  size_t outlen = Eurydice_slice_len(out[0U], uint8_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_c50(&s, out);
+  } else {
+    Eurydice_slice_uint8_t_1size_t__x2 uu____4 =
+        libcrux_sha3_portable_keccak_split_at_mut_n_5a(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_840(&s, o0);
+    core_ops_range_Range_b3 iter =
+        core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter(
+            (CLITERAL(core_ops_range_Range_b3){.start = (size_t)1U,
+                                               .end = blocks}),
+            core_ops_range_Range_b3, core_ops_range_Range_b3);
+    while (true) {
+      if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next(
+              &iter, size_t, Option_b3)
+              .tag == None) {
+        break;
+      } else {
+        Eurydice_slice_uint8_t_1size_t__x2 uu____5 =
+            libcrux_sha3_portable_keccak_split_at_mut_n_5a(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_fc0(&s, o);
+        memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice));
+      }
+    }
+    if (last < outlen) {
+      libcrux_sha3_generic_keccak_squeeze_last_cf0(s, o1);
+    }
+  }
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable.keccakx1
+with const generics
+- RATE= 136
+- DELIM= 6
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccakx1_ce0(
+    Eurydice_slice data[1U], Eurydice_slice out[1U]) {
+  /* Passing arrays by value in Rust generates a copy in C */
+  Eurydice_slice copy_of_data[1U];
+  memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice));
+  libcrux_sha3_generic_keccak_keccak_e90(copy_of_data, out);
+}
+
+/**
+ A portable SHA3 256 implementation.
+*/
+static KRML_MUSTINLINE 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_ce0(buf0, buf);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 136
+- DELIM= 31
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_c71(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice last[1U]) {
+  size_t last_len = Eurydice_slice_len(last[0U], uint8_t);
+  uint8_t blocks[1U][200U] = {{0U}};
+  for (size_t i = (size_t)0U; i < (size_t)1U; i++) {
+    size_t i0 = i;
+    if (last_len > (size_t)0U) {
+      Eurydice_slice uu____0 = Eurydice_array_to_subslice2(
+          blocks[i0], (size_t)0U, last_len, uint8_t);
+      Eurydice_slice_copy(uu____0, last[i0], uint8_t);
+    }
+    blocks[i0][last_len] = 31U;
+    size_t uu____1 = i0;
+    size_t uu____2 = (size_t)136U - (size_t)1U;
+    blocks[uu____1][uu____2] = (uint32_t)blocks[uu____1][uu____2] | 128U;
+  }
+  uint64_t(*uu____3)[5U] = s->st;
+  uint8_t uu____4[1U][200U];
+  memcpy(uu____4, blocks, (size_t)1U * sizeof(uint8_t[200U]));
+  libcrux_sha3_portable_keccak_load_block_full_5a_d20(uu____3, uu____4);
+  libcrux_sha3_generic_keccak_keccakf1600_21(s);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.keccak
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 136
+- DELIM= 31
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_keccak_e91(
+    Eurydice_slice data[1U], Eurydice_slice out[1U]) {
+  libcrux_sha3_generic_keccak_KeccakState_48 s =
+      libcrux_sha3_generic_keccak_new_1e_f4();
+  for (size_t i = (size_t)0U;
+       i < Eurydice_slice_len(data[0U], uint8_t) / (size_t)136U; i++) {
+    size_t i0 = i;
+    libcrux_sha3_generic_keccak_KeccakState_48 *uu____0 = &s;
+    /* Passing arrays by value in Rust generates a copy in C */
+    Eurydice_slice copy_of_data[1U];
+    memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice));
+    Eurydice_slice ret[1U];
+    libcrux_sha3_portable_keccak_slice_n_5a(copy_of_data, i0 * (size_t)136U,
+                                            (size_t)136U, ret);
+    libcrux_sha3_generic_keccak_absorb_block_df0(uu____0, ret);
+  }
+  size_t rem = Eurydice_slice_len(data[0U], uint8_t) % (size_t)136U;
+  libcrux_sha3_generic_keccak_KeccakState_48 *uu____2 = &s;
+  /* Passing arrays by value in Rust generates a copy in C */
+  Eurydice_slice copy_of_data[1U];
+  memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice));
+  Eurydice_slice ret[1U];
+  libcrux_sha3_portable_keccak_slice_n_5a(
+      copy_of_data, Eurydice_slice_len(data[0U], uint8_t) - rem, rem, ret);
+  libcrux_sha3_generic_keccak_absorb_final_c71(uu____2, ret);
+  size_t outlen = Eurydice_slice_len(out[0U], uint8_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_c50(&s, out);
+  } else {
+    Eurydice_slice_uint8_t_1size_t__x2 uu____4 =
+        libcrux_sha3_portable_keccak_split_at_mut_n_5a(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_840(&s, o0);
+    core_ops_range_Range_b3 iter =
+        core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter(
+            (CLITERAL(core_ops_range_Range_b3){.start = (size_t)1U,
+                                               .end = blocks}),
+            core_ops_range_Range_b3, core_ops_range_Range_b3);
+    while (true) {
+      if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next(
+              &iter, size_t, Option_b3)
+              .tag == None) {
+        break;
+      } else {
+        Eurydice_slice_uint8_t_1size_t__x2 uu____5 =
+            libcrux_sha3_portable_keccak_split_at_mut_n_5a(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_fc0(&s, o);
+        memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice));
+      }
+    }
+    if (last < outlen) {
+      libcrux_sha3_generic_keccak_squeeze_last_cf0(s, o1);
+    }
+  }
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable.keccakx1
+with const generics
+- RATE= 136
+- DELIM= 31
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccakx1_ce1(
+    Eurydice_slice data[1U], Eurydice_slice out[1U]) {
+  /* Passing arrays by value in Rust generates a copy in C */
+  Eurydice_slice copy_of_data[1U];
+  memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice));
+  libcrux_sha3_generic_keccak_keccak_e91(copy_of_data, out);
+}
+
+/**
+ A portable SHAKE256 implementation.
+*/
+static KRML_MUSTINLINE 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_ce1(buf0, buf);
+}
+
+typedef libcrux_sha3_generic_keccak_KeccakState_48
+    libcrux_sha3_portable_KeccakState;
+
+/**
+ Create a new SHAKE-128 state object.
+*/
+static KRML_MUSTINLINE libcrux_sha3_generic_keccak_KeccakState_48
+libcrux_sha3_portable_incremental_shake128_init(void) {
+  return libcrux_sha3_generic_keccak_new_1e_f4();
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.load_block
+with const generics
+- RATE= 168
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_2c1(
+    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 uu____0[8U];
+    Result_56 dst;
+    Eurydice_slice_to_array2(
+        &dst,
+        Eurydice_slice_subslice2(blocks[0U], (size_t)8U * i0,
+                                 (size_t)8U * i0 + (size_t)8U, uint8_t),
+        Eurydice_slice, uint8_t[8U]);
+    unwrap_41_ac(dst, uu____0);
+    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] ^ core_num__u64_9__from_le_bytes(uu____0);
+  }
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full
+with const generics
+- RATE= 168
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_df1(
+    uint64_t (*s)[5U], uint8_t blocks[1U][200U]) {
+  Eurydice_slice buf[1U] = {
+      Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t)};
+  libcrux_sha3_portable_keccak_load_block_2c1(s, buf);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full_5a
+with const generics
+- RATE= 168
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_5a_d21(
+    uint64_t (*a)[5U], uint8_t b[1U][200U]) {
+  uint64_t(*uu____0)[5U] = a;
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_b[1U][200U];
+  memcpy(copy_of_b, b, (size_t)1U * sizeof(uint8_t[200U]));
+  libcrux_sha3_portable_keccak_load_block_full_df1(uu____0, copy_of_b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 168
+- DELIM= 31
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_c72(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice last[1U]) {
+  size_t last_len = Eurydice_slice_len(last[0U], uint8_t);
+  uint8_t blocks[1U][200U] = {{0U}};
+  for (size_t i = (size_t)0U; i < (size_t)1U; i++) {
+    size_t i0 = i;
+    if (last_len > (size_t)0U) {
+      Eurydice_slice uu____0 = Eurydice_array_to_subslice2(
+          blocks[i0], (size_t)0U, last_len, uint8_t);
+      Eurydice_slice_copy(uu____0, last[i0], uint8_t);
+    }
+    blocks[i0][last_len] = 31U;
+    size_t uu____1 = i0;
+    size_t uu____2 = (size_t)168U - (size_t)1U;
+    blocks[uu____1][uu____2] = (uint32_t)blocks[uu____1][uu____2] | 128U;
+  }
+  uint64_t(*uu____3)[5U] = s->st;
+  uint8_t uu____4[1U][200U];
+  memcpy(uu____4, blocks, (size_t)1U * sizeof(uint8_t[200U]));
+  libcrux_sha3_portable_keccak_load_block_full_5a_d21(uu____3, uu____4);
+  libcrux_sha3_generic_keccak_keccakf1600_21(s);
+}
+
+/**
+ Absorb
+*/
+static KRML_MUSTINLINE void
+libcrux_sha3_portable_incremental_shake128_absorb_final(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice data0) {
+  Eurydice_slice buf[1U] = {data0};
+  libcrux_sha3_generic_keccak_absorb_final_c72(s, buf);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.store_block
+with const generics
+- RATE= 168
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_581(
+    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_subslice2(
+        out[0U], (size_t)8U * i0, (size_t)8U * i0 + (size_t)8U, uint8_t);
+    uint8_t ret[8U];
+    core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret);
+    Eurydice_slice_copy(
+        uu____0, Eurydice_array_to_slice((size_t)8U, ret, uint8_t), uint8_t);
+  }
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.store_block_5a
+with const generics
+- RATE= 168
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_5a_591(
+    uint64_t (*a)[5U], Eurydice_slice b[1U]) {
+  libcrux_sha3_portable_keccak_store_block_581(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_next_block
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 168
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_next_block_fc1(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) {
+  libcrux_sha3_generic_keccak_keccakf1600_21(s);
+  libcrux_sha3_portable_keccak_store_block_5a_591(s->st, out);
+}
+
+/**
+ Squeeze another block
+*/
+static KRML_MUSTINLINE void
+libcrux_sha3_portable_incremental_shake128_squeeze_next_block(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out0) {
+  Eurydice_slice buf[1U] = {out0};
+  libcrux_sha3_generic_keccak_squeeze_next_block_fc1(s, buf);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_block
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 168
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_first_block_841(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) {
+  libcrux_sha3_portable_keccak_store_block_5a_591(s->st, out);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_three_blocks
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 168
+*/
+static KRML_MUSTINLINE void
+libcrux_sha3_generic_keccak_squeeze_first_three_blocks_cc(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) {
+  Eurydice_slice_uint8_t_1size_t__x2 uu____0 =
+      libcrux_sha3_portable_keccak_split_at_mut_n_5a(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_841(s, o0);
+  Eurydice_slice_uint8_t_1size_t__x2 uu____1 =
+      libcrux_sha3_portable_keccak_split_at_mut_n_5a(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_fc1(s, o1);
+  libcrux_sha3_generic_keccak_squeeze_next_block_fc1(s, o2);
+}
+
+/**
+ Squeeze three blocks
+*/
+static KRML_MUSTINLINE void
+libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out0) {
+  Eurydice_slice buf[1U] = {out0};
+  libcrux_sha3_generic_keccak_squeeze_first_three_blocks_cc(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;
+
+/**
+ Returns the output size of a digest.
+*/
+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;
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.load_block
+with const generics
+- RATE= 144
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_2c2(
+    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 uu____0[8U];
+    Result_56 dst;
+    Eurydice_slice_to_array2(
+        &dst,
+        Eurydice_slice_subslice2(blocks[0U], (size_t)8U * i0,
+                                 (size_t)8U * i0 + (size_t)8U, uint8_t),
+        Eurydice_slice, uint8_t[8U]);
+    unwrap_41_ac(dst, uu____0);
+    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] ^ core_num__u64_9__from_le_bytes(uu____0);
+  }
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.load_block_5a
+with const generics
+- RATE= 144
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_5a_b81(
+    uint64_t (*a)[5U], Eurydice_slice b[1U]) {
+  uint64_t(*uu____0)[5U] = a;
+  /* Passing arrays by value in Rust generates a copy in C */
+  Eurydice_slice copy_of_b[1U];
+  memcpy(copy_of_b, b, (size_t)1U * sizeof(Eurydice_slice));
+  libcrux_sha3_portable_keccak_load_block_2c2(uu____0, copy_of_b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.absorb_block
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 144
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_block_df1(
+    libcrux_sha3_generic_keccak_KeccakState_48 *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_load_block_5a_b81(uu____0, uu____1);
+  libcrux_sha3_generic_keccak_keccakf1600_21(s);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full
+with const generics
+- RATE= 144
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_df2(
+    uint64_t (*s)[5U], uint8_t blocks[1U][200U]) {
+  Eurydice_slice buf[1U] = {
+      Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t)};
+  libcrux_sha3_portable_keccak_load_block_2c2(s, buf);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full_5a
+with const generics
+- RATE= 144
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_5a_d22(
+    uint64_t (*a)[5U], uint8_t b[1U][200U]) {
+  uint64_t(*uu____0)[5U] = a;
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_b[1U][200U];
+  memcpy(copy_of_b, b, (size_t)1U * sizeof(uint8_t[200U]));
+  libcrux_sha3_portable_keccak_load_block_full_df2(uu____0, copy_of_b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 144
+- DELIM= 6
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_c73(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice last[1U]) {
+  size_t last_len = Eurydice_slice_len(last[0U], uint8_t);
+  uint8_t blocks[1U][200U] = {{0U}};
+  for (size_t i = (size_t)0U; i < (size_t)1U; i++) {
+    size_t i0 = i;
+    if (last_len > (size_t)0U) {
+      Eurydice_slice uu____0 = Eurydice_array_to_subslice2(
+          blocks[i0], (size_t)0U, last_len, uint8_t);
+      Eurydice_slice_copy(uu____0, last[i0], uint8_t);
+    }
+    blocks[i0][last_len] = 6U;
+    size_t uu____1 = i0;
+    size_t uu____2 = (size_t)144U - (size_t)1U;
+    blocks[uu____1][uu____2] = (uint32_t)blocks[uu____1][uu____2] | 128U;
+  }
+  uint64_t(*uu____3)[5U] = s->st;
+  uint8_t uu____4[1U][200U];
+  memcpy(uu____4, blocks, (size_t)1U * sizeof(uint8_t[200U]));
+  libcrux_sha3_portable_keccak_load_block_full_5a_d22(uu____3, uu____4);
+  libcrux_sha3_generic_keccak_keccakf1600_21(s);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.store_block
+with const generics
+- RATE= 144
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_582(
+    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_subslice2(
+        out[0U], (size_t)8U * i0, (size_t)8U * i0 + (size_t)8U, uint8_t);
+    uint8_t ret[8U];
+    core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret);
+    Eurydice_slice_copy(
+        uu____0, Eurydice_array_to_slice((size_t)8U, ret, uint8_t), uint8_t);
+  }
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full
+with const generics
+- RATE= 144
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_full_2d1(
+    uint64_t (*s)[5U], uint8_t ret[1U][200U]) {
+  uint8_t out[200U] = {0U};
+  Eurydice_slice buf[1U] = {
+      Eurydice_array_to_slice((size_t)200U, out, uint8_t)};
+  libcrux_sha3_portable_keccak_store_block_582(s, buf);
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_out[200U];
+  memcpy(copy_of_out, out, (size_t)200U * sizeof(uint8_t));
+  memcpy(ret[0U], copy_of_out, (size_t)200U * sizeof(uint8_t));
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full_5a
+with const generics
+- RATE= 144
+*/
+static KRML_MUSTINLINE void
+libcrux_sha3_portable_keccak_store_block_full_5a_291(uint64_t (*a)[5U],
+                                                     uint8_t ret[1U][200U]) {
+  libcrux_sha3_portable_keccak_store_block_full_2d1(a, ret);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_and_last
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 144
+*/
+static KRML_MUSTINLINE void
+libcrux_sha3_generic_keccak_squeeze_first_and_last_c51(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) {
+  uint8_t b[1U][200U];
+  libcrux_sha3_portable_keccak_store_block_full_5a_291(s->st, b);
+  for (size_t i = (size_t)0U; i < (size_t)1U; i++) {
+    size_t i0 = i;
+    Eurydice_slice uu____0 = out[i0];
+    uint8_t *uu____1 = b[i0];
+    core_ops_range_Range_b3 lit;
+    lit.start = (size_t)0U;
+    lit.end = Eurydice_slice_len(out[i0], uint8_t);
+    Eurydice_slice_copy(
+        uu____0,
+        Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t,
+                                   core_ops_range_Range_b3),
+        uint8_t);
+  }
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.store_block_5a
+with const generics
+- RATE= 144
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_5a_592(
+    uint64_t (*a)[5U], Eurydice_slice b[1U]) {
+  libcrux_sha3_portable_keccak_store_block_582(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_block
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 144
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_first_block_842(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) {
+  libcrux_sha3_portable_keccak_store_block_5a_592(s->st, out);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_next_block
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 144
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_next_block_fc2(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) {
+  libcrux_sha3_generic_keccak_keccakf1600_21(s);
+  libcrux_sha3_portable_keccak_store_block_5a_592(s->st, out);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_last
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 144
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_last_cf1(
+    libcrux_sha3_generic_keccak_KeccakState_48 s, Eurydice_slice out[1U]) {
+  libcrux_sha3_generic_keccak_keccakf1600_21(&s);
+  uint8_t b[1U][200U];
+  libcrux_sha3_portable_keccak_store_block_full_5a_291(s.st, b);
+  for (size_t i = (size_t)0U; i < (size_t)1U; i++) {
+    size_t i0 = i;
+    Eurydice_slice uu____0 = out[i0];
+    uint8_t *uu____1 = b[i0];
+    core_ops_range_Range_b3 lit;
+    lit.start = (size_t)0U;
+    lit.end = Eurydice_slice_len(out[i0], uint8_t);
+    Eurydice_slice_copy(
+        uu____0,
+        Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t,
+                                   core_ops_range_Range_b3),
+        uint8_t);
+  }
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.keccak
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 144
+- DELIM= 6
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_keccak_e92(
+    Eurydice_slice data[1U], Eurydice_slice out[1U]) {
+  libcrux_sha3_generic_keccak_KeccakState_48 s =
+      libcrux_sha3_generic_keccak_new_1e_f4();
+  for (size_t i = (size_t)0U;
+       i < Eurydice_slice_len(data[0U], uint8_t) / (size_t)144U; i++) {
+    size_t i0 = i;
+    libcrux_sha3_generic_keccak_KeccakState_48 *uu____0 = &s;
+    /* Passing arrays by value in Rust generates a copy in C */
+    Eurydice_slice copy_of_data[1U];
+    memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice));
+    Eurydice_slice ret[1U];
+    libcrux_sha3_portable_keccak_slice_n_5a(copy_of_data, i0 * (size_t)144U,
+                                            (size_t)144U, ret);
+    libcrux_sha3_generic_keccak_absorb_block_df1(uu____0, ret);
+  }
+  size_t rem = Eurydice_slice_len(data[0U], uint8_t) % (size_t)144U;
+  libcrux_sha3_generic_keccak_KeccakState_48 *uu____2 = &s;
+  /* Passing arrays by value in Rust generates a copy in C */
+  Eurydice_slice copy_of_data[1U];
+  memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice));
+  Eurydice_slice ret[1U];
+  libcrux_sha3_portable_keccak_slice_n_5a(
+      copy_of_data, Eurydice_slice_len(data[0U], uint8_t) - rem, rem, ret);
+  libcrux_sha3_generic_keccak_absorb_final_c73(uu____2, ret);
+  size_t outlen = Eurydice_slice_len(out[0U], uint8_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_c51(&s, out);
+  } else {
+    Eurydice_slice_uint8_t_1size_t__x2 uu____4 =
+        libcrux_sha3_portable_keccak_split_at_mut_n_5a(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_842(&s, o0);
+    core_ops_range_Range_b3 iter =
+        core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter(
+            (CLITERAL(core_ops_range_Range_b3){.start = (size_t)1U,
+                                               .end = blocks}),
+            core_ops_range_Range_b3, core_ops_range_Range_b3);
+    while (true) {
+      if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next(
+              &iter, size_t, Option_b3)
+              .tag == None) {
+        break;
+      } else {
+        Eurydice_slice_uint8_t_1size_t__x2 uu____5 =
+            libcrux_sha3_portable_keccak_split_at_mut_n_5a(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_fc2(&s, o);
+        memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice));
+      }
+    }
+    if (last < outlen) {
+      libcrux_sha3_generic_keccak_squeeze_last_cf1(s, o1);
+    }
+  }
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable.keccakx1
+with const generics
+- RATE= 144
+- DELIM= 6
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccakx1_ce2(
+    Eurydice_slice data[1U], Eurydice_slice out[1U]) {
+  /* Passing arrays by value in Rust generates a copy in C */
+  Eurydice_slice copy_of_data[1U];
+  memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice));
+  libcrux_sha3_generic_keccak_keccak_e92(copy_of_data, out);
+}
+
+/**
+ A portable SHA3 224 implementation.
+*/
+static KRML_MUSTINLINE 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_ce2(buf0, buf);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.load_block
+with const generics
+- RATE= 104
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_2c3(
+    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 uu____0[8U];
+    Result_56 dst;
+    Eurydice_slice_to_array2(
+        &dst,
+        Eurydice_slice_subslice2(blocks[0U], (size_t)8U * i0,
+                                 (size_t)8U * i0 + (size_t)8U, uint8_t),
+        Eurydice_slice, uint8_t[8U]);
+    unwrap_41_ac(dst, uu____0);
+    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] ^ core_num__u64_9__from_le_bytes(uu____0);
+  }
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.load_block_5a
+with const generics
+- RATE= 104
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_5a_b82(
+    uint64_t (*a)[5U], Eurydice_slice b[1U]) {
+  uint64_t(*uu____0)[5U] = a;
+  /* Passing arrays by value in Rust generates a copy in C */
+  Eurydice_slice copy_of_b[1U];
+  memcpy(copy_of_b, b, (size_t)1U * sizeof(Eurydice_slice));
+  libcrux_sha3_portable_keccak_load_block_2c3(uu____0, copy_of_b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.absorb_block
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 104
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_block_df2(
+    libcrux_sha3_generic_keccak_KeccakState_48 *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_load_block_5a_b82(uu____0, uu____1);
+  libcrux_sha3_generic_keccak_keccakf1600_21(s);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full
+with const generics
+- RATE= 104
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_df3(
+    uint64_t (*s)[5U], uint8_t blocks[1U][200U]) {
+  Eurydice_slice buf[1U] = {
+      Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t)};
+  libcrux_sha3_portable_keccak_load_block_2c3(s, buf);
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full_5a
+with const generics
+- RATE= 104
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_5a_d23(
+    uint64_t (*a)[5U], uint8_t b[1U][200U]) {
+  uint64_t(*uu____0)[5U] = a;
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_b[1U][200U];
+  memcpy(copy_of_b, b, (size_t)1U * sizeof(uint8_t[200U]));
+  libcrux_sha3_portable_keccak_load_block_full_df3(uu____0, copy_of_b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 104
+- DELIM= 6
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_c74(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice last[1U]) {
+  size_t last_len = Eurydice_slice_len(last[0U], uint8_t);
+  uint8_t blocks[1U][200U] = {{0U}};
+  for (size_t i = (size_t)0U; i < (size_t)1U; i++) {
+    size_t i0 = i;
+    if (last_len > (size_t)0U) {
+      Eurydice_slice uu____0 = Eurydice_array_to_subslice2(
+          blocks[i0], (size_t)0U, last_len, uint8_t);
+      Eurydice_slice_copy(uu____0, last[i0], uint8_t);
+    }
+    blocks[i0][last_len] = 6U;
+    size_t uu____1 = i0;
+    size_t uu____2 = (size_t)104U - (size_t)1U;
+    blocks[uu____1][uu____2] = (uint32_t)blocks[uu____1][uu____2] | 128U;
+  }
+  uint64_t(*uu____3)[5U] = s->st;
+  uint8_t uu____4[1U][200U];
+  memcpy(uu____4, blocks, (size_t)1U * sizeof(uint8_t[200U]));
+  libcrux_sha3_portable_keccak_load_block_full_5a_d23(uu____3, uu____4);
+  libcrux_sha3_generic_keccak_keccakf1600_21(s);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.store_block
+with const generics
+- RATE= 104
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_583(
+    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_subslice2(
+        out[0U], (size_t)8U * i0, (size_t)8U * i0 + (size_t)8U, uint8_t);
+    uint8_t ret[8U];
+    core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret);
+    Eurydice_slice_copy(
+        uu____0, Eurydice_array_to_slice((size_t)8U, ret, uint8_t), uint8_t);
+  }
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full
+with const generics
+- RATE= 104
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_full_2d2(
+    uint64_t (*s)[5U], uint8_t ret[1U][200U]) {
+  uint8_t out[200U] = {0U};
+  Eurydice_slice buf[1U] = {
+      Eurydice_array_to_slice((size_t)200U, out, uint8_t)};
+  libcrux_sha3_portable_keccak_store_block_583(s, buf);
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_out[200U];
+  memcpy(copy_of_out, out, (size_t)200U * sizeof(uint8_t));
+  memcpy(ret[0U], copy_of_out, (size_t)200U * sizeof(uint8_t));
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full_5a
+with const generics
+- RATE= 104
+*/
+static KRML_MUSTINLINE void
+libcrux_sha3_portable_keccak_store_block_full_5a_292(uint64_t (*a)[5U],
+                                                     uint8_t ret[1U][200U]) {
+  libcrux_sha3_portable_keccak_store_block_full_2d2(a, ret);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_and_last
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 104
+*/
+static KRML_MUSTINLINE void
+libcrux_sha3_generic_keccak_squeeze_first_and_last_c52(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) {
+  uint8_t b[1U][200U];
+  libcrux_sha3_portable_keccak_store_block_full_5a_292(s->st, b);
+  for (size_t i = (size_t)0U; i < (size_t)1U; i++) {
+    size_t i0 = i;
+    Eurydice_slice uu____0 = out[i0];
+    uint8_t *uu____1 = b[i0];
+    core_ops_range_Range_b3 lit;
+    lit.start = (size_t)0U;
+    lit.end = Eurydice_slice_len(out[i0], uint8_t);
+    Eurydice_slice_copy(
+        uu____0,
+        Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t,
+                                   core_ops_range_Range_b3),
+        uint8_t);
+  }
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.store_block_5a
+with const generics
+- RATE= 104
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_5a_593(
+    uint64_t (*a)[5U], Eurydice_slice b[1U]) {
+  libcrux_sha3_portable_keccak_store_block_583(a, b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_block
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 104
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_first_block_843(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) {
+  libcrux_sha3_portable_keccak_store_block_5a_593(s->st, out);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_next_block
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 104
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_next_block_fc3(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) {
+  libcrux_sha3_generic_keccak_keccakf1600_21(s);
+  libcrux_sha3_portable_keccak_store_block_5a_593(s->st, out);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_last
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 104
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_last_cf2(
+    libcrux_sha3_generic_keccak_KeccakState_48 s, Eurydice_slice out[1U]) {
+  libcrux_sha3_generic_keccak_keccakf1600_21(&s);
+  uint8_t b[1U][200U];
+  libcrux_sha3_portable_keccak_store_block_full_5a_292(s.st, b);
+  for (size_t i = (size_t)0U; i < (size_t)1U; i++) {
+    size_t i0 = i;
+    Eurydice_slice uu____0 = out[i0];
+    uint8_t *uu____1 = b[i0];
+    core_ops_range_Range_b3 lit;
+    lit.start = (size_t)0U;
+    lit.end = Eurydice_slice_len(out[i0], uint8_t);
+    Eurydice_slice_copy(
+        uu____0,
+        Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t,
+                                   core_ops_range_Range_b3),
+        uint8_t);
+  }
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.keccak
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 104
+- DELIM= 6
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_keccak_e93(
+    Eurydice_slice data[1U], Eurydice_slice out[1U]) {
+  libcrux_sha3_generic_keccak_KeccakState_48 s =
+      libcrux_sha3_generic_keccak_new_1e_f4();
+  for (size_t i = (size_t)0U;
+       i < Eurydice_slice_len(data[0U], uint8_t) / (size_t)104U; i++) {
+    size_t i0 = i;
+    libcrux_sha3_generic_keccak_KeccakState_48 *uu____0 = &s;
+    /* Passing arrays by value in Rust generates a copy in C */
+    Eurydice_slice copy_of_data[1U];
+    memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice));
+    Eurydice_slice ret[1U];
+    libcrux_sha3_portable_keccak_slice_n_5a(copy_of_data, i0 * (size_t)104U,
+                                            (size_t)104U, ret);
+    libcrux_sha3_generic_keccak_absorb_block_df2(uu____0, ret);
+  }
+  size_t rem = Eurydice_slice_len(data[0U], uint8_t) % (size_t)104U;
+  libcrux_sha3_generic_keccak_KeccakState_48 *uu____2 = &s;
+  /* Passing arrays by value in Rust generates a copy in C */
+  Eurydice_slice copy_of_data[1U];
+  memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice));
+  Eurydice_slice ret[1U];
+  libcrux_sha3_portable_keccak_slice_n_5a(
+      copy_of_data, Eurydice_slice_len(data[0U], uint8_t) - rem, rem, ret);
+  libcrux_sha3_generic_keccak_absorb_final_c74(uu____2, ret);
+  size_t outlen = Eurydice_slice_len(out[0U], uint8_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_c52(&s, out);
+  } else {
+    Eurydice_slice_uint8_t_1size_t__x2 uu____4 =
+        libcrux_sha3_portable_keccak_split_at_mut_n_5a(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_843(&s, o0);
+    core_ops_range_Range_b3 iter =
+        core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter(
+            (CLITERAL(core_ops_range_Range_b3){.start = (size_t)1U,
+                                               .end = blocks}),
+            core_ops_range_Range_b3, core_ops_range_Range_b3);
+    while (true) {
+      if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next(
+              &iter, size_t, Option_b3)
+              .tag == None) {
+        break;
+      } else {
+        Eurydice_slice_uint8_t_1size_t__x2 uu____5 =
+            libcrux_sha3_portable_keccak_split_at_mut_n_5a(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_fc3(&s, o);
+        memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice));
+      }
+    }
+    if (last < outlen) {
+      libcrux_sha3_generic_keccak_squeeze_last_cf2(s, o1);
+    }
+  }
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable.keccakx1
+with const generics
+- RATE= 104
+- DELIM= 6
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccakx1_ce3(
+    Eurydice_slice data[1U], Eurydice_slice out[1U]) {
+  /* Passing arrays by value in Rust generates a copy in C */
+  Eurydice_slice copy_of_data[1U];
+  memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice));
+  libcrux_sha3_generic_keccak_keccak_e93(copy_of_data, out);
+}
+
+/**
+ A portable SHA3 384 implementation.
+*/
+static KRML_MUSTINLINE 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_ce3(buf0, buf);
+}
+
+/**
+ SHA3 224
+
+ Preconditions:
+ - `digest.len() == 28`
+*/
+static KRML_MUSTINLINE void libcrux_sha3_sha224_ema(Eurydice_slice digest,
+                                                    Eurydice_slice payload) {
+  libcrux_sha3_portable_sha224(digest, payload);
+}
+
+/**
+ SHA3 224
+*/
+static KRML_MUSTINLINE 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),
+                          data);
+  memcpy(ret, out, (size_t)28U * sizeof(uint8_t));
+}
+
+/**
+ SHA3 256
+*/
+static KRML_MUSTINLINE void libcrux_sha3_sha256_ema(Eurydice_slice digest,
+                                                    Eurydice_slice payload) {
+  libcrux_sha3_portable_sha256(digest, payload);
+}
+
+/**
+ SHA3 256
+*/
+static KRML_MUSTINLINE 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),
+                          data);
+  memcpy(ret, out, (size_t)32U * sizeof(uint8_t));
+}
+
+/**
+ SHA3 384
+*/
+static KRML_MUSTINLINE void libcrux_sha3_sha384_ema(Eurydice_slice digest,
+                                                    Eurydice_slice payload) {
+  libcrux_sha3_portable_sha384(digest, payload);
+}
+
+/**
+ SHA3 384
+*/
+static KRML_MUSTINLINE 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),
+                          data);
+  memcpy(ret, out, (size_t)48U * sizeof(uint8_t));
+}
+
+/**
+ SHA3 512
+*/
+static KRML_MUSTINLINE void libcrux_sha3_sha512_ema(Eurydice_slice digest,
+                                                    Eurydice_slice payload) {
+  libcrux_sha3_portable_sha512(digest, payload);
+}
+
+/**
+ SHA3 512
+*/
+static KRML_MUSTINLINE 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),
+                          data);
+  memcpy(ret, out, (size_t)64U * sizeof(uint8_t));
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.load_block_5a
+with const generics
+- RATE= 168
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_5a_b83(
+    uint64_t (*a)[5U], Eurydice_slice b[1U]) {
+  uint64_t(*uu____0)[5U] = a;
+  /* Passing arrays by value in Rust generates a copy in C */
+  Eurydice_slice copy_of_b[1U];
+  memcpy(copy_of_b, b, (size_t)1U * sizeof(Eurydice_slice));
+  libcrux_sha3_portable_keccak_load_block_2c1(uu____0, copy_of_b);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.absorb_block
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 168
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_block_df3(
+    libcrux_sha3_generic_keccak_KeccakState_48 *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_load_block_5a_b83(uu____0, uu____1);
+  libcrux_sha3_generic_keccak_keccakf1600_21(s);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full
+with const generics
+- RATE= 168
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_full_2d3(
+    uint64_t (*s)[5U], uint8_t ret[1U][200U]) {
+  uint8_t out[200U] = {0U};
+  Eurydice_slice buf[1U] = {
+      Eurydice_array_to_slice((size_t)200U, out, uint8_t)};
+  libcrux_sha3_portable_keccak_store_block_581(s, buf);
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_out[200U];
+  memcpy(copy_of_out, out, (size_t)200U * sizeof(uint8_t));
+  memcpy(ret[0U], copy_of_out, (size_t)200U * sizeof(uint8_t));
+}
+
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full_5a
+with const generics
+- RATE= 168
+*/
+static KRML_MUSTINLINE void
+libcrux_sha3_portable_keccak_store_block_full_5a_293(uint64_t (*a)[5U],
+                                                     uint8_t ret[1U][200U]) {
+  libcrux_sha3_portable_keccak_store_block_full_2d3(a, ret);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_and_last
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 168
+*/
+static KRML_MUSTINLINE void
+libcrux_sha3_generic_keccak_squeeze_first_and_last_c53(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) {
+  uint8_t b[1U][200U];
+  libcrux_sha3_portable_keccak_store_block_full_5a_293(s->st, b);
+  for (size_t i = (size_t)0U; i < (size_t)1U; i++) {
+    size_t i0 = i;
+    Eurydice_slice uu____0 = out[i0];
+    uint8_t *uu____1 = b[i0];
+    core_ops_range_Range_b3 lit;
+    lit.start = (size_t)0U;
+    lit.end = Eurydice_slice_len(out[i0], uint8_t);
+    Eurydice_slice_copy(
+        uu____0,
+        Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t,
+                                   core_ops_range_Range_b3),
+        uint8_t);
+  }
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_last
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 168
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_last_cf3(
+    libcrux_sha3_generic_keccak_KeccakState_48 s, Eurydice_slice out[1U]) {
+  libcrux_sha3_generic_keccak_keccakf1600_21(&s);
+  uint8_t b[1U][200U];
+  libcrux_sha3_portable_keccak_store_block_full_5a_293(s.st, b);
+  for (size_t i = (size_t)0U; i < (size_t)1U; i++) {
+    size_t i0 = i;
+    Eurydice_slice uu____0 = out[i0];
+    uint8_t *uu____1 = b[i0];
+    core_ops_range_Range_b3 lit;
+    lit.start = (size_t)0U;
+    lit.end = Eurydice_slice_len(out[i0], uint8_t);
+    Eurydice_slice_copy(
+        uu____0,
+        Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t,
+                                   core_ops_range_Range_b3),
+        uint8_t);
+  }
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.keccak
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 168
+- DELIM= 31
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_keccak_e94(
+    Eurydice_slice data[1U], Eurydice_slice out[1U]) {
+  libcrux_sha3_generic_keccak_KeccakState_48 s =
+      libcrux_sha3_generic_keccak_new_1e_f4();
+  for (size_t i = (size_t)0U;
+       i < Eurydice_slice_len(data[0U], uint8_t) / (size_t)168U; i++) {
+    size_t i0 = i;
+    libcrux_sha3_generic_keccak_KeccakState_48 *uu____0 = &s;
+    /* Passing arrays by value in Rust generates a copy in C */
+    Eurydice_slice copy_of_data[1U];
+    memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice));
+    Eurydice_slice ret[1U];
+    libcrux_sha3_portable_keccak_slice_n_5a(copy_of_data, i0 * (size_t)168U,
+                                            (size_t)168U, ret);
+    libcrux_sha3_generic_keccak_absorb_block_df3(uu____0, ret);
+  }
+  size_t rem = Eurydice_slice_len(data[0U], uint8_t) % (size_t)168U;
+  libcrux_sha3_generic_keccak_KeccakState_48 *uu____2 = &s;
+  /* Passing arrays by value in Rust generates a copy in C */
+  Eurydice_slice copy_of_data[1U];
+  memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice));
+  Eurydice_slice ret[1U];
+  libcrux_sha3_portable_keccak_slice_n_5a(
+      copy_of_data, Eurydice_slice_len(data[0U], uint8_t) - rem, rem, ret);
+  libcrux_sha3_generic_keccak_absorb_final_c72(uu____2, ret);
+  size_t outlen = Eurydice_slice_len(out[0U], uint8_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_c53(&s, out);
+  } else {
+    Eurydice_slice_uint8_t_1size_t__x2 uu____4 =
+        libcrux_sha3_portable_keccak_split_at_mut_n_5a(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_841(&s, o0);
+    core_ops_range_Range_b3 iter =
+        core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter(
+            (CLITERAL(core_ops_range_Range_b3){.start = (size_t)1U,
+                                               .end = blocks}),
+            core_ops_range_Range_b3, core_ops_range_Range_b3);
+    while (true) {
+      if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next(
+              &iter, size_t, Option_b3)
+              .tag == None) {
+        break;
+      } else {
+        Eurydice_slice_uint8_t_1size_t__x2 uu____5 =
+            libcrux_sha3_portable_keccak_split_at_mut_n_5a(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_fc1(&s, o);
+        memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice));
+      }
+    }
+    if (last < outlen) {
+      libcrux_sha3_generic_keccak_squeeze_last_cf3(s, o1);
+    }
+  }
+}
+
+/**
+A monomorphic instance of libcrux_sha3.portable.keccakx1
+with const generics
+- RATE= 168
+- DELIM= 31
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccakx1_ce4(
+    Eurydice_slice data[1U], Eurydice_slice out[1U]) {
+  /* Passing arrays by value in Rust generates a copy in C */
+  Eurydice_slice copy_of_data[1U];
+  memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice));
+  libcrux_sha3_generic_keccak_keccak_e94(copy_of_data, out);
+}
+
+/**
+ A portable SHAKE128 implementation.
+*/
+static KRML_MUSTINLINE 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_ce4(buf0, buf);
+}
+
+/**
+ SHAKE 128
+
+ Writes `out.len()` bytes.
+*/
+static KRML_MUSTINLINE void libcrux_sha3_shake128_ema(Eurydice_slice out,
+                                                      Eurydice_slice data) {
+  libcrux_sha3_portable_shake128(out, data);
+}
+
+/**
+ SHAKE 256
+
+ Writes `out.len()` bytes.
+*/
+static KRML_MUSTINLINE void libcrux_sha3_shake256_ema(Eurydice_slice out,
+                                                      Eurydice_slice data) {
+  libcrux_sha3_portable_shake256(out, data);
+}
+
+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};
+
+/**
+ A portable SHA3 224 implementation.
+*/
+static KRML_MUSTINLINE 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);
+}
+
+/**
+ A portable SHA3 256 implementation.
+*/
+static KRML_MUSTINLINE 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);
+}
+
+/**
+ A portable SHA3 384 implementation.
+*/
+static KRML_MUSTINLINE 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);
+}
+
+/**
+ A portable SHA3 512 implementation.
+*/
+static KRML_MUSTINLINE 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);
+}
+
+/**
+ Run SHAKE256 on both inputs in parallel.
+
+ Writes the two results into `out0` and `out1`
+*/
+static KRML_MUSTINLINE 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 struct libcrux_sha3_neon_x2_incremental_KeccakState_s {
+  libcrux_sha3_generic_keccak_KeccakState_48 state[2U];
+} libcrux_sha3_neon_x2_incremental_KeccakState;
+
+/**
+ Initialise the `KeccakState2`.
+*/
+static KRML_MUSTINLINE libcrux_sha3_neon_x2_incremental_KeccakState
+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);
+}
+
+/**
+ Shake128 absorb `data0` and `data1` in the [`KeccakState`] `s`.
+*/
+static KRML_MUSTINLINE void
+libcrux_sha3_neon_x2_incremental_shake128_absorb_final(
+    libcrux_sha3_neon_x2_incremental_KeccakState *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);
+}
+
+/**
+ Squeeze 2 times the first three blocks in parallel in the
+ [`KeccakState`] and return the output in `out0` and `out1`.
+*/
+static KRML_MUSTINLINE void
+libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks(
+    libcrux_sha3_neon_x2_incremental_KeccakState *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);
+}
+
+/**
+ Squeeze 2 times the next block in parallel in the
+ [`KeccakState`] and return the output in `out0` and `out1`.
+*/
+static KRML_MUSTINLINE void
+libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block(
+    libcrux_sha3_neon_x2_incremental_KeccakState *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);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_five_blocks
+with types uint64_t
+with const generics
+- N= 1
+- RATE= 168
+*/
+static KRML_MUSTINLINE void
+libcrux_sha3_generic_keccak_squeeze_first_five_blocks_4f(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) {
+  Eurydice_slice_uint8_t_1size_t__x2 uu____0 =
+      libcrux_sha3_portable_keccak_split_at_mut_n_5a(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_841(s, o0);
+  Eurydice_slice_uint8_t_1size_t__x2 uu____1 =
+      libcrux_sha3_portable_keccak_split_at_mut_n_5a(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_fc1(s, o1);
+  Eurydice_slice_uint8_t_1size_t__x2 uu____2 =
+      libcrux_sha3_portable_keccak_split_at_mut_n_5a(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_fc1(s, o2);
+  Eurydice_slice_uint8_t_1size_t__x2 uu____3 =
+      libcrux_sha3_portable_keccak_split_at_mut_n_5a(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_fc1(s, o3);
+  libcrux_sha3_generic_keccak_squeeze_next_block_fc1(s, o4);
+}
+
+/**
+ Squeeze five blocks
+*/
+static KRML_MUSTINLINE void
+libcrux_sha3_portable_incremental_shake128_squeeze_first_five_blocks(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out0) {
+  Eurydice_slice buf[1U] = {out0};
+  libcrux_sha3_generic_keccak_squeeze_first_five_blocks_4f(s, buf);
+}
+
+/**
+ Absorb some data for SHAKE-256 for the last time
+*/
+static KRML_MUSTINLINE void
+libcrux_sha3_portable_incremental_shake256_absorb_final(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice data) {
+  Eurydice_slice buf[1U] = {data};
+  libcrux_sha3_generic_keccak_absorb_final_c71(s, buf);
+}
+
+/**
+ Create a new SHAKE-256 state object.
+*/
+static KRML_MUSTINLINE libcrux_sha3_generic_keccak_KeccakState_48
+libcrux_sha3_portable_incremental_shake256_init(void) {
+  return libcrux_sha3_generic_keccak_new_1e_f4();
+}
+
+/**
+ Squeeze the first SHAKE-256 block
+*/
+static KRML_MUSTINLINE void
+libcrux_sha3_portable_incremental_shake256_squeeze_first_block(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out) {
+  Eurydice_slice buf[1U] = {out};
+  libcrux_sha3_generic_keccak_squeeze_first_block_840(s, buf);
+}
+
+/**
+ Squeeze the next SHAKE-256 block
+*/
+static KRML_MUSTINLINE void
+libcrux_sha3_portable_incremental_shake256_squeeze_next_block(
+    libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out) {
+  Eurydice_slice buf[1U] = {out};
+  libcrux_sha3_generic_keccak_squeeze_next_block_fc0(s, buf);
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.KeccakXofState
+with types uint64_t
+with const generics
+- $1size_t
+- $136size_t
+*/
+typedef struct libcrux_sha3_generic_keccak_KeccakXofState_4f_s {
+  libcrux_sha3_generic_keccak_KeccakState_48 inner;
+  uint8_t buf[1U][136U];
+  size_t buf_len;
+  bool sponge;
+} libcrux_sha3_generic_keccak_KeccakXofState_4f;
+
+typedef libcrux_sha3_generic_keccak_KeccakXofState_4f
+    libcrux_sha3_portable_incremental_Shake256Absorb;
+
+/**
+ Consume the internal buffer and the required amount of the input to pad to
+ `RATE`.
+
+ Returns the `consumed` bytes from `inputs` if there's enough buffered
+ content to consume, and `0` otherwise.
+ If `consumed > 0` is returned, `self.buf` contains a full block to be
+ loaded.
+*/
+/**
+This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState<STATE,
+PARALLEL_LANES, RATE>[TraitClause@0]#2}
+*/
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.fill_buffer_9d
+with types uint64_t
+with const generics
+- PARALLEL_LANES= 1
+- RATE= 136
+*/
+static inline size_t libcrux_sha3_generic_keccak_fill_buffer_9d_b0(
+    libcrux_sha3_generic_keccak_KeccakXofState_4f *self,
+    Eurydice_slice inputs[1U]) {
+  size_t input_len = Eurydice_slice_len(inputs[0U], uint8_t);
+  size_t consumed = (size_t)0U;
+  if (self->buf_len > (size_t)0U) {
+    if (self->buf_len + input_len >= (size_t)136U) {
+      consumed = (size_t)136U - self->buf_len;
+      for (size_t i = (size_t)0U; i < (size_t)1U; i++) {
+        size_t i0 = i;
+        Eurydice_slice uu____0 = Eurydice_array_to_subslice_from(
+            (size_t)136U, self->buf[i0], self->buf_len, uint8_t, size_t);
+        Eurydice_slice_copy(
+            uu____0,
+            Eurydice_slice_subslice_to(inputs[i0], consumed, uint8_t, size_t),
+            uint8_t);
+      }
+      self->buf_len = self->buf_len + consumed;
+    }
+  }
+  return consumed;
+}
+
+/**
+This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState<STATE,
+PARALLEL_LANES, RATE>[TraitClause@0]#2}
+*/
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.absorb_full_9d
+with types uint64_t
+with const generics
+- PARALLEL_LANES= 1
+- RATE= 136
+*/
+static inline size_t libcrux_sha3_generic_keccak_absorb_full_9d_f8(
+    libcrux_sha3_generic_keccak_KeccakXofState_4f *self,
+    Eurydice_slice inputs[1U]) {
+  libcrux_sha3_generic_keccak_KeccakXofState_4f *uu____0 = self;
+  /* Passing arrays by value in Rust generates a copy in C */
+  Eurydice_slice copy_of_inputs0[1U];
+  memcpy(copy_of_inputs0, inputs, (size_t)1U * sizeof(Eurydice_slice));
+  size_t input_consumed =
+      libcrux_sha3_generic_keccak_fill_buffer_9d_b0(uu____0, copy_of_inputs0);
+  if (input_consumed > (size_t)0U) {
+    Eurydice_slice borrowed[1U];
+    for (size_t i = (size_t)0U; i < (size_t)1U; i++) {
+      uint8_t buf[136U] = {0U};
+      borrowed[i] = core_array___Array_T__N__23__as_slice(
+          (size_t)136U, buf, uint8_t, Eurydice_slice);
+    }
+    for (size_t i = (size_t)0U; i < (size_t)1U; i++) {
+      size_t i0 = i;
+      borrowed[i0] =
+          Eurydice_array_to_slice((size_t)136U, self->buf[i0], uint8_t);
+    }
+    uint64_t(*uu____2)[5U] = self->inner.st;
+    Eurydice_slice uu____3[1U];
+    memcpy(uu____3, borrowed, (size_t)1U * sizeof(Eurydice_slice));
+    libcrux_sha3_portable_keccak_load_block_5a_b80(uu____2, uu____3);
+    libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner);
+    self->buf_len = (size_t)0U;
+  }
+  size_t input_to_consume =
+      Eurydice_slice_len(inputs[0U], uint8_t) - input_consumed;
+  size_t num_blocks = input_to_consume / (size_t)136U;
+  size_t remainder = input_to_consume % (size_t)136U;
+  for (size_t i = (size_t)0U; i < num_blocks; i++) {
+    size_t i0 = i;
+    uint64_t(*uu____4)[5U] = self->inner.st;
+    /* Passing arrays by value in Rust generates a copy in C */
+    Eurydice_slice copy_of_inputs[1U];
+    memcpy(copy_of_inputs, inputs, (size_t)1U * sizeof(Eurydice_slice));
+    Eurydice_slice ret[1U];
+    libcrux_sha3_portable_keccak_slice_n_5a(
+        copy_of_inputs, input_consumed + i0 * (size_t)136U, (size_t)136U, ret);
+    libcrux_sha3_portable_keccak_load_block_5a_b80(uu____4, ret);
+    libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner);
+  }
+  return remainder;
+}
+
+/**
+ Absorb
+
+ This function takes any number of bytes to absorb and buffers if it's not
+ enough. The function assumes that all input slices in `blocks` have the same
+ length.
+
+ Only a multiple of `RATE` blocks are absorbed.
+ For the remaining bytes [`absorb_final`] needs to be called.
+
+ This works best with relatively small `inputs`.
+*/
+/**
+This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState<STATE,
+PARALLEL_LANES, RATE>[TraitClause@0]#2}
+*/
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.absorb_9d
+with types uint64_t
+with const generics
+- PARALLEL_LANES= 1
+- RATE= 136
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_9d_7b(
+    libcrux_sha3_generic_keccak_KeccakXofState_4f *self,
+    Eurydice_slice inputs[1U]) {
+  libcrux_sha3_generic_keccak_KeccakXofState_4f *uu____0 = self;
+  /* Passing arrays by value in Rust generates a copy in C */
+  Eurydice_slice copy_of_inputs[1U];
+  memcpy(copy_of_inputs, inputs, (size_t)1U * sizeof(Eurydice_slice));
+  size_t input_remainder_len =
+      libcrux_sha3_generic_keccak_absorb_full_9d_f8(uu____0, copy_of_inputs);
+  if (input_remainder_len > (size_t)0U) {
+    size_t input_len = Eurydice_slice_len(inputs[0U], uint8_t);
+    for (size_t i = (size_t)0U; i < (size_t)1U; i++) {
+      size_t i0 = i;
+      Eurydice_slice uu____2 = Eurydice_array_to_subslice2(
+          self->buf[i0], self->buf_len, self->buf_len + input_remainder_len,
+          uint8_t);
+      Eurydice_slice_copy(
+          uu____2,
+          Eurydice_slice_subslice_from(
+              inputs[i0], input_len - input_remainder_len, uint8_t, size_t),
+          uint8_t);
+    }
+    self->buf_len = self->buf_len + input_remainder_len;
+  }
+}
+
+/**
+ Shake256 absorb
+*/
+/**
+This function found in impl
+{(libcrux_sha3::portable::incremental::XofAbsorb<136: usize> for
+libcrux_sha3::portable::incremental::Shake256Absorb)#2}
+*/
+static inline void libcrux_sha3_portable_incremental_absorb_7d(
+    libcrux_sha3_generic_keccak_KeccakXofState_4f *self, Eurydice_slice input) {
+  Eurydice_slice buf[1U] = {input};
+  libcrux_sha3_generic_keccak_absorb_9d_7b(self, buf);
+}
+
+typedef libcrux_sha3_generic_keccak_KeccakXofState_4f
+    libcrux_sha3_portable_incremental_Shake256Squeeze;
+
+/**
+ Absorb a final block.
+
+ The `inputs` block may be empty. Everything in the `inputs` block beyond
+ `RATE` bytes is ignored.
+*/
+/**
+This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState<STATE,
+PARALLEL_LANES, RATE>[TraitClause@0]#2}
+*/
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final_9d
+with types uint64_t
+with const generics
+- PARALLEL_LANES= 1
+- RATE= 136
+- DELIMITER= 31
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_9d_25(
+    libcrux_sha3_generic_keccak_KeccakXofState_4f *self,
+    Eurydice_slice inputs[1U]) {
+  libcrux_sha3_generic_keccak_KeccakXofState_4f *uu____0 = self;
+  /* Passing arrays by value in Rust generates a copy in C */
+  Eurydice_slice copy_of_inputs[1U];
+  memcpy(copy_of_inputs, inputs, (size_t)1U * sizeof(Eurydice_slice));
+  size_t input_remainder_len =
+      libcrux_sha3_generic_keccak_absorb_full_9d_f8(uu____0, copy_of_inputs);
+  size_t input_len = Eurydice_slice_len(inputs[0U], uint8_t);
+  uint8_t blocks[1U][200U] = {{0U}};
+  for (size_t i = (size_t)0U; i < (size_t)1U; i++) {
+    size_t i0 = i;
+    if (self->buf_len > (size_t)0U) {
+      Eurydice_slice uu____2 = Eurydice_array_to_subslice2(
+          blocks[i0], (size_t)0U, self->buf_len, uint8_t);
+      Eurydice_slice_copy(uu____2,
+                          Eurydice_array_to_subslice2(self->buf[i0], (size_t)0U,
+                                                      self->buf_len, uint8_t),
+                          uint8_t);
+    }
+    if (input_remainder_len > (size_t)0U) {
+      Eurydice_slice uu____3 = Eurydice_array_to_subslice2(
+          blocks[i0], self->buf_len, self->buf_len + input_remainder_len,
+          uint8_t);
+      Eurydice_slice_copy(
+          uu____3,
+          Eurydice_slice_subslice_from(
+              inputs[i0], input_len - input_remainder_len, uint8_t, size_t),
+          uint8_t);
+    }
+    blocks[i0][self->buf_len + input_remainder_len] = 31U;
+    size_t uu____4 = i0;
+    size_t uu____5 = (size_t)136U - (size_t)1U;
+    blocks[uu____4][uu____5] = (uint32_t)blocks[uu____4][uu____5] | 128U;
+  }
+  uint64_t(*uu____6)[5U] = self->inner.st;
+  uint8_t uu____7[1U][200U];
+  memcpy(uu____7, blocks, (size_t)1U * sizeof(uint8_t[200U]));
+  libcrux_sha3_portable_keccak_load_block_full_5a_d20(uu____6, uu____7);
+  libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner);
+}
+
+/**
+ Shake256 absorb final
+*/
+/**
+This function found in impl
+{(libcrux_sha3::portable::incremental::XofAbsorb<136: usize> for
+libcrux_sha3::portable::incremental::Shake256Absorb)#2}
+*/
+static inline libcrux_sha3_generic_keccak_KeccakXofState_4f
+libcrux_sha3_portable_incremental_absorb_final_7d(
+    libcrux_sha3_generic_keccak_KeccakXofState_4f self, Eurydice_slice input) {
+  Eurydice_slice buf[1U] = {input};
+  libcrux_sha3_generic_keccak_absorb_final_9d_25(&self, buf);
+  return self;
+}
+
+/**
+ An all zero block
+*/
+/**
+This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState<STATE,
+PARALLEL_LANES, RATE>[TraitClause@0]#2}
+*/
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.zero_block_9d
+with types uint64_t
+with const generics
+- PARALLEL_LANES= 1
+- RATE= 136
+*/
+static inline void libcrux_sha3_generic_keccak_zero_block_9d_e6(
+    uint8_t ret[136U]) {
+  ret[0U] = 0U;
+  ret[1U] = 0U;
+  ret[2U] = 0U;
+  ret[3U] = 0U;
+  ret[4U] = 0U;
+  ret[5U] = 0U;
+  ret[6U] = 0U;
+  ret[7U] = 0U;
+  ret[8U] = 0U;
+  ret[9U] = 0U;
+  ret[10U] = 0U;
+  ret[11U] = 0U;
+  ret[12U] = 0U;
+  ret[13U] = 0U;
+  ret[14U] = 0U;
+  ret[15U] = 0U;
+  ret[16U] = 0U;
+  ret[17U] = 0U;
+  ret[18U] = 0U;
+  ret[19U] = 0U;
+  ret[20U] = 0U;
+  ret[21U] = 0U;
+  ret[22U] = 0U;
+  ret[23U] = 0U;
+  ret[24U] = 0U;
+  ret[25U] = 0U;
+  ret[26U] = 0U;
+  ret[27U] = 0U;
+  ret[28U] = 0U;
+  ret[29U] = 0U;
+  ret[30U] = 0U;
+  ret[31U] = 0U;
+  ret[32U] = 0U;
+  ret[33U] = 0U;
+  ret[34U] = 0U;
+  ret[35U] = 0U;
+  ret[36U] = 0U;
+  ret[37U] = 0U;
+  ret[38U] = 0U;
+  ret[39U] = 0U;
+  ret[40U] = 0U;
+  ret[41U] = 0U;
+  ret[42U] = 0U;
+  ret[43U] = 0U;
+  ret[44U] = 0U;
+  ret[45U] = 0U;
+  ret[46U] = 0U;
+  ret[47U] = 0U;
+  ret[48U] = 0U;
+  ret[49U] = 0U;
+  ret[50U] = 0U;
+  ret[51U] = 0U;
+  ret[52U] = 0U;
+  ret[53U] = 0U;
+  ret[54U] = 0U;
+  ret[55U] = 0U;
+  ret[56U] = 0U;
+  ret[57U] = 0U;
+  ret[58U] = 0U;
+  ret[59U] = 0U;
+  ret[60U] = 0U;
+  ret[61U] = 0U;
+  ret[62U] = 0U;
+  ret[63U] = 0U;
+  ret[64U] = 0U;
+  ret[65U] = 0U;
+  ret[66U] = 0U;
+  ret[67U] = 0U;
+  ret[68U] = 0U;
+  ret[69U] = 0U;
+  ret[70U] = 0U;
+  ret[71U] = 0U;
+  ret[72U] = 0U;
+  ret[73U] = 0U;
+  ret[74U] = 0U;
+  ret[75U] = 0U;
+  ret[76U] = 0U;
+  ret[77U] = 0U;
+  ret[78U] = 0U;
+  ret[79U] = 0U;
+  ret[80U] = 0U;
+  ret[81U] = 0U;
+  ret[82U] = 0U;
+  ret[83U] = 0U;
+  ret[84U] = 0U;
+  ret[85U] = 0U;
+  ret[86U] = 0U;
+  ret[87U] = 0U;
+  ret[88U] = 0U;
+  ret[89U] = 0U;
+  ret[90U] = 0U;
+  ret[91U] = 0U;
+  ret[92U] = 0U;
+  ret[93U] = 0U;
+  ret[94U] = 0U;
+  ret[95U] = 0U;
+  ret[96U] = 0U;
+  ret[97U] = 0U;
+  ret[98U] = 0U;
+  ret[99U] = 0U;
+  ret[100U] = 0U;
+  ret[101U] = 0U;
+  ret[102U] = 0U;
+  ret[103U] = 0U;
+  ret[104U] = 0U;
+  ret[105U] = 0U;
+  ret[106U] = 0U;
+  ret[107U] = 0U;
+  ret[108U] = 0U;
+  ret[109U] = 0U;
+  ret[110U] = 0U;
+  ret[111U] = 0U;
+  ret[112U] = 0U;
+  ret[113U] = 0U;
+  ret[114U] = 0U;
+  ret[115U] = 0U;
+  ret[116U] = 0U;
+  ret[117U] = 0U;
+  ret[118U] = 0U;
+  ret[119U] = 0U;
+  ret[120U] = 0U;
+  ret[121U] = 0U;
+  ret[122U] = 0U;
+  ret[123U] = 0U;
+  ret[124U] = 0U;
+  ret[125U] = 0U;
+  ret[126U] = 0U;
+  ret[127U] = 0U;
+  ret[128U] = 0U;
+  ret[129U] = 0U;
+  ret[130U] = 0U;
+  ret[131U] = 0U;
+  ret[132U] = 0U;
+  ret[133U] = 0U;
+  ret[134U] = 0U;
+  ret[135U] = 0U;
+}
+
+/**
+ Generate a new keccak xof state.
+*/
+/**
+This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState<STATE,
+PARALLEL_LANES, RATE>[TraitClause@0]#2}
+*/
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.new_9d
+with types uint64_t
+with const generics
+- PARALLEL_LANES= 1
+- RATE= 136
+*/
+static inline libcrux_sha3_generic_keccak_KeccakXofState_4f
+libcrux_sha3_generic_keccak_new_9d_7e(void) {
+  libcrux_sha3_generic_keccak_KeccakXofState_4f lit;
+  lit.inner = libcrux_sha3_generic_keccak_new_1e_f4();
+  uint8_t ret[136U];
+  libcrux_sha3_generic_keccak_zero_block_9d_e6(ret);
+  memcpy(lit.buf[0U], ret, (size_t)136U * sizeof(uint8_t));
+  lit.buf_len = (size_t)0U;
+  lit.sponge = false;
+  return lit;
+}
+
+/**
+ Shake256 new state
+*/
+/**
+This function found in impl
+{(libcrux_sha3::portable::incremental::XofAbsorb<136: usize> for
+libcrux_sha3::portable::incremental::Shake256Absorb)#2}
+*/
+static inline libcrux_sha3_generic_keccak_KeccakXofState_4f
+libcrux_sha3_portable_incremental_new_7d(void) {
+  return libcrux_sha3_generic_keccak_new_9d_7e();
+}
+
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.KeccakXofState
+with types uint64_t
+with const generics
+- $1size_t
+- $168size_t
+*/
+typedef struct libcrux_sha3_generic_keccak_KeccakXofState_78_s {
+  libcrux_sha3_generic_keccak_KeccakState_48 inner;
+  uint8_t buf[1U][168U];
+  size_t buf_len;
+  bool sponge;
+} libcrux_sha3_generic_keccak_KeccakXofState_78;
+
+typedef libcrux_sha3_generic_keccak_KeccakXofState_78
+    libcrux_sha3_portable_incremental_Shake128Absorb;
+
+/**
+ Consume the internal buffer and the required amount of the input to pad to
+ `RATE`.
+
+ Returns the `consumed` bytes from `inputs` if there's enough buffered
+ content to consume, and `0` otherwise.
+ If `consumed > 0` is returned, `self.buf` contains a full block to be
+ loaded.
+*/
+/**
+This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState<STATE,
+PARALLEL_LANES, RATE>[TraitClause@0]#2}
+*/
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.fill_buffer_9d
+with types uint64_t
+with const generics
+- PARALLEL_LANES= 1
+- RATE= 168
+*/
+static inline size_t libcrux_sha3_generic_keccak_fill_buffer_9d_b00(
+    libcrux_sha3_generic_keccak_KeccakXofState_78 *self,
+    Eurydice_slice inputs[1U]) {
+  size_t input_len = Eurydice_slice_len(inputs[0U], uint8_t);
+  size_t consumed = (size_t)0U;
+  if (self->buf_len > (size_t)0U) {
+    if (self->buf_len + input_len >= (size_t)168U) {
+      consumed = (size_t)168U - self->buf_len;
+      for (size_t i = (size_t)0U; i < (size_t)1U; i++) {
+        size_t i0 = i;
+        Eurydice_slice uu____0 = Eurydice_array_to_subslice_from(
+            (size_t)168U, self->buf[i0], self->buf_len, uint8_t, size_t);
+        Eurydice_slice_copy(
+            uu____0,
+            Eurydice_slice_subslice_to(inputs[i0], consumed, uint8_t, size_t),
+            uint8_t);
+      }
+      self->buf_len = self->buf_len + consumed;
+    }
+  }
+  return consumed;
+}
+
+/**
+This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState<STATE,
+PARALLEL_LANES, RATE>[TraitClause@0]#2}
+*/
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.absorb_full_9d
+with types uint64_t
+with const generics
+- PARALLEL_LANES= 1
+- RATE= 168
+*/
+static inline size_t libcrux_sha3_generic_keccak_absorb_full_9d_f80(
+    libcrux_sha3_generic_keccak_KeccakXofState_78 *self,
+    Eurydice_slice inputs[1U]) {
+  libcrux_sha3_generic_keccak_KeccakXofState_78 *uu____0 = self;
+  /* Passing arrays by value in Rust generates a copy in C */
+  Eurydice_slice copy_of_inputs0[1U];
+  memcpy(copy_of_inputs0, inputs, (size_t)1U * sizeof(Eurydice_slice));
+  size_t input_consumed =
+      libcrux_sha3_generic_keccak_fill_buffer_9d_b00(uu____0, copy_of_inputs0);
+  if (input_consumed > (size_t)0U) {
+    Eurydice_slice borrowed[1U];
+    for (size_t i = (size_t)0U; i < (size_t)1U; i++) {
+      uint8_t buf[168U] = {0U};
+      borrowed[i] = core_array___Array_T__N__23__as_slice(
+          (size_t)168U, buf, uint8_t, Eurydice_slice);
+    }
+    for (size_t i = (size_t)0U; i < (size_t)1U; i++) {
+      size_t i0 = i;
+      borrowed[i0] =
+          Eurydice_array_to_slice((size_t)168U, self->buf[i0], uint8_t);
+    }
+    uint64_t(*uu____2)[5U] = self->inner.st;
+    Eurydice_slice uu____3[1U];
+    memcpy(uu____3, borrowed, (size_t)1U * sizeof(Eurydice_slice));
+    libcrux_sha3_portable_keccak_load_block_5a_b83(uu____2, uu____3);
+    libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner);
+    self->buf_len = (size_t)0U;
+  }
+  size_t input_to_consume =
+      Eurydice_slice_len(inputs[0U], uint8_t) - input_consumed;
+  size_t num_blocks = input_to_consume / (size_t)168U;
+  size_t remainder = input_to_consume % (size_t)168U;
+  for (size_t i = (size_t)0U; i < num_blocks; i++) {
+    size_t i0 = i;
+    uint64_t(*uu____4)[5U] = self->inner.st;
+    /* Passing arrays by value in Rust generates a copy in C */
+    Eurydice_slice copy_of_inputs[1U];
+    memcpy(copy_of_inputs, inputs, (size_t)1U * sizeof(Eurydice_slice));
+    Eurydice_slice ret[1U];
+    libcrux_sha3_portable_keccak_slice_n_5a(
+        copy_of_inputs, input_consumed + i0 * (size_t)168U, (size_t)168U, ret);
+    libcrux_sha3_portable_keccak_load_block_5a_b83(uu____4, ret);
+    libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner);
+  }
+  return remainder;
+}
+
+/**
+ Absorb
+
+ This function takes any number of bytes to absorb and buffers if it's not
+ enough. The function assumes that all input slices in `blocks` have the same
+ length.
+
+ Only a multiple of `RATE` blocks are absorbed.
+ For the remaining bytes [`absorb_final`] needs to be called.
+
+ This works best with relatively small `inputs`.
+*/
+/**
+This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState<STATE,
+PARALLEL_LANES, RATE>[TraitClause@0]#2}
+*/
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.absorb_9d
+with types uint64_t
+with const generics
+- PARALLEL_LANES= 1
+- RATE= 168
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_9d_7b0(
+    libcrux_sha3_generic_keccak_KeccakXofState_78 *self,
+    Eurydice_slice inputs[1U]) {
+  libcrux_sha3_generic_keccak_KeccakXofState_78 *uu____0 = self;
+  /* Passing arrays by value in Rust generates a copy in C */
+  Eurydice_slice copy_of_inputs[1U];
+  memcpy(copy_of_inputs, inputs, (size_t)1U * sizeof(Eurydice_slice));
+  size_t input_remainder_len =
+      libcrux_sha3_generic_keccak_absorb_full_9d_f80(uu____0, copy_of_inputs);
+  if (input_remainder_len > (size_t)0U) {
+    size_t input_len = Eurydice_slice_len(inputs[0U], uint8_t);
+    for (size_t i = (size_t)0U; i < (size_t)1U; i++) {
+      size_t i0 = i;
+      Eurydice_slice uu____2 = Eurydice_array_to_subslice2(
+          self->buf[i0], self->buf_len, self->buf_len + input_remainder_len,
+          uint8_t);
+      Eurydice_slice_copy(
+          uu____2,
+          Eurydice_slice_subslice_from(
+              inputs[i0], input_len - input_remainder_len, uint8_t, size_t),
+          uint8_t);
+    }
+    self->buf_len = self->buf_len + input_remainder_len;
+  }
+}
+
+/**
+This function found in impl
+{(libcrux_sha3::portable::incremental::XofAbsorb<168: usize> for
+libcrux_sha3::portable::incremental::Shake128Absorb)}
+*/
+static inline void libcrux_sha3_portable_incremental_absorb_1c(
+    libcrux_sha3_generic_keccak_KeccakXofState_78 *self, Eurydice_slice input) {
+  Eurydice_slice buf[1U] = {input};
+  libcrux_sha3_generic_keccak_absorb_9d_7b0(self, buf);
+}
+
+typedef libcrux_sha3_generic_keccak_KeccakXofState_78
+    libcrux_sha3_portable_incremental_Shake128Squeeze;
+
+/**
+ Absorb a final block.
+
+ The `inputs` block may be empty. Everything in the `inputs` block beyond
+ `RATE` bytes is ignored.
+*/
+/**
+This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState<STATE,
+PARALLEL_LANES, RATE>[TraitClause@0]#2}
+*/
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final_9d
+with types uint64_t
+with const generics
+- PARALLEL_LANES= 1
+- RATE= 168
+- DELIMITER= 31
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_9d_250(
+    libcrux_sha3_generic_keccak_KeccakXofState_78 *self,
+    Eurydice_slice inputs[1U]) {
+  libcrux_sha3_generic_keccak_KeccakXofState_78 *uu____0 = self;
+  /* Passing arrays by value in Rust generates a copy in C */
+  Eurydice_slice copy_of_inputs[1U];
+  memcpy(copy_of_inputs, inputs, (size_t)1U * sizeof(Eurydice_slice));
+  size_t input_remainder_len =
+      libcrux_sha3_generic_keccak_absorb_full_9d_f80(uu____0, copy_of_inputs);
+  size_t input_len = Eurydice_slice_len(inputs[0U], uint8_t);
+  uint8_t blocks[1U][200U] = {{0U}};
+  for (size_t i = (size_t)0U; i < (size_t)1U; i++) {
+    size_t i0 = i;
+    if (self->buf_len > (size_t)0U) {
+      Eurydice_slice uu____2 = Eurydice_array_to_subslice2(
+          blocks[i0], (size_t)0U, self->buf_len, uint8_t);
+      Eurydice_slice_copy(uu____2,
+                          Eurydice_array_to_subslice2(self->buf[i0], (size_t)0U,
+                                                      self->buf_len, uint8_t),
+                          uint8_t);
+    }
+    if (input_remainder_len > (size_t)0U) {
+      Eurydice_slice uu____3 = Eurydice_array_to_subslice2(
+          blocks[i0], self->buf_len, self->buf_len + input_remainder_len,
+          uint8_t);
+      Eurydice_slice_copy(
+          uu____3,
+          Eurydice_slice_subslice_from(
+              inputs[i0], input_len - input_remainder_len, uint8_t, size_t),
+          uint8_t);
+    }
+    blocks[i0][self->buf_len + input_remainder_len] = 31U;
+    size_t uu____4 = i0;
+    size_t uu____5 = (size_t)168U - (size_t)1U;
+    blocks[uu____4][uu____5] = (uint32_t)blocks[uu____4][uu____5] | 128U;
+  }
+  uint64_t(*uu____6)[5U] = self->inner.st;
+  uint8_t uu____7[1U][200U];
+  memcpy(uu____7, blocks, (size_t)1U * sizeof(uint8_t[200U]));
+  libcrux_sha3_portable_keccak_load_block_full_5a_d21(uu____6, uu____7);
+  libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner);
+}
+
+/**
+This function found in impl
+{(libcrux_sha3::portable::incremental::XofAbsorb<168: usize> for
+libcrux_sha3::portable::incremental::Shake128Absorb)}
+*/
+static inline libcrux_sha3_generic_keccak_KeccakXofState_78
+libcrux_sha3_portable_incremental_absorb_final_1c(
+    libcrux_sha3_generic_keccak_KeccakXofState_78 self, Eurydice_slice input) {
+  Eurydice_slice buf[1U] = {input};
+  libcrux_sha3_generic_keccak_absorb_final_9d_250(&self, buf);
+  return self;
+}
+
+/**
+ An all zero block
+*/
+/**
+This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState<STATE,
+PARALLEL_LANES, RATE>[TraitClause@0]#2}
+*/
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.zero_block_9d
+with types uint64_t
+with const generics
+- PARALLEL_LANES= 1
+- RATE= 168
+*/
+static inline void libcrux_sha3_generic_keccak_zero_block_9d_e60(
+    uint8_t ret[168U]) {
+  ret[0U] = 0U;
+  ret[1U] = 0U;
+  ret[2U] = 0U;
+  ret[3U] = 0U;
+  ret[4U] = 0U;
+  ret[5U] = 0U;
+  ret[6U] = 0U;
+  ret[7U] = 0U;
+  ret[8U] = 0U;
+  ret[9U] = 0U;
+  ret[10U] = 0U;
+  ret[11U] = 0U;
+  ret[12U] = 0U;
+  ret[13U] = 0U;
+  ret[14U] = 0U;
+  ret[15U] = 0U;
+  ret[16U] = 0U;
+  ret[17U] = 0U;
+  ret[18U] = 0U;
+  ret[19U] = 0U;
+  ret[20U] = 0U;
+  ret[21U] = 0U;
+  ret[22U] = 0U;
+  ret[23U] = 0U;
+  ret[24U] = 0U;
+  ret[25U] = 0U;
+  ret[26U] = 0U;
+  ret[27U] = 0U;
+  ret[28U] = 0U;
+  ret[29U] = 0U;
+  ret[30U] = 0U;
+  ret[31U] = 0U;
+  ret[32U] = 0U;
+  ret[33U] = 0U;
+  ret[34U] = 0U;
+  ret[35U] = 0U;
+  ret[36U] = 0U;
+  ret[37U] = 0U;
+  ret[38U] = 0U;
+  ret[39U] = 0U;
+  ret[40U] = 0U;
+  ret[41U] = 0U;
+  ret[42U] = 0U;
+  ret[43U] = 0U;
+  ret[44U] = 0U;
+  ret[45U] = 0U;
+  ret[46U] = 0U;
+  ret[47U] = 0U;
+  ret[48U] = 0U;
+  ret[49U] = 0U;
+  ret[50U] = 0U;
+  ret[51U] = 0U;
+  ret[52U] = 0U;
+  ret[53U] = 0U;
+  ret[54U] = 0U;
+  ret[55U] = 0U;
+  ret[56U] = 0U;
+  ret[57U] = 0U;
+  ret[58U] = 0U;
+  ret[59U] = 0U;
+  ret[60U] = 0U;
+  ret[61U] = 0U;
+  ret[62U] = 0U;
+  ret[63U] = 0U;
+  ret[64U] = 0U;
+  ret[65U] = 0U;
+  ret[66U] = 0U;
+  ret[67U] = 0U;
+  ret[68U] = 0U;
+  ret[69U] = 0U;
+  ret[70U] = 0U;
+  ret[71U] = 0U;
+  ret[72U] = 0U;
+  ret[73U] = 0U;
+  ret[74U] = 0U;
+  ret[75U] = 0U;
+  ret[76U] = 0U;
+  ret[77U] = 0U;
+  ret[78U] = 0U;
+  ret[79U] = 0U;
+  ret[80U] = 0U;
+  ret[81U] = 0U;
+  ret[82U] = 0U;
+  ret[83U] = 0U;
+  ret[84U] = 0U;
+  ret[85U] = 0U;
+  ret[86U] = 0U;
+  ret[87U] = 0U;
+  ret[88U] = 0U;
+  ret[89U] = 0U;
+  ret[90U] = 0U;
+  ret[91U] = 0U;
+  ret[92U] = 0U;
+  ret[93U] = 0U;
+  ret[94U] = 0U;
+  ret[95U] = 0U;
+  ret[96U] = 0U;
+  ret[97U] = 0U;
+  ret[98U] = 0U;
+  ret[99U] = 0U;
+  ret[100U] = 0U;
+  ret[101U] = 0U;
+  ret[102U] = 0U;
+  ret[103U] = 0U;
+  ret[104U] = 0U;
+  ret[105U] = 0U;
+  ret[106U] = 0U;
+  ret[107U] = 0U;
+  ret[108U] = 0U;
+  ret[109U] = 0U;
+  ret[110U] = 0U;
+  ret[111U] = 0U;
+  ret[112U] = 0U;
+  ret[113U] = 0U;
+  ret[114U] = 0U;
+  ret[115U] = 0U;
+  ret[116U] = 0U;
+  ret[117U] = 0U;
+  ret[118U] = 0U;
+  ret[119U] = 0U;
+  ret[120U] = 0U;
+  ret[121U] = 0U;
+  ret[122U] = 0U;
+  ret[123U] = 0U;
+  ret[124U] = 0U;
+  ret[125U] = 0U;
+  ret[126U] = 0U;
+  ret[127U] = 0U;
+  ret[128U] = 0U;
+  ret[129U] = 0U;
+  ret[130U] = 0U;
+  ret[131U] = 0U;
+  ret[132U] = 0U;
+  ret[133U] = 0U;
+  ret[134U] = 0U;
+  ret[135U] = 0U;
+  ret[136U] = 0U;
+  ret[137U] = 0U;
+  ret[138U] = 0U;
+  ret[139U] = 0U;
+  ret[140U] = 0U;
+  ret[141U] = 0U;
+  ret[142U] = 0U;
+  ret[143U] = 0U;
+  ret[144U] = 0U;
+  ret[145U] = 0U;
+  ret[146U] = 0U;
+  ret[147U] = 0U;
+  ret[148U] = 0U;
+  ret[149U] = 0U;
+  ret[150U] = 0U;
+  ret[151U] = 0U;
+  ret[152U] = 0U;
+  ret[153U] = 0U;
+  ret[154U] = 0U;
+  ret[155U] = 0U;
+  ret[156U] = 0U;
+  ret[157U] = 0U;
+  ret[158U] = 0U;
+  ret[159U] = 0U;
+  ret[160U] = 0U;
+  ret[161U] = 0U;
+  ret[162U] = 0U;
+  ret[163U] = 0U;
+  ret[164U] = 0U;
+  ret[165U] = 0U;
+  ret[166U] = 0U;
+  ret[167U] = 0U;
+}
+
+/**
+ Generate a new keccak xof state.
+*/
+/**
+This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState<STATE,
+PARALLEL_LANES, RATE>[TraitClause@0]#2}
+*/
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.new_9d
+with types uint64_t
+with const generics
+- PARALLEL_LANES= 1
+- RATE= 168
+*/
+static inline libcrux_sha3_generic_keccak_KeccakXofState_78
+libcrux_sha3_generic_keccak_new_9d_7e0(void) {
+  libcrux_sha3_generic_keccak_KeccakXofState_78 lit;
+  lit.inner = libcrux_sha3_generic_keccak_new_1e_f4();
+  uint8_t ret[168U];
+  libcrux_sha3_generic_keccak_zero_block_9d_e60(ret);
+  memcpy(lit.buf[0U], ret, (size_t)168U * sizeof(uint8_t));
+  lit.buf_len = (size_t)0U;
+  lit.sponge = false;
+  return lit;
+}
+
+/**
+This function found in impl
+{(libcrux_sha3::portable::incremental::XofAbsorb<168: usize> for
+libcrux_sha3::portable::incremental::Shake128Absorb)}
+*/
+static inline libcrux_sha3_generic_keccak_KeccakXofState_78
+libcrux_sha3_portable_incremental_new_1c(void) {
+  return libcrux_sha3_generic_keccak_new_9d_7e0();
+}
+
+/**
+ `out` has the exact size we want here. It must be less than or equal to `RATE`.
+*/
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.store_5a
+with const generics
+- RATE= 136
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_5a_1c(
+    uint64_t (*state)[5U], Eurydice_slice out[1U]) {
+  size_t num_full_blocks = Eurydice_slice_len(out[0U], uint8_t) / (size_t)8U;
+  size_t last_block_len = Eurydice_slice_len(out[0U], uint8_t) % (size_t)8U;
+  for (size_t i = (size_t)0U; i < num_full_blocks; i++) {
+    size_t i0 = i;
+    Eurydice_slice uu____0 = Eurydice_slice_subslice2(
+        out[0U], i0 * (size_t)8U, i0 * (size_t)8U + (size_t)8U, uint8_t);
+    uint8_t ret[8U];
+    core_num__u64_9__to_le_bytes(state[i0 / (size_t)5U][i0 % (size_t)5U], ret);
+    Eurydice_slice_copy(
+        uu____0, Eurydice_array_to_slice((size_t)8U, ret, uint8_t), uint8_t);
+  }
+  if (last_block_len != (size_t)0U) {
+    Eurydice_slice uu____1 = Eurydice_slice_subslice2(
+        out[0U], num_full_blocks * (size_t)8U,
+        num_full_blocks * (size_t)8U + last_block_len, uint8_t);
+    uint8_t ret[8U];
+    core_num__u64_9__to_le_bytes(
+        state[num_full_blocks / (size_t)5U][num_full_blocks % (size_t)5U], ret);
+    Eurydice_slice_copy(
+        uu____1,
+        Eurydice_array_to_subslice2(ret, (size_t)0U, last_block_len, uint8_t),
+        uint8_t);
+  }
+}
+
+/**
+ Squeeze `N` x `LEN` bytes.
+*/
+/**
+This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState<STATE,
+PARALLEL_LANES, RATE>[TraitClause@0]#2}
+*/
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_9d
+with types uint64_t
+with const generics
+- PARALLEL_LANES= 1
+- RATE= 136
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_9d_96(
+    libcrux_sha3_generic_keccak_KeccakXofState_4f *self,
+    Eurydice_slice out[1U]) {
+  if (self->sponge) {
+    libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner);
+  }
+  size_t out_len = Eurydice_slice_len(out[0U], uint8_t);
+  size_t blocks = out_len / (size_t)136U;
+  size_t last = out_len - out_len % (size_t)136U;
+  size_t mid;
+  if ((size_t)136U >= out_len) {
+    mid = out_len;
+  } else {
+    mid = (size_t)136U;
+  }
+  Eurydice_slice_uint8_t_1size_t__x2 uu____0 =
+      libcrux_sha3_portable_keccak_split_at_mut_n_5a(out, mid);
+  Eurydice_slice out00[1U];
+  memcpy(out00, uu____0.fst, (size_t)1U * sizeof(Eurydice_slice));
+  Eurydice_slice out_rest[1U];
+  memcpy(out_rest, uu____0.snd, (size_t)1U * sizeof(Eurydice_slice));
+  libcrux_sha3_portable_keccak_store_5a_1c(self->inner.st, out00);
+  core_ops_range_Range_b3 iter =
+      core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter(
+          (CLITERAL(core_ops_range_Range_b3){.start = (size_t)1U,
+                                             .end = blocks}),
+          core_ops_range_Range_b3, core_ops_range_Range_b3);
+  while (true) {
+    if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next(
+            &iter, size_t, Option_b3)
+            .tag == None) {
+      break;
+    } else {
+      Eurydice_slice_uint8_t_1size_t__x2 uu____1 =
+          libcrux_sha3_portable_keccak_split_at_mut_n_5a(out_rest,
+                                                         (size_t)136U);
+      Eurydice_slice out0[1U];
+      memcpy(out0, uu____1.fst, (size_t)1U * sizeof(Eurydice_slice));
+      Eurydice_slice tmp[1U];
+      memcpy(tmp, uu____1.snd, (size_t)1U * sizeof(Eurydice_slice));
+      libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner);
+      libcrux_sha3_portable_keccak_store_5a_1c(self->inner.st, out0);
+      memcpy(out_rest, tmp, (size_t)1U * sizeof(Eurydice_slice));
+    }
+  }
+  if (last < out_len) {
+    libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner);
+    libcrux_sha3_portable_keccak_store_5a_1c(self->inner.st, out_rest);
+  }
+  self->sponge = true;
+}
+
+/**
+ Shake256 squeeze
+*/
+/**
+This function found in impl
+{(libcrux_sha3::portable::incremental::XofSqueeze<136: usize> for
+libcrux_sha3::portable::incremental::Shake256Squeeze)#3}
+*/
+static inline void libcrux_sha3_portable_incremental_squeeze_8a(
+    libcrux_sha3_generic_keccak_KeccakXofState_4f *self, Eurydice_slice out) {
+  Eurydice_slice buf[1U] = {out};
+  libcrux_sha3_generic_keccak_squeeze_9d_96(self, buf);
+}
+
+/**
+ `out` has the exact size we want here. It must be less than or equal to `RATE`.
+*/
+/**
+This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1:
+usize> for u64)}
+*/
+/**
+A monomorphic instance of libcrux_sha3.portable_keccak.store_5a
+with const generics
+- RATE= 168
+*/
+static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_5a_1c0(
+    uint64_t (*state)[5U], Eurydice_slice out[1U]) {
+  size_t num_full_blocks = Eurydice_slice_len(out[0U], uint8_t) / (size_t)8U;
+  size_t last_block_len = Eurydice_slice_len(out[0U], uint8_t) % (size_t)8U;
+  for (size_t i = (size_t)0U; i < num_full_blocks; i++) {
+    size_t i0 = i;
+    Eurydice_slice uu____0 = Eurydice_slice_subslice2(
+        out[0U], i0 * (size_t)8U, i0 * (size_t)8U + (size_t)8U, uint8_t);
+    uint8_t ret[8U];
+    core_num__u64_9__to_le_bytes(state[i0 / (size_t)5U][i0 % (size_t)5U], ret);
+    Eurydice_slice_copy(
+        uu____0, Eurydice_array_to_slice((size_t)8U, ret, uint8_t), uint8_t);
+  }
+  if (last_block_len != (size_t)0U) {
+    Eurydice_slice uu____1 = Eurydice_slice_subslice2(
+        out[0U], num_full_blocks * (size_t)8U,
+        num_full_blocks * (size_t)8U + last_block_len, uint8_t);
+    uint8_t ret[8U];
+    core_num__u64_9__to_le_bytes(
+        state[num_full_blocks / (size_t)5U][num_full_blocks % (size_t)5U], ret);
+    Eurydice_slice_copy(
+        uu____1,
+        Eurydice_array_to_subslice2(ret, (size_t)0U, last_block_len, uint8_t),
+        uint8_t);
+  }
+}
+
+/**
+ Squeeze `N` x `LEN` bytes.
+*/
+/**
+This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState<STATE,
+PARALLEL_LANES, RATE>[TraitClause@0]#2}
+*/
+/**
+A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_9d
+with types uint64_t
+with const generics
+- PARALLEL_LANES= 1
+- RATE= 168
+*/
+static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_9d_960(
+    libcrux_sha3_generic_keccak_KeccakXofState_78 *self,
+    Eurydice_slice out[1U]) {
+  if (self->sponge) {
+    libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner);
+  }
+  size_t out_len = Eurydice_slice_len(out[0U], uint8_t);
+  size_t blocks = out_len / (size_t)168U;
+  size_t last = out_len - out_len % (size_t)168U;
+  size_t mid;
+  if ((size_t)168U >= out_len) {
+    mid = out_len;
+  } else {
+    mid = (size_t)168U;
+  }
+  Eurydice_slice_uint8_t_1size_t__x2 uu____0 =
+      libcrux_sha3_portable_keccak_split_at_mut_n_5a(out, mid);
+  Eurydice_slice out00[1U];
+  memcpy(out00, uu____0.fst, (size_t)1U * sizeof(Eurydice_slice));
+  Eurydice_slice out_rest[1U];
+  memcpy(out_rest, uu____0.snd, (size_t)1U * sizeof(Eurydice_slice));
+  libcrux_sha3_portable_keccak_store_5a_1c0(self->inner.st, out00);
+  core_ops_range_Range_b3 iter =
+      core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter(
+          (CLITERAL(core_ops_range_Range_b3){.start = (size_t)1U,
+                                             .end = blocks}),
+          core_ops_range_Range_b3, core_ops_range_Range_b3);
+  while (true) {
+    if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next(
+            &iter, size_t, Option_b3)
+            .tag == None) {
+      break;
+    } else {
+      Eurydice_slice_uint8_t_1size_t__x2 uu____1 =
+          libcrux_sha3_portable_keccak_split_at_mut_n_5a(out_rest,
+                                                         (size_t)168U);
+      Eurydice_slice out0[1U];
+      memcpy(out0, uu____1.fst, (size_t)1U * sizeof(Eurydice_slice));
+      Eurydice_slice tmp[1U];
+      memcpy(tmp, uu____1.snd, (size_t)1U * sizeof(Eurydice_slice));
+      libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner);
+      libcrux_sha3_portable_keccak_store_5a_1c0(self->inner.st, out0);
+      memcpy(out_rest, tmp, (size_t)1U * sizeof(Eurydice_slice));
+    }
+  }
+  if (last < out_len) {
+    libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner);
+    libcrux_sha3_portable_keccak_store_5a_1c0(self->inner.st, out_rest);
+  }
+  self->sponge = true;
+}
+
+/**
+ Shake128 squeeze
+*/
+/**
+This function found in impl
+{(libcrux_sha3::portable::incremental::XofSqueeze<168: usize> for
+libcrux_sha3::portable::incremental::Shake128Squeeze)#1}
+*/
+static inline void libcrux_sha3_portable_incremental_squeeze_10(
+    libcrux_sha3_generic_keccak_KeccakXofState_78 *self, Eurydice_slice out) {
+  Eurydice_slice buf[1U] = {out};
+  libcrux_sha3_generic_keccak_squeeze_9d_960(self, buf);
+}
+
+/**
+This function found in impl {(core::clone::Clone for
+libcrux_sha3::portable::KeccakState)}
+*/
+static inline libcrux_sha3_generic_keccak_KeccakState_48
+libcrux_sha3_portable_clone_3d(
+    libcrux_sha3_generic_keccak_KeccakState_48 *self) {
+  return self[0U];
+}
+
+/**
+This function found in impl {(core::convert::From<libcrux_sha3::Algorithm> for
+u32)#1}
+*/
+static inline uint32_t libcrux_sha3_from_eb(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;
+}
+
+/**
+This function found in impl {(core::convert::From<u32> for
+libcrux_sha3::Algorithm)}
+*/
+static inline libcrux_sha3_Algorithm libcrux_sha3_from_2d(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
+
+/* from libcrux/libcrux-ml-kem/cg/libcrux_mlkem768_portable.h */
+/*
+ * SPDX-FileCopyrightText: 2024 Cryspen Sarl <info@cryspen.com>
+ *
+ * SPDX-License-Identifier: MIT or Apache-2.0
+ *
+ * This code was generated with the following revisions:
+ * Charon: 6b5e110342a771a3e1c739b10294b1778e4be8b4
+ * Eurydice: 31be7d65ca5d6acdacfb33652e478d24dd85c1cb
+ * Karamel: 3205d3365ea2790b02368f79fcee38e38d0b5908
+ * F*: a32b316e521fa4f239b610ec8f1d15e78d62cbe8-dirty
+ * Libcrux: 4ad532b206174114dd4140b718e7794a28fc59ee
+ */
+
+#ifndef __libcrux_mlkem768_portable_H
+#define __libcrux_mlkem768_portable_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+#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)
+
+static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_G(
+    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), input);
+  memcpy(ret, digest, (size_t)64U * sizeof(uint8_t));
+}
+
+static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_H(
+    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), input);
+  memcpy(ret, digest, (size_t)32U * sizeof(uint8_t));
+}
+
+#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)
+
+typedef struct libcrux_ml_kem_vector_portable_vector_type_PortableVector_s {
+  int16_t elements[16U];
+} libcrux_ml_kem_vector_portable_vector_type_PortableVector;
+
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_vector_type_from_i16_array(
+    Eurydice_slice array) {
+  libcrux_ml_kem_vector_portable_vector_type_PortableVector lit;
+  int16_t ret[16U];
+  Result_c0 dst;
+  Eurydice_slice_to_array2(
+      &dst, Eurydice_slice_subslice2(array, (size_t)0U, (size_t)16U, int16_t),
+      Eurydice_slice, int16_t[16U]);
+  unwrap_41_f9(dst, ret);
+  memcpy(lit.elements, ret, (size_t)16U * sizeof(int16_t));
+  return lit;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_from_i16_array_0d(Eurydice_slice array) {
+  return libcrux_ml_kem_vector_portable_vector_type_from_i16_array(array);
+}
+
+typedef struct uint8_t_x11_s {
+  uint8_t fst;
+  uint8_t snd;
+  uint8_t thd;
+  uint8_t f3;
+  uint8_t f4;
+  uint8_t f5;
+  uint8_t f6;
+  uint8_t f7;
+  uint8_t f8;
+  uint8_t f9;
+  uint8_t f10;
+} uint8_t_x11;
+
+static KRML_MUSTINLINE uint8_t_x11
+libcrux_ml_kem_vector_portable_serialize_serialize_11_int(Eurydice_slice v) {
+  uint8_t r0 = (uint8_t)Eurydice_slice_index(v, (size_t)0U, int16_t, int16_t *);
+  uint8_t r1 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)1U, int16_t,
+                                                        int16_t *) &
+                                   (int16_t)31)
+                   << 3U |
+               (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)0U, int16_t,
+                                                        int16_t *) >>
+                                   8U);
+  uint8_t r2 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)2U, int16_t,
+                                                        int16_t *) &
+                                   (int16_t)3)
+                   << 6U |
+               (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)1U, int16_t,
+                                                        int16_t *) >>
+                                   5U);
+  uint8_t r3 =
+      (uint8_t)(Eurydice_slice_index(v, (size_t)2U, int16_t, int16_t *) >> 2U &
+                (int16_t)255);
+  uint8_t r4 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)3U, int16_t,
+                                                        int16_t *) &
+                                   (int16_t)127)
+                   << 1U |
+               (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)2U, int16_t,
+                                                        int16_t *) >>
+                                   10U);
+  uint8_t r5 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)4U, int16_t,
+                                                        int16_t *) &
+                                   (int16_t)15)
+                   << 4U |
+               (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)3U, int16_t,
+                                                        int16_t *) >>
+                                   7U);
+  uint8_t r6 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)5U, int16_t,
+                                                        int16_t *) &
+                                   (int16_t)1)
+                   << 7U |
+               (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)4U, int16_t,
+                                                        int16_t *) >>
+                                   4U);
+  uint8_t r7 =
+      (uint8_t)(Eurydice_slice_index(v, (size_t)5U, int16_t, int16_t *) >> 1U &
+                (int16_t)255);
+  uint8_t r8 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)6U, int16_t,
+                                                        int16_t *) &
+                                   (int16_t)63)
+                   << 2U |
+               (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)5U, int16_t,
+                                                        int16_t *) >>
+                                   9U);
+  uint8_t r9 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)7U, int16_t,
+                                                        int16_t *) &
+                                   (int16_t)7)
+                   << 5U |
+               (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)6U, int16_t,
+                                                        int16_t *) >>
+                                   6U);
+  uint8_t r10 =
+      (uint8_t)(Eurydice_slice_index(v, (size_t)7U, int16_t, int16_t *) >> 3U);
+  return (CLITERAL(uint8_t_x11){.fst = r0,
+                                .snd = r1,
+                                .thd = r2,
+                                .f3 = r3,
+                                .f4 = r4,
+                                .f5 = r5,
+                                .f6 = r6,
+                                .f7 = r7,
+                                .f8 = r8,
+                                .f9 = r9,
+                                .f10 = r10});
+}
+
+static KRML_MUSTINLINE void
+libcrux_ml_kem_vector_portable_serialize_serialize_11(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v,
+    uint8_t ret[22U]) {
+  uint8_t_x11 r0_10 = libcrux_ml_kem_vector_portable_serialize_serialize_11_int(
+      Eurydice_array_to_subslice2(v.elements, (size_t)0U, (size_t)8U, int16_t));
+  uint8_t_x11 r11_21 =
+      libcrux_ml_kem_vector_portable_serialize_serialize_11_int(
+          Eurydice_array_to_subslice2(v.elements, (size_t)8U, (size_t)16U,
+                                      int16_t));
+  uint8_t result[22U] = {0U};
+  result[0U] = r0_10.fst;
+  result[1U] = r0_10.snd;
+  result[2U] = r0_10.thd;
+  result[3U] = r0_10.f3;
+  result[4U] = r0_10.f4;
+  result[5U] = r0_10.f5;
+  result[6U] = r0_10.f6;
+  result[7U] = r0_10.f7;
+  result[8U] = r0_10.f8;
+  result[9U] = r0_10.f9;
+  result[10U] = r0_10.f10;
+  result[11U] = r11_21.fst;
+  result[12U] = r11_21.snd;
+  result[13U] = r11_21.thd;
+  result[14U] = r11_21.f3;
+  result[15U] = r11_21.f4;
+  result[16U] = r11_21.f5;
+  result[17U] = r11_21.f6;
+  result[18U] = r11_21.f7;
+  result[19U] = r11_21.f8;
+  result[20U] = r11_21.f9;
+  result[21U] = r11_21.f10;
+  memcpy(ret, result, (size_t)22U * sizeof(uint8_t));
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline void libcrux_ml_kem_vector_portable_serialize_11_0d(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector a,
+    uint8_t ret[22U]) {
+  libcrux_ml_kem_vector_portable_serialize_serialize_11(a, ret);
+}
+
+typedef struct int16_t_x8_s {
+  int16_t fst;
+  int16_t snd;
+  int16_t thd;
+  int16_t f3;
+  int16_t f4;
+  int16_t f5;
+  int16_t f6;
+  int16_t f7;
+} int16_t_x8;
+
+static KRML_MUSTINLINE int16_t_x8
+libcrux_ml_kem_vector_portable_serialize_deserialize_11_int(
+    Eurydice_slice bytes) {
+  int16_t r0 =
+      ((int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *) &
+       (int16_t)7)
+          << 8U |
+      (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *);
+  int16_t r1 =
+      ((int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *) &
+       (int16_t)63)
+          << 5U |
+      (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *) >>
+          3U;
+  int16_t r2 =
+      (((int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *) &
+        (int16_t)1)
+           << 10U |
+       (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *)
+           << 2U) |
+      (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *) >>
+          6U;
+  int16_t r3 =
+      ((int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *) &
+       (int16_t)15)
+          << 7U |
+      (int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *) >>
+          1U;
+  int16_t r4 =
+      ((int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *) &
+       (int16_t)127)
+          << 4U |
+      (int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *) >>
+          4U;
+  int16_t r5 =
+      (((int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *) &
+        (int16_t)3)
+           << 9U |
+       (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *)
+           << 1U) |
+      (int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *) >>
+          7U;
+  int16_t r6 =
+      ((int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *) &
+       (int16_t)31)
+          << 6U |
+      (int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *) >>
+          2U;
+  int16_t r7 =
+      (int16_t)Eurydice_slice_index(bytes, (size_t)10U, uint8_t, uint8_t *)
+          << 3U |
+      (int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *) >>
+          5U;
+  return (CLITERAL(int16_t_x8){.fst = r0,
+                               .snd = r1,
+                               .thd = r2,
+                               .f3 = r3,
+                               .f4 = r4,
+                               .f5 = r5,
+                               .f6 = r6,
+                               .f7 = r7});
+}
+
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_vector_type_zero(void) {
+  libcrux_ml_kem_vector_portable_vector_type_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 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_serialize_deserialize_11(Eurydice_slice bytes) {
+  int16_t_x8 v0_7 = libcrux_ml_kem_vector_portable_serialize_deserialize_11_int(
+      Eurydice_slice_subslice2(bytes, (size_t)0U, (size_t)11U, uint8_t));
+  int16_t_x8 v8_15 =
+      libcrux_ml_kem_vector_portable_serialize_deserialize_11_int(
+          Eurydice_slice_subslice2(bytes, (size_t)11U, (size_t)22U, uint8_t));
+  libcrux_ml_kem_vector_portable_vector_type_PortableVector v =
+      libcrux_ml_kem_vector_portable_vector_type_zero();
+  v.elements[0U] = v0_7.fst;
+  v.elements[1U] = v0_7.snd;
+  v.elements[2U] = v0_7.thd;
+  v.elements[3U] = v0_7.f3;
+  v.elements[4U] = v0_7.f4;
+  v.elements[5U] = v0_7.f5;
+  v.elements[6U] = v0_7.f6;
+  v.elements[7U] = v0_7.f7;
+  v.elements[8U] = v8_15.fst;
+  v.elements[9U] = v8_15.snd;
+  v.elements[10U] = v8_15.thd;
+  v.elements[11U] = v8_15.f3;
+  v.elements[12U] = v8_15.f4;
+  v.elements[13U] = v8_15.f5;
+  v.elements[14U] = v8_15.f6;
+  v.elements[15U] = v8_15.f7;
+  return v;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_deserialize_11_0d(Eurydice_slice a) {
+  return libcrux_ml_kem_vector_portable_serialize_deserialize_11(a);
+}
+
+static KRML_MUSTINLINE void
+libcrux_ml_kem_vector_portable_vector_type_to_i16_array(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector x,
+    int16_t ret[16U]) {
+  memcpy(ret, x.elements, (size_t)16U * sizeof(int16_t));
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline void libcrux_ml_kem_vector_portable_to_i16_array_0d(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector x,
+    int16_t ret[16U]) {
+  libcrux_ml_kem_vector_portable_vector_type_to_i16_array(x, ret);
+}
+
+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}};
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_ZERO_0d(void) {
+  return libcrux_ml_kem_vector_portable_vector_type_zero();
+}
+
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_arithmetic_add(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector lhs,
+    libcrux_ml_kem_vector_portable_vector_type_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;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_add_0d(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector lhs,
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector *rhs) {
+  return libcrux_ml_kem_vector_portable_arithmetic_add(lhs, rhs);
+}
+
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_arithmetic_sub(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector lhs,
+    libcrux_ml_kem_vector_portable_vector_type_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;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_sub_0d(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector lhs,
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector *rhs) {
+  return libcrux_ml_kem_vector_portable_arithmetic_sub(lhs, rhs);
+}
+
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_arithmetic_multiply_by_constant(
+    libcrux_ml_kem_vector_portable_vector_type_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;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_multiply_by_constant_0d(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t c) {
+  return libcrux_ml_kem_vector_portable_arithmetic_multiply_by_constant(v, c);
+}
+
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_arithmetic_bitwise_and_with_constant(
+    libcrux_ml_kem_vector_portable_vector_type_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;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_bitwise_and_with_constant_0d(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t c) {
+  return libcrux_ml_kem_vector_portable_arithmetic_bitwise_and_with_constant(v,
+                                                                             c);
+}
+
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_arithmetic_cond_subtract_3329(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v) {
+  core_ops_range_Range_b3 iter =
+      core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter(
+          (CLITERAL(core_ops_range_Range_b3){
+              .start = (size_t)0U,
+              .end = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR}),
+          core_ops_range_Range_b3, core_ops_range_Range_b3);
+  while (true) {
+    Option_b3 uu____0 =
+        core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next(
+            &iter, size_t, Option_b3);
+    if (!(uu____0.tag == 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;
+  }
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_cond_subtract_3329_0d(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v) {
+  return libcrux_ml_kem_vector_portable_arithmetic_cond_subtract_3329(v);
+}
+
+#define LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_BARRETT_MULTIPLIER \
+  ((int32_t)20159)
+
+#define LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_BARRETT_SHIFT ((int32_t)26)
+
+#define LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_BARRETT_R \
+  ((int32_t)1 << (uint32_t)                                 \
+       LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_BARRETT_SHIFT)
+
+/**
+ Signed Barrett Reduction
+
+ Given an input `value`, `barrett_reduce` outputs a representative `result`
+ such that:
+
+ - result ≡ value (mod FIELD_MODULUS)
+ - the absolute value of `result` is bound as follows:
+
+ `|result| ≤ FIELD_MODULUS / 2 · (|value|/BARRETT_R + 1)
+
+ In particular, if `|value| < BARRETT_R`, then `|result| < FIELD_MODULUS`.
+*/
+static inline int16_t
+libcrux_ml_kem_vector_portable_arithmetic_barrett_reduce_element(
+    int16_t value) {
+  int32_t t = (int32_t)value *
+                  LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_BARRETT_MULTIPLIER +
+              (LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_BARRETT_R >> 1U);
+  int16_t quotient =
+      (int16_t)(t >>
+                (uint32_t)
+                    LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_BARRETT_SHIFT);
+  return value - quotient * LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS;
+}
+
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_arithmetic_barrett_reduce(
+    libcrux_ml_kem_vector_portable_vector_type_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] =
+        libcrux_ml_kem_vector_portable_arithmetic_barrett_reduce_element(
+            v.elements[i0]);
+  }
+  return v;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_barrett_reduce_0d(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v) {
+  return libcrux_ml_kem_vector_portable_arithmetic_barrett_reduce(v);
+}
+
+#define LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_MONTGOMERY_SHIFT (16U)
+
+#define LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_MONTGOMERY_R \
+  ((int32_t)1 << (uint32_t)                                    \
+       LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_MONTGOMERY_SHIFT)
+
+/**
+ Signed Montgomery Reduction
+
+ Given an input `value`, `montgomery_reduce` outputs a representative `o`
+ such that:
+
+ - o ≡ value · MONTGOMERY_R^(-1) (mod FIELD_MODULUS)
+ - the absolute value of `o` is bound as follows:
+
+ `|result| ≤ (|value| / MONTGOMERY_R) + (FIELD_MODULUS / 2)
+
+ In particular, if `|value| ≤ FIELD_MODULUS * MONTGOMERY_R`, then `|o| < (3 ·
+ FIELD_MODULUS) / 2`.
+*/
+static inline int16_t
+libcrux_ml_kem_vector_portable_arithmetic_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_PORTABLE_ARITHMETIC_MONTGOMERY_SHIFT);
+  int16_t value_high =
+      (int16_t)(value >>
+                (uint32_t)
+                    LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_MONTGOMERY_SHIFT);
+  return value_high - c;
+}
+
+/**
+ If `fe` is some field element 'x' of the Kyber field and `fer` is congruent to
+ `y · MONTGOMERY_R`, this procedure outputs a value that is congruent to
+ `x · y`, as follows:
+
+    `fe · fer ≡ x · y · MONTGOMERY_R (mod FIELD_MODULUS)`
+
+ `montgomery_reduce` takes the value `x · y · MONTGOMERY_R` and outputs a
+ representative `x · y · MONTGOMERY_R * MONTGOMERY_R^{-1} ≡ x · y (mod
+ FIELD_MODULUS)`.
+*/
+static KRML_MUSTINLINE int16_t
+libcrux_ml_kem_vector_portable_arithmetic_montgomery_multiply_fe_by_fer(
+    int16_t fe, int16_t fer) {
+  return libcrux_ml_kem_vector_portable_arithmetic_montgomery_reduce_element(
+      (int32_t)fe * (int32_t)fer);
+}
+
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_arithmetic_montgomery_multiply_by_constant(
+    libcrux_ml_kem_vector_portable_vector_type_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;
+    v.elements[i0] =
+        libcrux_ml_kem_vector_portable_arithmetic_montgomery_multiply_fe_by_fer(
+            v.elements[i0], c);
+  }
+  return v;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_0d(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t r) {
+  return libcrux_ml_kem_vector_portable_arithmetic_montgomery_multiply_by_constant(
+      v, r);
+}
+
+/**
+ The `compress_*` functions implement the `Compress` function specified in the
+ NIST FIPS 203 standard (Page 18, Expression 4.5), which is defined as:
+
+ ```plaintext
+ Compress_d: ℤq -> ℤ_{2ᵈ}
+ Compress_d(x) = ⌈(2ᵈ/q)·x⌋
+ ```
+
+ Since `⌈x⌋ = ⌊x + 1/2⌋` we have:
+
+ ```plaintext
+ Compress_d(x) = ⌊(2ᵈ/q)·x + 1/2⌋
+               = ⌊(2^{d+1}·x + q) / 2q⌋
+ ```
+
+ For further information about the function implementations, consult the
+ `implementation_notes.pdf` document in this directory.
+
+ The NIST FIPS 203 standard can be found at
+ <https://csrc.nist.gov/pubs/fips/203/ipd>.
+*/
+static inline uint8_t
+libcrux_ml_kem_vector_portable_compress_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 KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_compress_compress_1(
+    libcrux_ml_kem_vector_portable_vector_type_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] = (int16_t)
+        libcrux_ml_kem_vector_portable_compress_compress_message_coefficient(
+            (uint16_t)v.elements[i0]);
+  }
+  return v;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_compress_1_0d(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v) {
+  return libcrux_ml_kem_vector_portable_compress_compress_1(v);
+}
+
+static KRML_MUSTINLINE uint32_t
+libcrux_ml_kem_vector_portable_arithmetic_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_portable_compress_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_portable_arithmetic_get_n_least_significant_bits(
+          coefficient_bits, (uint32_t)compressed);
+}
+
+static KRML_MUSTINLINE void libcrux_ml_kem_vector_portable_ntt_ntt_step(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector *v, int16_t zeta,
+    size_t i, size_t j) {
+  int16_t t =
+      libcrux_ml_kem_vector_portable_arithmetic_montgomery_multiply_fe_by_fer(
+          v->elements[j], zeta);
+  v->elements[j] = v->elements[i] - t;
+  v->elements[i] = v->elements[i] + t;
+}
+
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_ntt_ntt_layer_1_step(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t zeta0,
+    int16_t zeta1, int16_t zeta2, int16_t zeta3) {
+  libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta0, (size_t)0U,
+                                              (size_t)2U);
+  libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta0, (size_t)1U,
+                                              (size_t)3U);
+  libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta1, (size_t)4U,
+                                              (size_t)6U);
+  libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta1, (size_t)5U,
+                                              (size_t)7U);
+  libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta2, (size_t)8U,
+                                              (size_t)10U);
+  libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta2, (size_t)9U,
+                                              (size_t)11U);
+  libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta3, (size_t)12U,
+                                              (size_t)14U);
+  libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta3, (size_t)13U,
+                                              (size_t)15U);
+  return v;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_ntt_layer_1_step_0d(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector a, int16_t zeta0,
+    int16_t zeta1, int16_t zeta2, int16_t zeta3) {
+  return libcrux_ml_kem_vector_portable_ntt_ntt_layer_1_step(a, zeta0, zeta1,
+                                                             zeta2, zeta3);
+}
+
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_ntt_ntt_layer_2_step(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t zeta0,
+    int16_t zeta1) {
+  libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta0, (size_t)0U,
+                                              (size_t)4U);
+  libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta0, (size_t)1U,
+                                              (size_t)5U);
+  libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta0, (size_t)2U,
+                                              (size_t)6U);
+  libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta0, (size_t)3U,
+                                              (size_t)7U);
+  libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta1, (size_t)8U,
+                                              (size_t)12U);
+  libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta1, (size_t)9U,
+                                              (size_t)13U);
+  libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta1, (size_t)10U,
+                                              (size_t)14U);
+  libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta1, (size_t)11U,
+                                              (size_t)15U);
+  return v;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_ntt_layer_2_step_0d(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector a, int16_t zeta0,
+    int16_t zeta1) {
+  return libcrux_ml_kem_vector_portable_ntt_ntt_layer_2_step(a, zeta0, zeta1);
+}
+
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_ntt_ntt_layer_3_step(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t zeta) {
+  libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta, (size_t)0U, (size_t)8U);
+  libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta, (size_t)1U, (size_t)9U);
+  libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta, (size_t)2U,
+                                              (size_t)10U);
+  libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta, (size_t)3U,
+                                              (size_t)11U);
+  libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta, (size_t)4U,
+                                              (size_t)12U);
+  libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta, (size_t)5U,
+                                              (size_t)13U);
+  libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta, (size_t)6U,
+                                              (size_t)14U);
+  libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta, (size_t)7U,
+                                              (size_t)15U);
+  return v;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_ntt_layer_3_step_0d(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector a, int16_t zeta) {
+  return libcrux_ml_kem_vector_portable_ntt_ntt_layer_3_step(a, zeta);
+}
+
+static KRML_MUSTINLINE void libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector *v, int16_t zeta,
+    size_t i, size_t j) {
+  int16_t a_minus_b = v->elements[j] - v->elements[i];
+  v->elements[i] =
+      libcrux_ml_kem_vector_portable_arithmetic_barrett_reduce_element(
+          v->elements[i] + v->elements[j]);
+  v->elements[j] =
+      libcrux_ml_kem_vector_portable_arithmetic_montgomery_multiply_fe_by_fer(
+          a_minus_b, zeta);
+}
+
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_ntt_inv_ntt_layer_1_step(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t zeta0,
+    int16_t zeta1, int16_t zeta2, int16_t zeta3) {
+  libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta0, (size_t)0U,
+                                                  (size_t)2U);
+  libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta0, (size_t)1U,
+                                                  (size_t)3U);
+  libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta1, (size_t)4U,
+                                                  (size_t)6U);
+  libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta1, (size_t)5U,
+                                                  (size_t)7U);
+  libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta2, (size_t)8U,
+                                                  (size_t)10U);
+  libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta2, (size_t)9U,
+                                                  (size_t)11U);
+  libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta3, (size_t)12U,
+                                                  (size_t)14U);
+  libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta3, (size_t)13U,
+                                                  (size_t)15U);
+  return v;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_inv_ntt_layer_1_step_0d(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector a, int16_t zeta0,
+    int16_t zeta1, int16_t zeta2, int16_t zeta3) {
+  return libcrux_ml_kem_vector_portable_ntt_inv_ntt_layer_1_step(
+      a, zeta0, zeta1, zeta2, zeta3);
+}
+
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_ntt_inv_ntt_layer_2_step(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t zeta0,
+    int16_t zeta1) {
+  libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta0, (size_t)0U,
+                                                  (size_t)4U);
+  libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta0, (size_t)1U,
+                                                  (size_t)5U);
+  libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta0, (size_t)2U,
+                                                  (size_t)6U);
+  libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta0, (size_t)3U,
+                                                  (size_t)7U);
+  libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta1, (size_t)8U,
+                                                  (size_t)12U);
+  libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta1, (size_t)9U,
+                                                  (size_t)13U);
+  libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta1, (size_t)10U,
+                                                  (size_t)14U);
+  libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta1, (size_t)11U,
+                                                  (size_t)15U);
+  return v;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_inv_ntt_layer_2_step_0d(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector a, int16_t zeta0,
+    int16_t zeta1) {
+  return libcrux_ml_kem_vector_portable_ntt_inv_ntt_layer_2_step(a, zeta0,
+                                                                 zeta1);
+}
+
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_ntt_inv_ntt_layer_3_step(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t zeta) {
+  libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta, (size_t)0U,
+                                                  (size_t)8U);
+  libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta, (size_t)1U,
+                                                  (size_t)9U);
+  libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta, (size_t)2U,
+                                                  (size_t)10U);
+  libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta, (size_t)3U,
+                                                  (size_t)11U);
+  libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta, (size_t)4U,
+                                                  (size_t)12U);
+  libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta, (size_t)5U,
+                                                  (size_t)13U);
+  libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta, (size_t)6U,
+                                                  (size_t)14U);
+  libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta, (size_t)7U,
+                                                  (size_t)15U);
+  return v;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_inv_ntt_layer_3_step_0d(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector a, int16_t zeta) {
+  return libcrux_ml_kem_vector_portable_ntt_inv_ntt_layer_3_step(a, zeta);
+}
+
+/**
+ Compute the product of two Kyber binomials with respect to the
+ modulus `X² - zeta`.
+
+ This function almost implements <strong>Algorithm 11</strong> of the
+ NIST FIPS 203 standard, which is reproduced below:
+
+ ```plaintext
+ Input:  a₀, a₁, b₀, b₁ ∈ ℤq.
+ Input: γ ∈ ℤq.
+ Output: c₀, c₁ ∈ ℤq.
+
+ c₀ ← a₀·b₀ + a₁·b₁·γ
+ c₁ ← a₀·b₁ + a₁·b₀
+ return c₀, c₁
+ ```
+ We say "almost" because the coefficients output by this function are in
+ the Montgomery domain (unlike in the specification).
+
+ The NIST FIPS 203 standard can be found at
+ <https://csrc.nist.gov/pubs/fips/203/ipd>.
+*/
+static KRML_MUSTINLINE void
+libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector *a,
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector *b, int16_t zeta,
+    size_t i, size_t j,
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector *out) {
+  int16_t o0 = libcrux_ml_kem_vector_portable_arithmetic_montgomery_reduce_element(
+      (int32_t)a->elements[i] * (int32_t)b->elements[i] +
+      (int32_t)
+              libcrux_ml_kem_vector_portable_arithmetic_montgomery_reduce_element(
+                  (int32_t)a->elements[j] * (int32_t)b->elements[j]) *
+          (int32_t)zeta);
+  int16_t o1 =
+      libcrux_ml_kem_vector_portable_arithmetic_montgomery_reduce_element(
+          (int32_t)a->elements[i] * (int32_t)b->elements[j] +
+          (int32_t)a->elements[j] * (int32_t)b->elements[i]);
+  out->elements[i] = o0;
+  out->elements[j] = o1;
+}
+
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_ntt_ntt_multiply(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector *lhs,
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector *rhs,
+    int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3) {
+  libcrux_ml_kem_vector_portable_vector_type_PortableVector out =
+      libcrux_ml_kem_vector_portable_vector_type_zero();
+  libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials(
+      lhs, rhs, zeta0, (size_t)0U, (size_t)1U, &out);
+  libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials(
+      lhs, rhs, -zeta0, (size_t)2U, (size_t)3U, &out);
+  libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials(
+      lhs, rhs, zeta1, (size_t)4U, (size_t)5U, &out);
+  libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials(
+      lhs, rhs, -zeta1, (size_t)6U, (size_t)7U, &out);
+  libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials(
+      lhs, rhs, zeta2, (size_t)8U, (size_t)9U, &out);
+  libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials(
+      lhs, rhs, -zeta2, (size_t)10U, (size_t)11U, &out);
+  libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials(
+      lhs, rhs, zeta3, (size_t)12U, (size_t)13U, &out);
+  libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials(
+      lhs, rhs, -zeta3, (size_t)14U, (size_t)15U, &out);
+  return out;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_ntt_multiply_0d(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector *lhs,
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector *rhs,
+    int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3) {
+  return libcrux_ml_kem_vector_portable_ntt_ntt_multiply(lhs, rhs, zeta0, zeta1,
+                                                         zeta2, zeta3);
+}
+
+static KRML_MUSTINLINE void
+libcrux_ml_kem_vector_portable_serialize_serialize_1(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v,
+    uint8_t ret[2U]) {
+  uint8_t result[2U] = {0U};
+  for (size_t i = (size_t)0U; i < (size_t)8U; i++) {
+    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;
+  }
+  for (size_t i = (size_t)8U; i < (size_t)16U; i++) {
+    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));
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline void libcrux_ml_kem_vector_portable_serialize_1_0d(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector a,
+    uint8_t ret[2U]) {
+  libcrux_ml_kem_vector_portable_serialize_serialize_1(a, ret);
+}
+
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_serialize_deserialize_1(Eurydice_slice v) {
+  libcrux_ml_kem_vector_portable_vector_type_PortableVector result =
+      libcrux_ml_kem_vector_portable_vector_type_zero();
+  for (size_t i = (size_t)0U; i < (size_t)8U; i++) {
+    size_t i0 = i;
+    result.elements[i0] = (int16_t)((uint32_t)Eurydice_slice_index(
+                                        v, (size_t)0U, uint8_t, uint8_t *) >>
+                                        (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;
+    result.elements[i0] = (int16_t)((uint32_t)Eurydice_slice_index(
+                                        v, (size_t)1U, uint8_t, uint8_t *) >>
+                                        (uint32_t)(i0 - (size_t)8U) &
+                                    1U);
+  }
+  return result;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_deserialize_1_0d(Eurydice_slice a) {
+  return libcrux_ml_kem_vector_portable_serialize_deserialize_1(a);
+}
+
+typedef struct uint8_t_x4_s {
+  uint8_t fst;
+  uint8_t snd;
+  uint8_t thd;
+  uint8_t f3;
+} uint8_t_x4;
+
+static KRML_MUSTINLINE uint8_t_x4
+libcrux_ml_kem_vector_portable_serialize_serialize_4_int(Eurydice_slice v) {
+  uint8_t result0 =
+      (uint32_t)(uint8_t)Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *)
+          << 4U |
+      (uint32_t)(uint8_t)Eurydice_slice_index(v, (size_t)0U, int16_t,
+                                              int16_t *);
+  uint8_t result1 =
+      (uint32_t)(uint8_t)Eurydice_slice_index(v, (size_t)3U, int16_t, int16_t *)
+          << 4U |
+      (uint32_t)(uint8_t)Eurydice_slice_index(v, (size_t)2U, int16_t,
+                                              int16_t *);
+  uint8_t result2 =
+      (uint32_t)(uint8_t)Eurydice_slice_index(v, (size_t)5U, int16_t, int16_t *)
+          << 4U |
+      (uint32_t)(uint8_t)Eurydice_slice_index(v, (size_t)4U, int16_t,
+                                              int16_t *);
+  uint8_t result3 =
+      (uint32_t)(uint8_t)Eurydice_slice_index(v, (size_t)7U, int16_t, int16_t *)
+          << 4U |
+      (uint32_t)(uint8_t)Eurydice_slice_index(v, (size_t)6U, int16_t,
+                                              int16_t *);
+  return (CLITERAL(uint8_t_x4){
+      .fst = result0, .snd = result1, .thd = result2, .f3 = result3});
+}
+
+static KRML_MUSTINLINE void
+libcrux_ml_kem_vector_portable_serialize_serialize_4(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v,
+    uint8_t ret[8U]) {
+  uint8_t_x4 result0_3 =
+      libcrux_ml_kem_vector_portable_serialize_serialize_4_int(
+          Eurydice_array_to_subslice2(v.elements, (size_t)0U, (size_t)8U,
+                                      int16_t));
+  uint8_t_x4 result4_7 =
+      libcrux_ml_kem_vector_portable_serialize_serialize_4_int(
+          Eurydice_array_to_subslice2(v.elements, (size_t)8U, (size_t)16U,
+                                      int16_t));
+  uint8_t result[8U] = {0U};
+  result[0U] = result0_3.fst;
+  result[1U] = result0_3.snd;
+  result[2U] = result0_3.thd;
+  result[3U] = result0_3.f3;
+  result[4U] = result4_7.fst;
+  result[5U] = result4_7.snd;
+  result[6U] = result4_7.thd;
+  result[7U] = result4_7.f3;
+  memcpy(ret, result, (size_t)8U * sizeof(uint8_t));
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline void libcrux_ml_kem_vector_portable_serialize_4_0d(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector a,
+    uint8_t ret[8U]) {
+  libcrux_ml_kem_vector_portable_serialize_serialize_4(a, ret);
+}
+
+static KRML_MUSTINLINE int16_t_x8
+libcrux_ml_kem_vector_portable_serialize_deserialize_4_int(
+    Eurydice_slice bytes) {
+  int16_t v0 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)0U,
+                                                        uint8_t, uint8_t *) &
+                         15U);
+  int16_t v1 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)0U,
+                                                        uint8_t, uint8_t *) >>
+                             4U &
+                         15U);
+  int16_t v2 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)1U,
+                                                        uint8_t, uint8_t *) &
+                         15U);
+  int16_t v3 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)1U,
+                                                        uint8_t, uint8_t *) >>
+                             4U &
+                         15U);
+  int16_t v4 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)2U,
+                                                        uint8_t, uint8_t *) &
+                         15U);
+  int16_t v5 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)2U,
+                                                        uint8_t, uint8_t *) >>
+                             4U &
+                         15U);
+  int16_t v6 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)3U,
+                                                        uint8_t, uint8_t *) &
+                         15U);
+  int16_t v7 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)3U,
+                                                        uint8_t, uint8_t *) >>
+                             4U &
+                         15U);
+  return (CLITERAL(int16_t_x8){.fst = v0,
+                               .snd = v1,
+                               .thd = v2,
+                               .f3 = v3,
+                               .f4 = v4,
+                               .f5 = v5,
+                               .f6 = v6,
+                               .f7 = v7});
+}
+
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_serialize_deserialize_4(Eurydice_slice bytes) {
+  int16_t_x8 v0_7 = libcrux_ml_kem_vector_portable_serialize_deserialize_4_int(
+      Eurydice_slice_subslice2(bytes, (size_t)0U, (size_t)4U, uint8_t));
+  int16_t_x8 v8_15 = libcrux_ml_kem_vector_portable_serialize_deserialize_4_int(
+      Eurydice_slice_subslice2(bytes, (size_t)4U, (size_t)8U, uint8_t));
+  libcrux_ml_kem_vector_portable_vector_type_PortableVector v =
+      libcrux_ml_kem_vector_portable_vector_type_zero();
+  v.elements[0U] = v0_7.fst;
+  v.elements[1U] = v0_7.snd;
+  v.elements[2U] = v0_7.thd;
+  v.elements[3U] = v0_7.f3;
+  v.elements[4U] = v0_7.f4;
+  v.elements[5U] = v0_7.f5;
+  v.elements[6U] = v0_7.f6;
+  v.elements[7U] = v0_7.f7;
+  v.elements[8U] = v8_15.fst;
+  v.elements[9U] = v8_15.snd;
+  v.elements[10U] = v8_15.thd;
+  v.elements[11U] = v8_15.f3;
+  v.elements[12U] = v8_15.f4;
+  v.elements[13U] = v8_15.f5;
+  v.elements[14U] = v8_15.f6;
+  v.elements[15U] = v8_15.f7;
+  return v;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_deserialize_4_0d(Eurydice_slice a) {
+  return libcrux_ml_kem_vector_portable_serialize_deserialize_4(a);
+}
+
+typedef struct uint8_t_x5_s {
+  uint8_t fst;
+  uint8_t snd;
+  uint8_t thd;
+  uint8_t f3;
+  uint8_t f4;
+} uint8_t_x5;
+
+static KRML_MUSTINLINE uint8_t_x5
+libcrux_ml_kem_vector_portable_serialize_serialize_5_int(Eurydice_slice v) {
+  uint8_t r0 =
+      (uint8_t)(Eurydice_slice_index(v, (size_t)0U, int16_t, int16_t *) |
+                Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *) << 5U);
+  uint8_t r1 =
+      (uint8_t)((Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *) >> 3U |
+                 Eurydice_slice_index(v, (size_t)2U, int16_t, int16_t *)
+                     << 2U) |
+                Eurydice_slice_index(v, (size_t)3U, int16_t, int16_t *) << 7U);
+  uint8_t r2 =
+      (uint8_t)(Eurydice_slice_index(v, (size_t)3U, int16_t, int16_t *) >> 1U |
+                Eurydice_slice_index(v, (size_t)4U, int16_t, int16_t *) << 4U);
+  uint8_t r3 =
+      (uint8_t)((Eurydice_slice_index(v, (size_t)4U, int16_t, int16_t *) >> 4U |
+                 Eurydice_slice_index(v, (size_t)5U, int16_t, int16_t *)
+                     << 1U) |
+                Eurydice_slice_index(v, (size_t)6U, int16_t, int16_t *) << 6U);
+  uint8_t r4 =
+      (uint8_t)(Eurydice_slice_index(v, (size_t)6U, int16_t, int16_t *) >> 2U |
+                Eurydice_slice_index(v, (size_t)7U, int16_t, int16_t *) << 3U);
+  return (CLITERAL(uint8_t_x5){
+      .fst = r0, .snd = r1, .thd = r2, .f3 = r3, .f4 = r4});
+}
+
+static KRML_MUSTINLINE void
+libcrux_ml_kem_vector_portable_serialize_serialize_5(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v,
+    uint8_t ret[10U]) {
+  uint8_t_x5 r0_4 = libcrux_ml_kem_vector_portable_serialize_serialize_5_int(
+      Eurydice_array_to_subslice2(v.elements, (size_t)0U, (size_t)8U, int16_t));
+  uint8_t_x5 r5_9 = libcrux_ml_kem_vector_portable_serialize_serialize_5_int(
+      Eurydice_array_to_subslice2(v.elements, (size_t)8U, (size_t)16U,
+                                  int16_t));
+  uint8_t result[10U] = {0U};
+  result[0U] = r0_4.fst;
+  result[1U] = r0_4.snd;
+  result[2U] = r0_4.thd;
+  result[3U] = r0_4.f3;
+  result[4U] = r0_4.f4;
+  result[5U] = r5_9.fst;
+  result[6U] = r5_9.snd;
+  result[7U] = r5_9.thd;
+  result[8U] = r5_9.f3;
+  result[9U] = r5_9.f4;
+  memcpy(ret, result, (size_t)10U * sizeof(uint8_t));
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline void libcrux_ml_kem_vector_portable_serialize_5_0d(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector a,
+    uint8_t ret[10U]) {
+  libcrux_ml_kem_vector_portable_serialize_serialize_5(a, ret);
+}
+
+static KRML_MUSTINLINE int16_t_x8
+libcrux_ml_kem_vector_portable_serialize_deserialize_5_int(
+    Eurydice_slice bytes) {
+  int16_t v0 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)0U,
+                                                        uint8_t, uint8_t *) &
+                         31U);
+  int16_t v1 = (int16_t)(((uint32_t)Eurydice_slice_index(bytes, (size_t)1U,
+                                                         uint8_t, uint8_t *) &
+                          3U) << 3U |
+                         (uint32_t)Eurydice_slice_index(bytes, (size_t)0U,
+                                                        uint8_t, uint8_t *) >>
+                             5U);
+  int16_t v2 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)1U,
+                                                        uint8_t, uint8_t *) >>
+                             2U &
+                         31U);
+  int16_t v3 = (int16_t)(((uint32_t)Eurydice_slice_index(bytes, (size_t)2U,
+                                                         uint8_t, uint8_t *) &
+                          15U)
+                             << 1U |
+                         (uint32_t)Eurydice_slice_index(bytes, (size_t)1U,
+                                                        uint8_t, uint8_t *) >>
+                             7U);
+  int16_t v4 = (int16_t)(((uint32_t)Eurydice_slice_index(bytes, (size_t)3U,
+                                                         uint8_t, uint8_t *) &
+                          1U) << 4U |
+                         (uint32_t)Eurydice_slice_index(bytes, (size_t)2U,
+                                                        uint8_t, uint8_t *) >>
+                             4U);
+  int16_t v5 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)3U,
+                                                        uint8_t, uint8_t *) >>
+                             1U &
+                         31U);
+  int16_t v6 = (int16_t)(((uint32_t)Eurydice_slice_index(bytes, (size_t)4U,
+                                                         uint8_t, uint8_t *) &
+                          7U) << 2U |
+                         (uint32_t)Eurydice_slice_index(bytes, (size_t)3U,
+                                                        uint8_t, uint8_t *) >>
+                             6U);
+  int16_t v7 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)4U,
+                                                        uint8_t, uint8_t *) >>
+                         3U);
+  return (CLITERAL(int16_t_x8){.fst = v0,
+                               .snd = v1,
+                               .thd = v2,
+                               .f3 = v3,
+                               .f4 = v4,
+                               .f5 = v5,
+                               .f6 = v6,
+                               .f7 = v7});
+}
+
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_serialize_deserialize_5(Eurydice_slice bytes) {
+  int16_t_x8 v0_7 = libcrux_ml_kem_vector_portable_serialize_deserialize_5_int(
+      Eurydice_slice_subslice2(bytes, (size_t)0U, (size_t)5U, uint8_t));
+  int16_t_x8 v8_15 = libcrux_ml_kem_vector_portable_serialize_deserialize_5_int(
+      Eurydice_slice_subslice2(bytes, (size_t)5U, (size_t)10U, uint8_t));
+  libcrux_ml_kem_vector_portable_vector_type_PortableVector v =
+      libcrux_ml_kem_vector_portable_vector_type_zero();
+  v.elements[0U] = v0_7.fst;
+  v.elements[1U] = v0_7.snd;
+  v.elements[2U] = v0_7.thd;
+  v.elements[3U] = v0_7.f3;
+  v.elements[4U] = v0_7.f4;
+  v.elements[5U] = v0_7.f5;
+  v.elements[6U] = v0_7.f6;
+  v.elements[7U] = v0_7.f7;
+  v.elements[8U] = v8_15.fst;
+  v.elements[9U] = v8_15.snd;
+  v.elements[10U] = v8_15.thd;
+  v.elements[11U] = v8_15.f3;
+  v.elements[12U] = v8_15.f4;
+  v.elements[13U] = v8_15.f5;
+  v.elements[14U] = v8_15.f6;
+  v.elements[15U] = v8_15.f7;
+  return v;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_deserialize_5_0d(Eurydice_slice a) {
+  return libcrux_ml_kem_vector_portable_serialize_deserialize_5(a);
+}
+
+static KRML_MUSTINLINE uint8_t_x5
+libcrux_ml_kem_vector_portable_serialize_serialize_10_int(Eurydice_slice v) {
+  uint8_t r0 =
+      (uint8_t)(Eurydice_slice_index(v, (size_t)0U, int16_t, int16_t *) &
+                (int16_t)255);
+  uint8_t r1 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)1U, int16_t,
+                                                        int16_t *) &
+                                   (int16_t)63)
+                   << 2U |
+               (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)0U, int16_t,
+                                                        int16_t *) >>
+                                       8U &
+                                   (int16_t)3);
+  uint8_t r2 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)2U, int16_t,
+                                                        int16_t *) &
+                                   (int16_t)15)
+                   << 4U |
+               (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)1U, int16_t,
+                                                        int16_t *) >>
+                                       6U &
+                                   (int16_t)15);
+  uint8_t r3 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)3U, int16_t,
+                                                        int16_t *) &
+                                   (int16_t)3)
+                   << 6U |
+               (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)2U, int16_t,
+                                                        int16_t *) >>
+                                       4U &
+                                   (int16_t)63);
+  uint8_t r4 =
+      (uint8_t)(Eurydice_slice_index(v, (size_t)3U, int16_t, int16_t *) >> 2U &
+                (int16_t)255);
+  return (CLITERAL(uint8_t_x5){
+      .fst = r0, .snd = r1, .thd = r2, .f3 = r3, .f4 = r4});
+}
+
+static KRML_MUSTINLINE void
+libcrux_ml_kem_vector_portable_serialize_serialize_10(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v,
+    uint8_t ret[20U]) {
+  uint8_t_x5 r0_4 = libcrux_ml_kem_vector_portable_serialize_serialize_10_int(
+      Eurydice_array_to_subslice2(v.elements, (size_t)0U, (size_t)4U, int16_t));
+  uint8_t_x5 r5_9 = libcrux_ml_kem_vector_portable_serialize_serialize_10_int(
+      Eurydice_array_to_subslice2(v.elements, (size_t)4U, (size_t)8U, int16_t));
+  uint8_t_x5 r10_14 = libcrux_ml_kem_vector_portable_serialize_serialize_10_int(
+      Eurydice_array_to_subslice2(v.elements, (size_t)8U, (size_t)12U,
+                                  int16_t));
+  uint8_t_x5 r15_19 = libcrux_ml_kem_vector_portable_serialize_serialize_10_int(
+      Eurydice_array_to_subslice2(v.elements, (size_t)12U, (size_t)16U,
+                                  int16_t));
+  uint8_t result[20U] = {0U};
+  result[0U] = r0_4.fst;
+  result[1U] = r0_4.snd;
+  result[2U] = r0_4.thd;
+  result[3U] = r0_4.f3;
+  result[4U] = r0_4.f4;
+  result[5U] = r5_9.fst;
+  result[6U] = r5_9.snd;
+  result[7U] = r5_9.thd;
+  result[8U] = r5_9.f3;
+  result[9U] = r5_9.f4;
+  result[10U] = r10_14.fst;
+  result[11U] = r10_14.snd;
+  result[12U] = r10_14.thd;
+  result[13U] = r10_14.f3;
+  result[14U] = r10_14.f4;
+  result[15U] = r15_19.fst;
+  result[16U] = r15_19.snd;
+  result[17U] = r15_19.thd;
+  result[18U] = r15_19.f3;
+  result[19U] = r15_19.f4;
+  memcpy(ret, result, (size_t)20U * sizeof(uint8_t));
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline void libcrux_ml_kem_vector_portable_serialize_10_0d(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector a,
+    uint8_t ret[20U]) {
+  libcrux_ml_kem_vector_portable_serialize_serialize_10(a, ret);
+}
+
+static KRML_MUSTINLINE int16_t_x8
+libcrux_ml_kem_vector_portable_serialize_deserialize_10_int(
+    Eurydice_slice bytes) {
+  int16_t r0 =
+      ((int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *) &
+       (int16_t)3)
+          << 8U |
+      ((int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *) &
+       (int16_t)255);
+  int16_t r1 =
+      ((int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *) &
+       (int16_t)15)
+          << 6U |
+      (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *) >>
+          2U;
+  int16_t r2 =
+      ((int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *) &
+       (int16_t)63)
+          << 4U |
+      (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *) >>
+          4U;
+  int16_t r3 =
+      (int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *)
+          << 2U |
+      (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *) >>
+          6U;
+  int16_t r4 =
+      ((int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *) &
+       (int16_t)3)
+          << 8U |
+      ((int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *) &
+       (int16_t)255);
+  int16_t r5 =
+      ((int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *) &
+       (int16_t)15)
+          << 6U |
+      (int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *) >>
+          2U;
+  int16_t r6 =
+      ((int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *) &
+       (int16_t)63)
+          << 4U |
+      (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *) >>
+          4U;
+  int16_t r7 =
+      (int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *)
+          << 2U |
+      (int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *) >>
+          6U;
+  return (CLITERAL(int16_t_x8){.fst = r0,
+                               .snd = r1,
+                               .thd = r2,
+                               .f3 = r3,
+                               .f4 = r4,
+                               .f5 = r5,
+                               .f6 = r6,
+                               .f7 = r7});
+}
+
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_serialize_deserialize_10(Eurydice_slice bytes) {
+  int16_t_x8 v0_7 = libcrux_ml_kem_vector_portable_serialize_deserialize_10_int(
+      Eurydice_slice_subslice2(bytes, (size_t)0U, (size_t)10U, uint8_t));
+  int16_t_x8 v8_15 =
+      libcrux_ml_kem_vector_portable_serialize_deserialize_10_int(
+          Eurydice_slice_subslice2(bytes, (size_t)10U, (size_t)20U, uint8_t));
+  libcrux_ml_kem_vector_portable_vector_type_PortableVector v =
+      libcrux_ml_kem_vector_portable_vector_type_zero();
+  v.elements[0U] = v0_7.fst;
+  v.elements[1U] = v0_7.snd;
+  v.elements[2U] = v0_7.thd;
+  v.elements[3U] = v0_7.f3;
+  v.elements[4U] = v0_7.f4;
+  v.elements[5U] = v0_7.f5;
+  v.elements[6U] = v0_7.f6;
+  v.elements[7U] = v0_7.f7;
+  v.elements[8U] = v8_15.fst;
+  v.elements[9U] = v8_15.snd;
+  v.elements[10U] = v8_15.thd;
+  v.elements[11U] = v8_15.f3;
+  v.elements[12U] = v8_15.f4;
+  v.elements[13U] = v8_15.f5;
+  v.elements[14U] = v8_15.f6;
+  v.elements[15U] = v8_15.f7;
+  return v;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_deserialize_10_0d(Eurydice_slice a) {
+  return libcrux_ml_kem_vector_portable_serialize_deserialize_10(a);
+}
+
+typedef struct uint8_t_x3_s {
+  uint8_t fst;
+  uint8_t snd;
+  uint8_t thd;
+} uint8_t_x3;
+
+static KRML_MUSTINLINE uint8_t_x3
+libcrux_ml_kem_vector_portable_serialize_serialize_12_int(Eurydice_slice v) {
+  uint8_t r0 =
+      (uint8_t)(Eurydice_slice_index(v, (size_t)0U, int16_t, int16_t *) &
+                (int16_t)255);
+  uint8_t r1 =
+      (uint8_t)(Eurydice_slice_index(v, (size_t)0U, int16_t, int16_t *) >> 8U |
+                (Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *) &
+                 (int16_t)15)
+                    << 4U);
+  uint8_t r2 =
+      (uint8_t)(Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *) >> 4U &
+                (int16_t)255);
+  return (CLITERAL(uint8_t_x3){.fst = r0, .snd = r1, .thd = r2});
+}
+
+static KRML_MUSTINLINE void
+libcrux_ml_kem_vector_portable_serialize_serialize_12(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v,
+    uint8_t ret[24U]) {
+  uint8_t_x3 r0_2 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int(
+      Eurydice_array_to_subslice2(v.elements, (size_t)0U, (size_t)2U, int16_t));
+  uint8_t_x3 r3_5 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int(
+      Eurydice_array_to_subslice2(v.elements, (size_t)2U, (size_t)4U, int16_t));
+  uint8_t_x3 r6_8 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int(
+      Eurydice_array_to_subslice2(v.elements, (size_t)4U, (size_t)6U, int16_t));
+  uint8_t_x3 r9_11 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int(
+      Eurydice_array_to_subslice2(v.elements, (size_t)6U, (size_t)8U, int16_t));
+  uint8_t_x3 r12_14 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int(
+      Eurydice_array_to_subslice2(v.elements, (size_t)8U, (size_t)10U,
+                                  int16_t));
+  uint8_t_x3 r15_17 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int(
+      Eurydice_array_to_subslice2(v.elements, (size_t)10U, (size_t)12U,
+                                  int16_t));
+  uint8_t_x3 r18_20 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int(
+      Eurydice_array_to_subslice2(v.elements, (size_t)12U, (size_t)14U,
+                                  int16_t));
+  uint8_t_x3 r21_23 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int(
+      Eurydice_array_to_subslice2(v.elements, (size_t)14U, (size_t)16U,
+                                  int16_t));
+  uint8_t result[24U] = {0U};
+  result[0U] = r0_2.fst;
+  result[1U] = r0_2.snd;
+  result[2U] = r0_2.thd;
+  result[3U] = r3_5.fst;
+  result[4U] = r3_5.snd;
+  result[5U] = r3_5.thd;
+  result[6U] = r6_8.fst;
+  result[7U] = r6_8.snd;
+  result[8U] = r6_8.thd;
+  result[9U] = r9_11.fst;
+  result[10U] = r9_11.snd;
+  result[11U] = r9_11.thd;
+  result[12U] = r12_14.fst;
+  result[13U] = r12_14.snd;
+  result[14U] = r12_14.thd;
+  result[15U] = r15_17.fst;
+  result[16U] = r15_17.snd;
+  result[17U] = r15_17.thd;
+  result[18U] = r18_20.fst;
+  result[19U] = r18_20.snd;
+  result[20U] = r18_20.thd;
+  result[21U] = r21_23.fst;
+  result[22U] = r21_23.snd;
+  result[23U] = r21_23.thd;
+  memcpy(ret, result, (size_t)24U * sizeof(uint8_t));
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline void libcrux_ml_kem_vector_portable_serialize_12_0d(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector a,
+    uint8_t ret[24U]) {
+  libcrux_ml_kem_vector_portable_serialize_serialize_12(a, ret);
+}
+
+typedef struct int16_t_x2_s {
+  int16_t fst;
+  int16_t snd;
+} int16_t_x2;
+
+static KRML_MUSTINLINE int16_t_x2
+libcrux_ml_kem_vector_portable_serialize_deserialize_12_int(
+    Eurydice_slice bytes) {
+  int16_t byte0 =
+      (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *);
+  int16_t byte1 =
+      (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *);
+  int16_t byte2 =
+      (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *);
+  int16_t r0 = (byte1 & (int16_t)15) << 8U | (byte0 & (int16_t)255);
+  int16_t r1 = byte2 << 4U | (byte1 >> 4U & (int16_t)15);
+  return (CLITERAL(int16_t_x2){.fst = r0, .snd = r1});
+}
+
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_serialize_deserialize_12(Eurydice_slice bytes) {
+  int16_t_x2 v0_1 = libcrux_ml_kem_vector_portable_serialize_deserialize_12_int(
+      Eurydice_slice_subslice2(bytes, (size_t)0U, (size_t)3U, uint8_t));
+  int16_t_x2 v2_3 = libcrux_ml_kem_vector_portable_serialize_deserialize_12_int(
+      Eurydice_slice_subslice2(bytes, (size_t)3U, (size_t)6U, uint8_t));
+  int16_t_x2 v4_5 = libcrux_ml_kem_vector_portable_serialize_deserialize_12_int(
+      Eurydice_slice_subslice2(bytes, (size_t)6U, (size_t)9U, uint8_t));
+  int16_t_x2 v6_7 = libcrux_ml_kem_vector_portable_serialize_deserialize_12_int(
+      Eurydice_slice_subslice2(bytes, (size_t)9U, (size_t)12U, uint8_t));
+  int16_t_x2 v8_9 = libcrux_ml_kem_vector_portable_serialize_deserialize_12_int(
+      Eurydice_slice_subslice2(bytes, (size_t)12U, (size_t)15U, uint8_t));
+  int16_t_x2 v10_11 =
+      libcrux_ml_kem_vector_portable_serialize_deserialize_12_int(
+          Eurydice_slice_subslice2(bytes, (size_t)15U, (size_t)18U, uint8_t));
+  int16_t_x2 v12_13 =
+      libcrux_ml_kem_vector_portable_serialize_deserialize_12_int(
+          Eurydice_slice_subslice2(bytes, (size_t)18U, (size_t)21U, uint8_t));
+  int16_t_x2 v14_15 =
+      libcrux_ml_kem_vector_portable_serialize_deserialize_12_int(
+          Eurydice_slice_subslice2(bytes, (size_t)21U, (size_t)24U, uint8_t));
+  libcrux_ml_kem_vector_portable_vector_type_PortableVector re =
+      libcrux_ml_kem_vector_portable_vector_type_zero();
+  re.elements[0U] = v0_1.fst;
+  re.elements[1U] = v0_1.snd;
+  re.elements[2U] = v2_3.fst;
+  re.elements[3U] = v2_3.snd;
+  re.elements[4U] = v4_5.fst;
+  re.elements[5U] = v4_5.snd;
+  re.elements[6U] = v6_7.fst;
+  re.elements[7U] = v6_7.snd;
+  re.elements[8U] = v8_9.fst;
+  re.elements[9U] = v8_9.snd;
+  re.elements[10U] = v10_11.fst;
+  re.elements[11U] = v10_11.snd;
+  re.elements[12U] = v12_13.fst;
+  re.elements[13U] = v12_13.snd;
+  re.elements[14U] = v14_15.fst;
+  re.elements[15U] = v14_15.snd;
+  return re;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_deserialize_12_0d(Eurydice_slice a) {
+  return libcrux_ml_kem_vector_portable_serialize_deserialize_12(a);
+}
+
+static KRML_MUSTINLINE size_t
+libcrux_ml_kem_vector_portable_sampling_rej_sample(Eurydice_slice a,
+                                                   Eurydice_slice result) {
+  size_t sampled = (size_t)0U;
+  for (size_t i = (size_t)0U; i < Eurydice_slice_len(a, uint8_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 *);
+    int16_t b2 = (int16_t)Eurydice_slice_index(a, i0 * (size_t)3U + (size_t)1U,
+                                               uint8_t, uint8_t *);
+    int16_t b3 = (int16_t)Eurydice_slice_index(a, i0 * (size_t)3U + (size_t)2U,
+                                               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) {
+        Eurydice_slice_index(result, sampled, int16_t, int16_t *) = d1;
+        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 *) = 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 *) = uu____4;
+        sampled++;
+        continue;
+      }
+    }
+  }
+  return sampled;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline size_t libcrux_ml_kem_vector_portable_rej_sample_0d(
+    Eurydice_slice a, Eurydice_slice out) {
+  return libcrux_ml_kem_vector_portable_sampling_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_55
+    libcrux_ml_kem_mlkem768_MlKem768PrivateKey;
+
+typedef libcrux_ml_kem_types_MlKemPublicKey_15
+    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)
+
+/**
+A monomorphic instance of libcrux_ml_kem.polynomial.PolynomialRingElement
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+
+*/
+typedef struct libcrux_ml_kem_polynomial_PolynomialRingElement_f0_s {
+  libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficients[16U];
+} libcrux_ml_kem_polynomial_PolynomialRingElement_f0;
+
+/**
+This function found in impl
+{libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0]}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.polynomial.ZERO_89
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_polynomial_ZERO_89_ea(void) {
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 lit;
+  lit.coefficients[0U] = libcrux_ml_kem_vector_portable_ZERO_0d();
+  lit.coefficients[1U] = libcrux_ml_kem_vector_portable_ZERO_0d();
+  lit.coefficients[2U] = libcrux_ml_kem_vector_portable_ZERO_0d();
+  lit.coefficients[3U] = libcrux_ml_kem_vector_portable_ZERO_0d();
+  lit.coefficients[4U] = libcrux_ml_kem_vector_portable_ZERO_0d();
+  lit.coefficients[5U] = libcrux_ml_kem_vector_portable_ZERO_0d();
+  lit.coefficients[6U] = libcrux_ml_kem_vector_portable_ZERO_0d();
+  lit.coefficients[7U] = libcrux_ml_kem_vector_portable_ZERO_0d();
+  lit.coefficients[8U] = libcrux_ml_kem_vector_portable_ZERO_0d();
+  lit.coefficients[9U] = libcrux_ml_kem_vector_portable_ZERO_0d();
+  lit.coefficients[10U] = libcrux_ml_kem_vector_portable_ZERO_0d();
+  lit.coefficients[11U] = libcrux_ml_kem_vector_portable_ZERO_0d();
+  lit.coefficients[12U] = libcrux_ml_kem_vector_portable_ZERO_0d();
+  lit.coefficients[13U] = libcrux_ml_kem_vector_portable_ZERO_0d();
+  lit.coefficients[14U] = libcrux_ml_kem_vector_portable_ZERO_0d();
+  lit.coefficients[15U] = libcrux_ml_kem_vector_portable_ZERO_0d();
+  return lit;
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.ind_cpa.deserialize_secret_key.closure
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+- K= 3
+*/
+static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_ind_cpa_deserialize_secret_key_closure_6b(size_t _) {
+  return libcrux_ml_kem_polynomial_ZERO_89_ea();
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.serialize.deserialize_to_uncompressed_ring_element with types
+libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics
+
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_serialize_deserialize_to_uncompressed_ring_element_af(
+    Eurydice_slice serialized) {
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re =
+      libcrux_ml_kem_polynomial_ZERO_89_ea();
+  for (size_t i = (size_t)0U;
+       i < Eurydice_slice_len(serialized, uint8_t) / (size_t)24U; i++) {
+    size_t i0 = i;
+    Eurydice_slice bytes = Eurydice_slice_subslice2(
+        serialized, i0 * (size_t)24U, i0 * (size_t)24U + (size_t)24U, uint8_t);
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 =
+        libcrux_ml_kem_vector_portable_deserialize_12_0d(bytes);
+    re.coefficients[i0] = uu____0;
+  }
+  return re;
+}
+
+/**
+ Call [`deserialize_to_uncompressed_ring_element`] for each ring element.
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.ind_cpa.deserialize_secret_key
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+- K= 3
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_deserialize_secret_key_24(
+    Eurydice_slice secret_key,
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U]) {
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 secret_as_ntt[3U];
+  for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+    secret_as_ntt[i] = libcrux_ml_kem_polynomial_ZERO_89_ea();
+  }
+  for (size_t i = (size_t)0U;
+       i < Eurydice_slice_len(secret_key, uint8_t) /
+               LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT;
+       i++) {
+    size_t i0 = i;
+    Eurydice_slice secret_bytes = Eurydice_slice_subslice2(
+        secret_key, i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT,
+        i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT +
+            LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT,
+        uint8_t);
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 uu____0 =
+        libcrux_ml_kem_serialize_deserialize_to_uncompressed_ring_element_af(
+            secret_bytes);
+    secret_as_ntt[i0] = uu____0;
+  }
+  memcpy(
+      ret, secret_as_ntt,
+      (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.ind_cpa.unpacked.IndCpaPrivateKeyUnpacked with types
+libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics
+- $3size_t
+*/
+typedef struct libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_f8_s {
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 secret_as_ntt[3U];
+} libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_f8;
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.ind_cpa.deserialize_then_decompress_u.closure with types
+libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics
+- K= 3
+- CIPHERTEXT_SIZE= 1088
+- U_COMPRESSION_FACTOR= 10
+*/
+static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_ind_cpa_deserialize_then_decompress_u_closure_7c(size_t _) {
+  return libcrux_ml_kem_polynomial_ZERO_89_ea();
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.vector.portable.compress.decompress_ciphertext_coefficient with
+const generics
+- COEFFICIENT_BITS= 10
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_6b(
+    libcrux_ml_kem_vector_portable_vector_type_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;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+/**
+A monomorphic instance of
+libcrux_ml_kem.vector.portable.decompress_ciphertext_coefficient_0d with const
+generics
+- COEFFICIENT_BITS= 10
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_5a(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v) {
+  return libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_6b(
+      v);
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.serialize.deserialize_then_decompress_10 with types
+libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics
+
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_serialize_deserialize_then_decompress_10_2c(
+    Eurydice_slice serialized) {
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re =
+      libcrux_ml_kem_polynomial_ZERO_89_ea();
+  for (size_t i = (size_t)0U;
+       i < Eurydice_slice_len(serialized, uint8_t) / (size_t)20U; i++) {
+    size_t i0 = i;
+    Eurydice_slice bytes = Eurydice_slice_subslice2(
+        serialized, i0 * (size_t)20U, i0 * (size_t)20U + (size_t)20U, uint8_t);
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient =
+        libcrux_ml_kem_vector_portable_deserialize_10_0d(bytes);
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 =
+        libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_5a(
+            coefficient);
+    re.coefficients[i0] = uu____0;
+  }
+  return re;
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.vector.portable.compress.decompress_ciphertext_coefficient with
+const generics
+- COEFFICIENT_BITS= 11
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_6b0(
+    libcrux_ml_kem_vector_portable_vector_type_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;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+/**
+A monomorphic instance of
+libcrux_ml_kem.vector.portable.decompress_ciphertext_coefficient_0d with const
+generics
+- COEFFICIENT_BITS= 11
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_5a0(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v) {
+  return libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_6b0(
+      v);
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.serialize.deserialize_then_decompress_11 with types
+libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics
+
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_serialize_deserialize_then_decompress_11_8d(
+    Eurydice_slice serialized) {
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re =
+      libcrux_ml_kem_polynomial_ZERO_89_ea();
+  for (size_t i = (size_t)0U;
+       i < Eurydice_slice_len(serialized, uint8_t) / (size_t)22U; i++) {
+    size_t i0 = i;
+    Eurydice_slice bytes = Eurydice_slice_subslice2(
+        serialized, i0 * (size_t)22U, i0 * (size_t)22U + (size_t)22U, uint8_t);
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient =
+        libcrux_ml_kem_vector_portable_deserialize_11_0d(bytes);
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 =
+        libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_5a0(
+            coefficient);
+    re.coefficients[i0] = uu____0;
+  }
+  return re;
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.serialize.deserialize_then_decompress_ring_element_u with types
+libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics
+- COMPRESSION_FACTOR= 10
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_u_34(
+    Eurydice_slice serialized) {
+  return libcrux_ml_kem_serialize_deserialize_then_decompress_10_2c(serialized);
+}
+
+typedef struct libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2_s {
+  libcrux_ml_kem_vector_portable_vector_type_PortableVector fst;
+  libcrux_ml_kem_vector_portable_vector_type_PortableVector snd;
+} libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2;
+
+/**
+A monomorphic instance of libcrux_ml_kem.vector.traits.montgomery_multiply_fe
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_traits_montgomery_multiply_fe_67(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t fer) {
+  return libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_0d(v,
+                                                                           fer);
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.ntt.ntt_layer_int_vec_step
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static KRML_MUSTINLINE
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2
+    libcrux_ml_kem_ntt_ntt_layer_int_vec_step_0c(
+        libcrux_ml_kem_vector_portable_vector_type_PortableVector a,
+        libcrux_ml_kem_vector_portable_vector_type_PortableVector b,
+        int16_t zeta_r) {
+  libcrux_ml_kem_vector_portable_vector_type_PortableVector t =
+      libcrux_ml_kem_vector_traits_montgomery_multiply_fe_67(b, zeta_r);
+  b = libcrux_ml_kem_vector_portable_sub_0d(a, &t);
+  a = libcrux_ml_kem_vector_portable_add_0d(a, &t);
+  return (
+      CLITERAL(libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2){
+          .fst = a, .snd = b});
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.ntt.ntt_at_layer_4_plus
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_ntt_ntt_at_layer_4_plus_51(
+    size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *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;
+      libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2 uu____0 =
+          libcrux_ml_kem_ntt_ntt_layer_int_vec_step_0c(
+              re->coefficients[j], re->coefficients[j + step_vec],
+              libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]);
+      libcrux_ml_kem_vector_portable_vector_type_PortableVector x = uu____0.fst;
+      libcrux_ml_kem_vector_portable_vector_type_PortableVector y = uu____0.snd;
+      re->coefficients[j] = x;
+      re->coefficients[j + step_vec] = y;
+    }
+  }
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.ntt.ntt_at_layer_3
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_ntt_ntt_at_layer_3_fd(
+    size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re,
+    size_t _layer, size_t _initial_coefficient_bound) {
+  for (size_t i = (size_t)0U; i < (size_t)16U; i++) {
+    size_t round = i;
+    zeta_i[0U] = zeta_i[0U] + (size_t)1U;
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 =
+        libcrux_ml_kem_vector_portable_ntt_layer_3_step_0d(
+            re->coefficients[round],
+            libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]);
+    re->coefficients[round] = uu____0;
+  }
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.ntt.ntt_at_layer_2
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_ntt_ntt_at_layer_2_ad(
+    size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re,
+    size_t _layer, size_t _initial_coefficient_bound) {
+  for (size_t i = (size_t)0U; i < (size_t)16U; i++) {
+    size_t round = i;
+    zeta_i[0U] = zeta_i[0U] + (size_t)1U;
+    re->coefficients[round] =
+        libcrux_ml_kem_vector_portable_ntt_layer_2_step_0d(
+            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]);
+    zeta_i[0U] = zeta_i[0U] + (size_t)1U;
+  }
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.ntt.ntt_at_layer_1
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_ntt_ntt_at_layer_1_a2(
+    size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re,
+    size_t _layer, size_t _initial_coefficient_bound) {
+  for (size_t i = (size_t)0U; i < (size_t)16U; i++) {
+    size_t round = i;
+    zeta_i[0U] = zeta_i[0U] + (size_t)1U;
+    re->coefficients[round] =
+        libcrux_ml_kem_vector_portable_ntt_layer_1_step_0d(
+            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]);
+    zeta_i[0U] = zeta_i[0U] + (size_t)3U;
+  }
+}
+
+/**
+This function found in impl
+{libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0]}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.polynomial.poly_barrett_reduce_89
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_polynomial_poly_barrett_reduce_89_8b(
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *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_vector_type_PortableVector uu____0 =
+        libcrux_ml_kem_vector_portable_barrett_reduce_0d(
+            self->coefficients[i0]);
+    self->coefficients[i0] = uu____0;
+  }
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.ntt.ntt_vector_u
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+- VECTOR_U_COMPRESSION_FACTOR= 10
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_ntt_ntt_vector_u_9f(
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re) {
+  size_t zeta_i = (size_t)0U;
+  libcrux_ml_kem_ntt_ntt_at_layer_4_plus_51(&zeta_i, re, (size_t)7U,
+                                            (size_t)3328U);
+  libcrux_ml_kem_ntt_ntt_at_layer_4_plus_51(&zeta_i, re, (size_t)6U,
+                                            (size_t)3328U);
+  libcrux_ml_kem_ntt_ntt_at_layer_4_plus_51(&zeta_i, re, (size_t)5U,
+                                            (size_t)3328U);
+  libcrux_ml_kem_ntt_ntt_at_layer_4_plus_51(&zeta_i, re, (size_t)4U,
+                                            (size_t)3328U);
+  libcrux_ml_kem_ntt_ntt_at_layer_3_fd(&zeta_i, re, (size_t)3U, (size_t)3328U);
+  libcrux_ml_kem_ntt_ntt_at_layer_2_ad(&zeta_i, re, (size_t)2U, (size_t)3328U);
+  libcrux_ml_kem_ntt_ntt_at_layer_1_a2(&zeta_i, re, (size_t)1U, (size_t)3328U);
+  libcrux_ml_kem_polynomial_poly_barrett_reduce_89_8b(re);
+}
+
+/**
+ Call [`deserialize_then_decompress_ring_element_u`] on each ring element
+ in the `ciphertext`.
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.ind_cpa.deserialize_then_decompress_u
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+- K= 3
+- CIPHERTEXT_SIZE= 1088
+- U_COMPRESSION_FACTOR= 10
+*/
+static KRML_MUSTINLINE void
+libcrux_ml_kem_ind_cpa_deserialize_then_decompress_u_f4(
+    uint8_t *ciphertext,
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U]) {
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 u_as_ntt[3U];
+  for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+    u_as_ntt[i] = libcrux_ml_kem_polynomial_ZERO_89_ea();
+  }
+  for (size_t i = (size_t)0U;
+       i < Eurydice_slice_len(
+               Eurydice_array_to_slice((size_t)1088U, ciphertext, uint8_t),
+               uint8_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_subslice2(
+        ciphertext,
+        i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT *
+              (size_t)10U / (size_t)8U),
+        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);
+    u_as_ntt[i0] =
+        libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_u_34(
+            u_bytes);
+    libcrux_ml_kem_ntt_ntt_vector_u_9f(&u_as_ntt[i0]);
+  }
+  memcpy(
+      ret, u_as_ntt,
+      (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.vector.portable.compress.decompress_ciphertext_coefficient with
+const generics
+- COEFFICIENT_BITS= 4
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_6b1(
+    libcrux_ml_kem_vector_portable_vector_type_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;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+/**
+A monomorphic instance of
+libcrux_ml_kem.vector.portable.decompress_ciphertext_coefficient_0d with const
+generics
+- COEFFICIENT_BITS= 4
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_5a1(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v) {
+  return libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_6b1(
+      v);
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.serialize.deserialize_then_decompress_4
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_serialize_deserialize_then_decompress_4_41(
+    Eurydice_slice serialized) {
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re =
+      libcrux_ml_kem_polynomial_ZERO_89_ea();
+  for (size_t i = (size_t)0U;
+       i < Eurydice_slice_len(serialized, uint8_t) / (size_t)8U; i++) {
+    size_t i0 = i;
+    Eurydice_slice bytes = Eurydice_slice_subslice2(
+        serialized, i0 * (size_t)8U, i0 * (size_t)8U + (size_t)8U, uint8_t);
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient =
+        libcrux_ml_kem_vector_portable_deserialize_4_0d(bytes);
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 =
+        libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_5a1(
+            coefficient);
+    re.coefficients[i0] = uu____0;
+  }
+  return re;
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.vector.portable.compress.decompress_ciphertext_coefficient with
+const generics
+- COEFFICIENT_BITS= 5
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_6b2(
+    libcrux_ml_kem_vector_portable_vector_type_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;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+/**
+A monomorphic instance of
+libcrux_ml_kem.vector.portable.decompress_ciphertext_coefficient_0d with const
+generics
+- COEFFICIENT_BITS= 5
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_5a2(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v) {
+  return libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_6b2(
+      v);
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.serialize.deserialize_then_decompress_5
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_serialize_deserialize_then_decompress_5_4e(
+    Eurydice_slice serialized) {
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re =
+      libcrux_ml_kem_polynomial_ZERO_89_ea();
+  for (size_t i = (size_t)0U;
+       i < Eurydice_slice_len(serialized, uint8_t) / (size_t)10U; i++) {
+    size_t i0 = i;
+    Eurydice_slice bytes = Eurydice_slice_subslice2(
+        serialized, i0 * (size_t)10U, i0 * (size_t)10U + (size_t)10U, uint8_t);
+    re.coefficients[i0] =
+        libcrux_ml_kem_vector_portable_deserialize_5_0d(bytes);
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____1 =
+        libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_5a2(
+            re.coefficients[i0]);
+    re.coefficients[i0] = uu____1;
+  }
+  return re;
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.serialize.deserialize_then_decompress_ring_element_v with types
+libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics
+- COMPRESSION_FACTOR= 4
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v_56(
+    Eurydice_slice serialized) {
+  return libcrux_ml_kem_serialize_deserialize_then_decompress_4_41(serialized);
+}
+
+/**
+ Given two `KyberPolynomialRingElement`s in their NTT representations,
+ compute their product. Given two polynomials in the NTT domain `f^` and `ĵ`,
+ the `iᵗʰ` coefficient of the product `k̂` is determined by the calculation:
+
+ ```plaintext
+ ĥ[2·i] + ĥ[2·i + 1]X = (f^[2·i] + f^[2·i + 1]X)·(ĝ[2·i] + ĝ[2·i + 1]X) mod (X²
+ - ζ^(2·BitRev₇(i) + 1))
+ ```
+
+ This function almost implements <strong>Algorithm 10</strong> of the
+ NIST FIPS 203 standard, which is reproduced below:
+
+ ```plaintext
+ Input: Two arrays fˆ ∈ ℤ₂₅₆ and ĝ ∈ ℤ₂₅₆.
+ Output: An array ĥ ∈ ℤq.
+
+ for(i ← 0; i < 128; i++)
+     (ĥ[2i], ĥ[2i+1]) ← BaseCaseMultiply(fˆ[2i], fˆ[2i+1], ĝ[2i], ĝ[2i+1],
+ ζ^(2·BitRev₇(i) + 1)) end for return ĥ
+ ```
+ We say "almost" because the coefficients of the ring element output by
+ this function are in the Montgomery domain.
+
+ The NIST FIPS 203 standard can be found at
+ <https://csrc.nist.gov/pubs/fips/203/ipd>.
+*/
+/**
+This function found in impl
+{libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0]}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.polynomial.ntt_multiply_89
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_polynomial_ntt_multiply_89_2a(
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *self,
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *rhs) {
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 out =
+      libcrux_ml_kem_polynomial_ZERO_89_ea();
+  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_vector_type_PortableVector uu____0 =
+        libcrux_ml_kem_vector_portable_ntt_multiply_0d(
+            &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;
+}
+
+/**
+ Given two polynomial ring elements `lhs` and `rhs`, compute the pointwise
+ sum of their constituent coefficients.
+*/
+/**
+This function found in impl
+{libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0]}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.polynomial.add_to_ring_element_89
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+- K= 3
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_polynomial_add_to_ring_element_89_84(
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *self,
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *rhs) {
+  for (size_t i = (size_t)0U;
+       i < Eurydice_slice_len(
+               Eurydice_array_to_slice(
+                   (size_t)16U, self->coefficients,
+                   libcrux_ml_kem_vector_portable_vector_type_PortableVector),
+               libcrux_ml_kem_vector_portable_vector_type_PortableVector);
+       i++) {
+    size_t i0 = i;
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 =
+        libcrux_ml_kem_vector_portable_add_0d(self->coefficients[i0],
+                                              &rhs->coefficients[i0]);
+    self->coefficients[i0] = uu____0;
+  }
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.invert_ntt.invert_ntt_at_layer_1
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_1_83(
+    size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re,
+    size_t _layer) {
+  for (size_t i = (size_t)0U; i < (size_t)16U; i++) {
+    size_t round = i;
+    zeta_i[0U] = zeta_i[0U] - (size_t)1U;
+    re->coefficients[round] =
+        libcrux_ml_kem_vector_portable_inv_ntt_layer_1_step_0d(
+            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]);
+    zeta_i[0U] = zeta_i[0U] - (size_t)3U;
+  }
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.invert_ntt.invert_ntt_at_layer_2
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_2_c3(
+    size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re,
+    size_t _layer) {
+  for (size_t i = (size_t)0U; i < (size_t)16U; i++) {
+    size_t round = i;
+    zeta_i[0U] = zeta_i[0U] - (size_t)1U;
+    re->coefficients[round] =
+        libcrux_ml_kem_vector_portable_inv_ntt_layer_2_step_0d(
+            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]);
+    zeta_i[0U] = zeta_i[0U] - (size_t)1U;
+  }
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.invert_ntt.invert_ntt_at_layer_3
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_3_68(
+    size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re,
+    size_t _layer) {
+  for (size_t i = (size_t)0U; i < (size_t)16U; i++) {
+    size_t round = i;
+    zeta_i[0U] = zeta_i[0U] - (size_t)1U;
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 =
+        libcrux_ml_kem_vector_portable_inv_ntt_layer_3_step_0d(
+            re->coefficients[round],
+            libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]);
+    re->coefficients[round] = uu____0;
+  }
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.invert_ntt.inv_ntt_layer_int_vec_step_reduce with types
+libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics
+
+*/
+static KRML_MUSTINLINE
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2
+    libcrux_ml_kem_invert_ntt_inv_ntt_layer_int_vec_step_reduce_65(
+        libcrux_ml_kem_vector_portable_vector_type_PortableVector a,
+        libcrux_ml_kem_vector_portable_vector_type_PortableVector b,
+        int16_t zeta_r) {
+  libcrux_ml_kem_vector_portable_vector_type_PortableVector a_minus_b =
+      libcrux_ml_kem_vector_portable_sub_0d(b, &a);
+  a = libcrux_ml_kem_vector_portable_barrett_reduce_0d(
+      libcrux_ml_kem_vector_portable_add_0d(a, &b));
+  b = libcrux_ml_kem_vector_traits_montgomery_multiply_fe_67(a_minus_b, zeta_r);
+  return (
+      CLITERAL(libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2){
+          .fst = a, .snd = b});
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.invert_ntt.invert_ntt_at_layer_4_plus
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static KRML_MUSTINLINE void
+libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus_6e(
+    size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *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;
+      libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2 uu____0 =
+          libcrux_ml_kem_invert_ntt_inv_ntt_layer_int_vec_step_reduce_65(
+              re->coefficients[j], re->coefficients[j + step_vec],
+              libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]);
+      libcrux_ml_kem_vector_portable_vector_type_PortableVector x = uu____0.fst;
+      libcrux_ml_kem_vector_portable_vector_type_PortableVector y = uu____0.snd;
+      re->coefficients[j] = x;
+      re->coefficients[j + step_vec] = y;
+    }
+  }
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.invert_ntt.invert_ntt_montgomery
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+- K= 3
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_invert_ntt_invert_ntt_montgomery_f6(
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *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_83(&zeta_i, re, (size_t)1U);
+  libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_2_c3(&zeta_i, re, (size_t)2U);
+  libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_3_68(&zeta_i, re, (size_t)3U);
+  libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus_6e(&zeta_i, re,
+                                                          (size_t)4U);
+  libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus_6e(&zeta_i, re,
+                                                          (size_t)5U);
+  libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus_6e(&zeta_i, re,
+                                                          (size_t)6U);
+  libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus_6e(&zeta_i, re,
+                                                          (size_t)7U);
+  libcrux_ml_kem_polynomial_poly_barrett_reduce_89_8b(re);
+}
+
+/**
+This function found in impl
+{libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0]}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.polynomial.subtract_reduce_89
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_polynomial_subtract_reduce_89_d4(
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *self,
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 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_vector_type_PortableVector
+        coefficient_normal_form =
+            libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_0d(
+                b.coefficients[i0], (int16_t)1441);
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 =
+        libcrux_ml_kem_vector_portable_barrett_reduce_0d(
+            libcrux_ml_kem_vector_portable_sub_0d(self->coefficients[i0],
+                                                  &coefficient_normal_form));
+    b.coefficients[i0] = uu____0;
+  }
+  return b;
+}
+
+/**
+ The following functions compute various expressions involving
+ vectors and matrices. The computation of these expressions has been
+ abstracted away into these functions in order to save on loop iterations.
+ Compute v − InverseNTT(sᵀ ◦ NTT(u))
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.matrix.compute_message
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+- K= 3
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_matrix_compute_message_b3(
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *v,
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *secret_as_ntt,
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *u_as_ntt) {
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 result =
+      libcrux_ml_kem_polynomial_ZERO_89_ea();
+  for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+    size_t i0 = i;
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 product =
+        libcrux_ml_kem_polynomial_ntt_multiply_89_2a(&secret_as_ntt[i0],
+                                                     &u_as_ntt[i0]);
+    libcrux_ml_kem_polynomial_add_to_ring_element_89_84(&result, &product);
+  }
+  libcrux_ml_kem_invert_ntt_invert_ntt_montgomery_f6(&result);
+  result = libcrux_ml_kem_polynomial_subtract_reduce_89_d4(v, result);
+  return result;
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.vector.portable.arithmetic.shift_right
+with const generics
+- SHIFT_BY= 15
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_arithmetic_shift_right_94(
+    libcrux_ml_kem_vector_portable_vector_type_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;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.vector.portable.shift_right_0d
+with const generics
+- SHIFT_BY= 15
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_shift_right_0d_19(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v) {
+  return libcrux_ml_kem_vector_portable_arithmetic_shift_right_94(v);
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.vector.traits.to_unsigned_representative with types
+libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics
+
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_traits_to_unsigned_representative_db(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector a) {
+  libcrux_ml_kem_vector_portable_vector_type_PortableVector t =
+      libcrux_ml_kem_vector_portable_shift_right_0d_19(a);
+  libcrux_ml_kem_vector_portable_vector_type_PortableVector fm =
+      libcrux_ml_kem_vector_portable_bitwise_and_with_constant_0d(
+          t, LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS);
+  return libcrux_ml_kem_vector_portable_add_0d(a, &fm);
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.serialize.compress_then_serialize_message with types
+libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics
+
+*/
+static KRML_MUSTINLINE void
+libcrux_ml_kem_serialize_compress_then_serialize_message_aa(
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re, uint8_t ret[32U]) {
+  uint8_t serialized[32U] = {0U};
+  for (size_t i = (size_t)0U; i < (size_t)16U; i++) {
+    size_t i0 = i;
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient =
+        libcrux_ml_kem_vector_traits_to_unsigned_representative_db(
+            re.coefficients[i0]);
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector
+        coefficient_compressed =
+            libcrux_ml_kem_vector_portable_compress_1_0d(coefficient);
+    uint8_t bytes[2U];
+    libcrux_ml_kem_vector_portable_serialize_1_0d(coefficient_compressed,
+                                                  bytes);
+    Eurydice_slice uu____0 = Eurydice_array_to_subslice2(
+        serialized, (size_t)2U * i0, (size_t)2U * i0 + (size_t)2U, uint8_t);
+    Eurydice_slice_copy(
+        uu____0, Eurydice_array_to_slice((size_t)2U, bytes, uint8_t), uint8_t);
+  }
+  memcpy(ret, serialized, (size_t)32U * sizeof(uint8_t));
+}
+
+/**
+ This function implements <strong>Algorithm 14</strong> of the
+ NIST FIPS 203 specification; this is the Kyber CPA-PKE decryption algorithm.
+
+ Algorithm 14 is reproduced below:
+
+ ```plaintext
+ Input: decryption key dkₚₖₑ ∈ 𝔹^{384k}.
+ Input: ciphertext c ∈ 𝔹^{32(dᵤk + dᵥ)}.
+ Output: message m ∈ 𝔹^{32}.
+
+ c₁ ← c[0 : 32dᵤk]
+ c₂ ← c[32dᵤk : 32(dᵤk + dᵥ)]
+ u ← Decompress_{dᵤ}(ByteDecode_{dᵤ}(c₁))
+ v ← Decompress_{dᵥ}(ByteDecode_{dᵥ}(c₂))
+ ŝ ← ByteDecode₁₂(dkₚₖₑ)
+ w ← v - NTT-¹(ŝᵀ ◦ NTT(u))
+ m ← ByteEncode₁(Compress₁(w))
+ return m
+ ```
+
+ The NIST FIPS 203 standard can be found at
+ <https://csrc.nist.gov/pubs/fips/203/ipd>.
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.ind_cpa.decrypt_unpacked
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+- K= 3
+- CIPHERTEXT_SIZE= 1088
+- VECTOR_U_ENCODED_SIZE= 960
+- U_COMPRESSION_FACTOR= 10
+- V_COMPRESSION_FACTOR= 4
+*/
+static inline void libcrux_ml_kem_ind_cpa_decrypt_unpacked_6d(
+    libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_f8 *secret_key,
+    uint8_t *ciphertext, uint8_t ret[32U]) {
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 u_as_ntt[3U];
+  libcrux_ml_kem_ind_cpa_deserialize_then_decompress_u_f4(ciphertext, u_as_ntt);
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 v =
+      libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v_56(
+          Eurydice_array_to_subslice_from((size_t)1088U, ciphertext,
+                                          (size_t)960U, uint8_t, size_t));
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 message =
+      libcrux_ml_kem_matrix_compute_message_b3(&v, secret_key->secret_as_ntt,
+                                               u_as_ntt);
+  uint8_t ret0[32U];
+  libcrux_ml_kem_serialize_compress_then_serialize_message_aa(message, ret0);
+  memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t));
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.ind_cpa.decrypt
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+- K= 3
+- CIPHERTEXT_SIZE= 1088
+- VECTOR_U_ENCODED_SIZE= 960
+- U_COMPRESSION_FACTOR= 10
+- V_COMPRESSION_FACTOR= 4
+*/
+static inline void libcrux_ml_kem_ind_cpa_decrypt_43(Eurydice_slice secret_key,
+                                                     uint8_t *ciphertext,
+                                                     uint8_t ret[32U]) {
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 secret_as_ntt[3U];
+  libcrux_ml_kem_ind_cpa_deserialize_secret_key_24(secret_key, secret_as_ntt);
+  /* Passing arrays by value in Rust generates a copy in C */
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 copy_of_secret_as_ntt[3U];
+  memcpy(
+      copy_of_secret_as_ntt, secret_as_ntt,
+      (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+  libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_f8
+      secret_key_unpacked;
+  memcpy(
+      secret_key_unpacked.secret_as_ntt, copy_of_secret_as_ntt,
+      (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+  uint8_t ret0[32U];
+  libcrux_ml_kem_ind_cpa_decrypt_unpacked_6d(&secret_key_unpacked, ciphertext,
+                                             ret0);
+  memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t));
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::hash_functions::Hash<K> for
+libcrux_ml_kem::hash_functions::portable::PortableHash<K>)}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.hash_functions.portable.G_f1
+with const generics
+- K= 3
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_G_f1_e4(
+    Eurydice_slice input, uint8_t ret[64U]) {
+  libcrux_ml_kem_hash_functions_portable_G(input, ret);
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRF
+with const generics
+- LEN= 32
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_PRF_2b(
+    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), input);
+  memcpy(ret, digest, (size_t)32U * sizeof(uint8_t));
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::hash_functions::Hash<K> for
+libcrux_ml_kem::hash_functions::portable::PortableHash<K>)}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRF_f1
+with const generics
+- K= 3
+- LEN= 32
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_PRF_f1_ee(
+    Eurydice_slice input, uint8_t ret[32U]) {
+  libcrux_ml_kem_hash_functions_portable_PRF_2b(input, ret);
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.serialize.deserialize_ring_elements_reduced.closure with types
+libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics
+- PUBLIC_KEY_SIZE= 1152
+- K= 3
+*/
+static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_closure_cd(
+    size_t _i) {
+  return libcrux_ml_kem_polynomial_ZERO_89_ea();
+}
+
+/**
+ Only use with public values.
+
+ This MUST NOT be used with secret inputs, like its caller
+ `deserialize_ring_elements_reduced`.
+*/
+/**
+A monomorphic instance of
+libcrux_ml_kem.serialize.deserialize_to_reduced_ring_element with types
+libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics
+
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element_4c(
+    Eurydice_slice serialized) {
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re =
+      libcrux_ml_kem_polynomial_ZERO_89_ea();
+  for (size_t i = (size_t)0U;
+       i < Eurydice_slice_len(serialized, uint8_t) / (size_t)24U; i++) {
+    size_t i0 = i;
+    Eurydice_slice bytes = Eurydice_slice_subslice2(
+        serialized, i0 * (size_t)24U, i0 * (size_t)24U + (size_t)24U, uint8_t);
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient =
+        libcrux_ml_kem_vector_portable_deserialize_12_0d(bytes);
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 =
+        libcrux_ml_kem_vector_portable_cond_subtract_3329_0d(coefficient);
+    re.coefficients[i0] = uu____0;
+  }
+  return re;
+}
+
+/**
+ This function deserializes ring elements and reduces the result by the field
+ modulus.
+
+ This function MUST NOT be used on secret inputs.
+*/
+/**
+A monomorphic instance of
+libcrux_ml_kem.serialize.deserialize_ring_elements_reduced with types
+libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics
+- PUBLIC_KEY_SIZE= 1152
+- K= 3
+*/
+static KRML_MUSTINLINE void
+libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_33(
+    Eurydice_slice public_key,
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U]) {
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 deserialized_pk[3U];
+  for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+    deserialized_pk[i] = libcrux_ml_kem_polynomial_ZERO_89_ea();
+  }
+  for (size_t i = (size_t)0U;
+       i < Eurydice_slice_len(public_key, uint8_t) /
+               LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT;
+       i++) {
+    size_t i0 = i;
+    Eurydice_slice ring_element = Eurydice_slice_subslice2(
+        public_key, i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT,
+        i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT +
+            LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT,
+        uint8_t);
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 uu____0 =
+        libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element_4c(
+            ring_element);
+    deserialized_pk[i0] = uu____0;
+  }
+  memcpy(
+      ret, deserialized_pk,
+      (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.matrix.sample_matrix_A.closure.closure
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector,
+libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const
+generics
+- K= 3
+*/
+static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_matrix_sample_matrix_A_closure_closure_78(size_t _j) {
+  return libcrux_ml_kem_polynomial_ZERO_89_ea();
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.matrix.sample_matrix_A.closure
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector,
+libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const
+generics
+- K= 3
+*/
+static inline void libcrux_ml_kem_matrix_sample_matrix_A_closure_4b(
+    size_t _i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U]) {
+  for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+    ret[i] = libcrux_ml_kem_polynomial_ZERO_89_ea();
+  }
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PortableHash
+with const generics
+- $3size_t
+*/
+typedef struct libcrux_ml_kem_hash_functions_portable_PortableHash_58_s {
+  libcrux_sha3_generic_keccak_KeccakState_48 shake128_state[3U];
+} libcrux_ml_kem_hash_functions_portable_PortableHash_58;
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.hash_functions.portable.shake128_init_absorb with const generics
+- K= 3
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_hash_functions_portable_PortableHash_58
+libcrux_ml_kem_hash_functions_portable_shake128_init_absorb_b7(
+    uint8_t input[3U][34U]) {
+  libcrux_sha3_generic_keccak_KeccakState_48 shake128_state[3U];
+  for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+    shake128_state[i] = libcrux_sha3_portable_incremental_shake128_init();
+  }
+  for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+    size_t i0 = i;
+    libcrux_sha3_portable_incremental_shake128_absorb_final(
+        &shake128_state[i0],
+        Eurydice_array_to_slice((size_t)34U, input[i0], uint8_t));
+  }
+  /* Passing arrays by value in Rust generates a copy in C */
+  libcrux_sha3_generic_keccak_KeccakState_48 copy_of_shake128_state[3U];
+  memcpy(copy_of_shake128_state, shake128_state,
+         (size_t)3U * sizeof(libcrux_sha3_generic_keccak_KeccakState_48));
+  libcrux_ml_kem_hash_functions_portable_PortableHash_58 lit;
+  memcpy(lit.shake128_state, copy_of_shake128_state,
+         (size_t)3U * sizeof(libcrux_sha3_generic_keccak_KeccakState_48));
+  return lit;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::hash_functions::Hash<K> for
+libcrux_ml_kem::hash_functions::portable::PortableHash<K>)}
+*/
+/**
+A monomorphic instance of
+libcrux_ml_kem.hash_functions.portable.shake128_init_absorb_f1 with const
+generics
+- K= 3
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_hash_functions_portable_PortableHash_58
+libcrux_ml_kem_hash_functions_portable_shake128_init_absorb_f1_8c(
+    uint8_t input[3U][34U]) {
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_input[3U][34U];
+  memcpy(copy_of_input, input, (size_t)3U * sizeof(uint8_t[34U]));
+  return libcrux_ml_kem_hash_functions_portable_shake128_init_absorb_b7(
+      copy_of_input);
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.hash_functions.portable.shake128_squeeze_three_blocks with const
+generics
+- K= 3
+*/
+static KRML_MUSTINLINE void
+libcrux_ml_kem_hash_functions_portable_shake128_squeeze_three_blocks_ca(
+    libcrux_ml_kem_hash_functions_portable_PortableHash_58 *st,
+    uint8_t ret[3U][504U]) {
+  uint8_t out[3U][504U] = {{0U}};
+  for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+    size_t i0 = i;
+    libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks(
+        &st->shake128_state[i0],
+        Eurydice_array_to_slice((size_t)504U, out[i0], uint8_t));
+  }
+  memcpy(ret, out, (size_t)3U * sizeof(uint8_t[504U]));
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::hash_functions::Hash<K> for
+libcrux_ml_kem::hash_functions::portable::PortableHash<K>)}
+*/
+/**
+A monomorphic instance of
+libcrux_ml_kem.hash_functions.portable.shake128_squeeze_three_blocks_f1 with
+const generics
+- K= 3
+*/
+static KRML_MUSTINLINE void
+libcrux_ml_kem_hash_functions_portable_shake128_squeeze_three_blocks_f1_69(
+    libcrux_ml_kem_hash_functions_portable_PortableHash_58 *self,
+    uint8_t ret[3U][504U]) {
+  libcrux_ml_kem_hash_functions_portable_shake128_squeeze_three_blocks_ca(self,
+                                                                          ret);
+}
+
+/**
+ If `bytes` contains a set of uniformly random bytes, this function
+ uniformly samples a ring element `â` that is treated as being the NTT
+ representation of the corresponding polynomial `a`.
+
+ Since rejection sampling is used, it is possible the supplied bytes are
+ not enough to sample the element, in which case an `Err` is returned and the
+ caller must try again with a fresh set of bytes.
+
+ This function <strong>partially</strong> implements <strong>Algorithm
+ 6</strong> of the NIST FIPS 203 standard, We say "partially" because this
+ implementation only accepts a finite set of bytes as input and returns an error
+ if the set is not enough; Algorithm 6 of the FIPS 203 standard on the other
+ hand samples from an infinite stream of bytes until the ring element is filled.
+ Algorithm 6 is reproduced below:
+
+ ```plaintext
+ Input: byte stream B ∈ 𝔹*.
+ Output: array â ∈ ℤ₂₅₆.
+
+ i ← 0
+ j ← 0
+ while j < 256 do
+     d₁ ← B[i] + 256·(B[i+1] mod 16)
+     d₂ ← ⌊B[i+1]/16⌋ + 16·B[i+2]
+     if d₁ < q then
+         â[j] ← d₁
+         j ← j + 1
+     end if
+     if d₂ < q and j < 256 then
+         â[j] ← d₂
+         j ← j + 1
+     end if
+     i ← i + 3
+ end while
+ return â
+ ```
+
+ The NIST FIPS 203 standard can be found at
+ <https://csrc.nist.gov/pubs/fips/203/ipd>.
+*/
+/**
+A monomorphic instance of
+libcrux_ml_kem.sampling.sample_from_uniform_distribution_next with types
+libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics
+- K= 3
+- N= 504
+*/
+static KRML_MUSTINLINE bool
+libcrux_ml_kem_sampling_sample_from_uniform_distribution_next_db(
+    uint8_t randomness[3U][504U], size_t *sampled_coefficients,
+    int16_t (*out)[272U]) {
+  for (size_t i0 = (size_t)0U; i0 < (size_t)3U; i0++) {
+    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_subslice2(randomness[i1], r * (size_t)24U,
+                                        r * (size_t)24U + (size_t)24U, uint8_t);
+        size_t sampled = libcrux_ml_kem_vector_portable_rej_sample_0d(
+            uu____0, Eurydice_array_to_subslice2(
+                         out[i1], sampled_coefficients[i1],
+                         sampled_coefficients[i1] + (size_t)16U, int16_t));
+        size_t uu____1 = i1;
+        sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled;
+      }
+    }
+  }
+  bool done = true;
+  for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+    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;
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.hash_functions.portable.shake128_squeeze_block with const
+generics
+- K= 3
+*/
+static KRML_MUSTINLINE void
+libcrux_ml_kem_hash_functions_portable_shake128_squeeze_block_dd(
+    libcrux_ml_kem_hash_functions_portable_PortableHash_58 *st,
+    uint8_t ret[3U][168U]) {
+  uint8_t out[3U][168U] = {{0U}};
+  for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+    size_t i0 = i;
+    libcrux_sha3_portable_incremental_shake128_squeeze_next_block(
+        &st->shake128_state[i0],
+        Eurydice_array_to_slice((size_t)168U, out[i0], uint8_t));
+  }
+  memcpy(ret, out, (size_t)3U * sizeof(uint8_t[168U]));
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::hash_functions::Hash<K> for
+libcrux_ml_kem::hash_functions::portable::PortableHash<K>)}
+*/
+/**
+A monomorphic instance of
+libcrux_ml_kem.hash_functions.portable.shake128_squeeze_block_f1 with const
+generics
+- K= 3
+*/
+static KRML_MUSTINLINE void
+libcrux_ml_kem_hash_functions_portable_shake128_squeeze_block_f1_60(
+    libcrux_ml_kem_hash_functions_portable_PortableHash_58 *self,
+    uint8_t ret[3U][168U]) {
+  libcrux_ml_kem_hash_functions_portable_shake128_squeeze_block_dd(self, ret);
+}
+
+/**
+ If `bytes` contains a set of uniformly random bytes, this function
+ uniformly samples a ring element `â` that is treated as being the NTT
+ representation of the corresponding polynomial `a`.
+
+ Since rejection sampling is used, it is possible the supplied bytes are
+ not enough to sample the element, in which case an `Err` is returned and the
+ caller must try again with a fresh set of bytes.
+
+ This function <strong>partially</strong> implements <strong>Algorithm
+ 6</strong> of the NIST FIPS 203 standard, We say "partially" because this
+ implementation only accepts a finite set of bytes as input and returns an error
+ if the set is not enough; Algorithm 6 of the FIPS 203 standard on the other
+ hand samples from an infinite stream of bytes until the ring element is filled.
+ Algorithm 6 is reproduced below:
+
+ ```plaintext
+ Input: byte stream B ∈ 𝔹*.
+ Output: array â ∈ ℤ₂₅₆.
+
+ i ← 0
+ j ← 0
+ while j < 256 do
+     d₁ ← B[i] + 256·(B[i+1] mod 16)
+     d₂ ← ⌊B[i+1]/16⌋ + 16·B[i+2]
+     if d₁ < q then
+         â[j] ← d₁
+         j ← j + 1
+     end if
+     if d₂ < q and j < 256 then
+         â[j] ← d₂
+         j ← j + 1
+     end if
+     i ← i + 3
+ end while
+ return â
+ ```
+
+ The NIST FIPS 203 standard can be found at
+ <https://csrc.nist.gov/pubs/fips/203/ipd>.
+*/
+/**
+A monomorphic instance of
+libcrux_ml_kem.sampling.sample_from_uniform_distribution_next with types
+libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics
+- K= 3
+- N= 168
+*/
+static KRML_MUSTINLINE bool
+libcrux_ml_kem_sampling_sample_from_uniform_distribution_next_db0(
+    uint8_t randomness[3U][168U], size_t *sampled_coefficients,
+    int16_t (*out)[272U]) {
+  for (size_t i0 = (size_t)0U; i0 < (size_t)3U; i0++) {
+    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_subslice2(randomness[i1], r * (size_t)24U,
+                                        r * (size_t)24U + (size_t)24U, uint8_t);
+        size_t sampled = libcrux_ml_kem_vector_portable_rej_sample_0d(
+            uu____0, Eurydice_array_to_subslice2(
+                         out[i1], sampled_coefficients[i1],
+                         sampled_coefficients[i1] + (size_t)16U, int16_t));
+        size_t uu____1 = i1;
+        sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled;
+      }
+    }
+  }
+  bool done = true;
+  for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+    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;
+}
+
+/**
+This function found in impl
+{libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0]}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.polynomial.from_i16_array_89
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_polynomial_from_i16_array_89_c1(Eurydice_slice a) {
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 result =
+      libcrux_ml_kem_polynomial_ZERO_89_ea();
+  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_vector_type_PortableVector uu____0 =
+        libcrux_ml_kem_vector_portable_from_i16_array_0d(
+            Eurydice_slice_subslice2(a, i0 * (size_t)16U,
+                                     (i0 + (size_t)1U) * (size_t)16U, int16_t));
+    result.coefficients[i0] = uu____0;
+  }
+  return result;
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.sampling.sample_from_xof.closure
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector,
+libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const
+generics
+- K= 3
+*/
+static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_sampling_sample_from_xof_closure_04(int16_t s[272U]) {
+  return libcrux_ml_kem_polynomial_from_i16_array_89_c1(
+      Eurydice_array_to_subslice2(s, (size_t)0U, (size_t)256U, int16_t));
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.sampling.sample_from_xof
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector,
+libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const
+generics
+- K= 3
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_sampling_sample_from_xof_3f(
+    uint8_t seeds[3U][34U],
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U]) {
+  size_t sampled_coefficients[3U] = {0U};
+  int16_t out[3U][272U] = {{0U}};
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_seeds[3U][34U];
+  memcpy(copy_of_seeds, seeds, (size_t)3U * sizeof(uint8_t[34U]));
+  libcrux_ml_kem_hash_functions_portable_PortableHash_58 xof_state =
+      libcrux_ml_kem_hash_functions_portable_shake128_init_absorb_f1_8c(
+          copy_of_seeds);
+  uint8_t randomness0[3U][504U];
+  libcrux_ml_kem_hash_functions_portable_shake128_squeeze_three_blocks_f1_69(
+      &xof_state, randomness0);
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_randomness0[3U][504U];
+  memcpy(copy_of_randomness0, randomness0, (size_t)3U * sizeof(uint8_t[504U]));
+  bool done = libcrux_ml_kem_sampling_sample_from_uniform_distribution_next_db(
+      copy_of_randomness0, sampled_coefficients, out);
+  while (true) {
+    if (done) {
+      break;
+    } else {
+      uint8_t randomness[3U][168U];
+      libcrux_ml_kem_hash_functions_portable_shake128_squeeze_block_f1_60(
+          &xof_state, randomness);
+      /* Passing arrays by value in Rust generates a copy in C */
+      uint8_t copy_of_randomness[3U][168U];
+      memcpy(copy_of_randomness, randomness,
+             (size_t)3U * sizeof(uint8_t[168U]));
+      done = libcrux_ml_kem_sampling_sample_from_uniform_distribution_next_db0(
+          copy_of_randomness, sampled_coefficients, out);
+    }
+  }
+  /* Passing arrays by value in Rust generates a copy in C */
+  int16_t copy_of_out[3U][272U];
+  memcpy(copy_of_out, out, (size_t)3U * sizeof(int16_t[272U]));
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret0[3U];
+  for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+    ret0[i] =
+        libcrux_ml_kem_sampling_sample_from_xof_closure_04(copy_of_out[i]);
+  }
+  memcpy(
+      ret, ret0,
+      (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.matrix.sample_matrix_A
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector,
+libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const
+generics
+- K= 3
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_matrix_sample_matrix_A_38(
+    uint8_t seed[34U], bool transpose,
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U][3U]) {
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 A_transpose[3U][3U];
+  for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+    libcrux_ml_kem_matrix_sample_matrix_A_closure_4b(i, A_transpose[i]);
+  }
+  for (size_t i0 = (size_t)0U; i0 < (size_t)3U; i0++) {
+    size_t i1 = i0;
+    /* Passing arrays by value in Rust generates a copy in C */
+    uint8_t copy_of_seed[34U];
+    memcpy(copy_of_seed, seed, (size_t)34U * sizeof(uint8_t));
+    uint8_t seeds[3U][34U];
+    for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+      memcpy(seeds[i], copy_of_seed, (size_t)34U * sizeof(uint8_t));
+    }
+    for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+      size_t j = i;
+      seeds[j][32U] = (uint8_t)i1;
+      seeds[j][33U] = (uint8_t)j;
+    }
+    /* Passing arrays by value in Rust generates a copy in C */
+    uint8_t copy_of_seeds[3U][34U];
+    memcpy(copy_of_seeds, seeds, (size_t)3U * sizeof(uint8_t[34U]));
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 sampled[3U];
+    libcrux_ml_kem_sampling_sample_from_xof_3f(copy_of_seeds, sampled);
+    for (size_t i = (size_t)0U;
+         i < Eurydice_slice_len(
+                 Eurydice_array_to_slice(
+                     (size_t)3U, sampled,
+                     libcrux_ml_kem_polynomial_PolynomialRingElement_f0),
+                 libcrux_ml_kem_polynomial_PolynomialRingElement_f0);
+         i++) {
+      size_t j = i;
+      libcrux_ml_kem_polynomial_PolynomialRingElement_f0 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_f0[3U]));
+}
+
+/**
+A monomorphic instance of K.
+with types libcrux_ml_kem_polynomial_PolynomialRingElement
+libcrux_ml_kem_vector_portable_vector_type_PortableVector[3size_t], uint8_t
+
+*/
+typedef struct tuple_b0_s {
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 fst[3U];
+  uint8_t snd;
+} tuple_b0;
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.ind_cpa.sample_vector_cbd_then_ntt.closure with types
+libcrux_ml_kem_vector_portable_vector_type_PortableVector,
+libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const
+generics
+- K= 3
+- ETA= 2
+- ETA_RANDOMNESS_SIZE= 128
+*/
+static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_closure_f7(size_t _i) {
+  return libcrux_ml_kem_polynomial_ZERO_89_ea();
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRFxN
+with const generics
+- K= 3
+- LEN= 128
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_PRFxN_c5(
+    uint8_t (*input)[33U], uint8_t ret[3U][128U]) {
+  uint8_t out[3U][128U] = {{0U}};
+  for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+    size_t i0 = i;
+    libcrux_sha3_portable_shake256(
+        Eurydice_array_to_slice((size_t)128U, out[i0], uint8_t),
+        Eurydice_array_to_slice((size_t)33U, input[i0], uint8_t));
+  }
+  memcpy(ret, out, (size_t)3U * sizeof(uint8_t[128U]));
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::hash_functions::Hash<K> for
+libcrux_ml_kem::hash_functions::portable::PortableHash<K>)}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRFxN_f1
+with const generics
+- K= 3
+- LEN= 128
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_PRFxN_f1_93(
+    uint8_t (*input)[33U], uint8_t ret[3U][128U]) {
+  libcrux_ml_kem_hash_functions_portable_PRFxN_c5(input, ret);
+}
+
+/**
+ Given a series of uniformly random bytes in `randomness`, for some number
+ `eta`, the `sample_from_binomial_distribution_{eta}` functions sample a ring
+ element from a binomial distribution centered at 0 that uses two sets of `eta`
+ coin flips. If, for example, `eta = ETA`, each ring coefficient is a value `v`
+ such such that `v ∈ {-ETA, -ETA + 1, ..., 0, ..., ETA + 1, ETA}` and:
+
+ ```plaintext
+ - If v < 0, Pr[v] = Pr[-v]
+ - If v >= 0, Pr[v] = BINOMIAL_COEFFICIENT(2 * ETA; ETA - v) / 2 ^ (2 * ETA)
+ ```
+
+ The values `v < 0` are mapped to the appropriate `KyberFieldElement`.
+
+ The expected value is:
+
+ ```plaintext
+ E[X] = (-ETA)Pr[-ETA] + (-(ETA - 1))Pr[-(ETA - 1)] + ... + (ETA - 1)Pr[ETA - 1]
+ + (ETA)Pr[ETA] = 0 since Pr[-v] = Pr[v] when v < 0.
+ ```
+
+ And the variance is:
+
+ ```plaintext
+ Var(X) = E[(X - E[X])^2]
+        = E[X^2]
+        = sum_(v=-ETA to ETA)v^2 * (BINOMIAL_COEFFICIENT(2 * ETA; ETA - v) /
+ 2^(2 * ETA)) = ETA / 2
+ ```
+
+ This function implements <strong>Algorithm 7</strong> of the NIST FIPS 203
+ standard, which is reproduced below:
+
+ ```plaintext
+ Input: byte array B ∈ 𝔹^{64η}.
+ Output: array f ∈ ℤ₂₅₆.
+
+ b ← BytesToBits(B)
+ for (i ← 0; i < 256; i++)
+     x ← ∑(j=0 to η - 1) b[2iη + j]
+     y ← ∑(j=0 to η - 1) b[2iη + η + j]
+     f[i] ← x−y mod q
+ end for
+ return f
+ ```
+
+ The NIST FIPS 203 standard can be found at
+ <https://csrc.nist.gov/pubs/fips/203/ipd>.
+*/
+/**
+A monomorphic instance of
+libcrux_ml_kem.sampling.sample_from_binomial_distribution_2 with types
+libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics
+
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_sampling_sample_from_binomial_distribution_2_85(
+    Eurydice_slice randomness) {
+  int16_t sampled_i16s[256U] = {0U};
+  for (size_t i0 = (size_t)0U;
+       i0 < Eurydice_slice_len(randomness, uint8_t) / (size_t)4U; i0++) {
+    size_t chunk_number = i0;
+    Eurydice_slice byte_chunk = Eurydice_slice_subslice2(
+        randomness, chunk_number * (size_t)4U,
+        chunk_number * (size_t)4U + (size_t)4U, uint8_t);
+    uint32_t random_bits_as_u32 =
+        (((uint32_t)Eurydice_slice_index(byte_chunk, (size_t)0U, uint8_t,
+                                         uint8_t *) |
+          (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, uint8_t,
+                                         uint8_t *)
+              << 8U) |
+         (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, uint8_t,
+                                        uint8_t *)
+             << 16U) |
+        (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)3U, 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_from_i16_array_89_c1(
+      Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t));
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.sampling.sample_from_binomial_distribution_3 with types
+libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics
+
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_sampling_sample_from_binomial_distribution_3_eb(
+    Eurydice_slice randomness) {
+  int16_t sampled_i16s[256U] = {0U};
+  for (size_t i0 = (size_t)0U;
+       i0 < Eurydice_slice_len(randomness, uint8_t) / (size_t)3U; i0++) {
+    size_t chunk_number = i0;
+    Eurydice_slice byte_chunk = Eurydice_slice_subslice2(
+        randomness, chunk_number * (size_t)3U,
+        chunk_number * (size_t)3U + (size_t)3U, uint8_t);
+    uint32_t random_bits_as_u24 =
+        ((uint32_t)Eurydice_slice_index(byte_chunk, (size_t)0U, uint8_t,
+                                        uint8_t *) |
+         (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, uint8_t,
+                                        uint8_t *)
+             << 8U) |
+        (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, 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_from_i16_array_89_c1(
+      Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t));
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.sampling.sample_from_binomial_distribution with types
+libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics
+- ETA= 2
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_sampling_sample_from_binomial_distribution_c6(
+    Eurydice_slice randomness) {
+  return libcrux_ml_kem_sampling_sample_from_binomial_distribution_2_85(
+      randomness);
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.ntt.ntt_at_layer_7
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_ntt_ntt_at_layer_7_f4(
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *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_vector_type_PortableVector t =
+        libcrux_ml_kem_vector_portable_multiply_by_constant_0d(
+            re->coefficients[j + step], (int16_t)-1600);
+    re->coefficients[j + step] =
+        libcrux_ml_kem_vector_portable_sub_0d(re->coefficients[j], &t);
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____1 =
+        libcrux_ml_kem_vector_portable_add_0d(re->coefficients[j], &t);
+    re->coefficients[j] = uu____1;
+  }
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.ntt.ntt_binomially_sampled_ring_element
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static KRML_MUSTINLINE void
+libcrux_ml_kem_ntt_ntt_binomially_sampled_ring_element_0f(
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re) {
+  libcrux_ml_kem_ntt_ntt_at_layer_7_f4(re);
+  size_t zeta_i = (size_t)1U;
+  libcrux_ml_kem_ntt_ntt_at_layer_4_plus_51(&zeta_i, re, (size_t)6U,
+                                            (size_t)3U);
+  libcrux_ml_kem_ntt_ntt_at_layer_4_plus_51(&zeta_i, re, (size_t)5U,
+                                            (size_t)3U);
+  libcrux_ml_kem_ntt_ntt_at_layer_4_plus_51(&zeta_i, re, (size_t)4U,
+                                            (size_t)3U);
+  libcrux_ml_kem_ntt_ntt_at_layer_3_fd(&zeta_i, re, (size_t)3U, (size_t)3U);
+  libcrux_ml_kem_ntt_ntt_at_layer_2_ad(&zeta_i, re, (size_t)2U, (size_t)3U);
+  libcrux_ml_kem_ntt_ntt_at_layer_1_a2(&zeta_i, re, (size_t)1U, (size_t)3U);
+  libcrux_ml_kem_polynomial_poly_barrett_reduce_89_8b(re);
+}
+
+/**
+ Sample a vector of ring elements from a centered binomial distribution and
+ convert them into their NTT representations.
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.ind_cpa.sample_vector_cbd_then_ntt
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector,
+libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const
+generics
+- K= 3
+- ETA= 2
+- ETA_RANDOMNESS_SIZE= 128
+*/
+static KRML_MUSTINLINE tuple_b0
+libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_fc(uint8_t prf_input[33U],
+                                                     uint8_t domain_separator) {
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re_as_ntt[3U];
+  for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+    re_as_ntt[i] = libcrux_ml_kem_polynomial_ZERO_89_ea();
+  }
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_prf_input[33U];
+  memcpy(copy_of_prf_input, prf_input, (size_t)33U * sizeof(uint8_t));
+  uint8_t prf_inputs[3U][33U];
+  for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+    memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t));
+  }
+  for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+    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_PRFxN_f1_93(prf_inputs, prf_outputs);
+  for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+    size_t i0 = i;
+    re_as_ntt[i0] =
+        libcrux_ml_kem_sampling_sample_from_binomial_distribution_c6(
+            Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], uint8_t));
+    libcrux_ml_kem_ntt_ntt_binomially_sampled_ring_element_0f(&re_as_ntt[i0]);
+  }
+  /* Passing arrays by value in Rust generates a copy in C */
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 copy_of_re_as_ntt[3U];
+  memcpy(
+      copy_of_re_as_ntt, re_as_ntt,
+      (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+  tuple_b0 lit;
+  memcpy(
+      lit.fst, copy_of_re_as_ntt,
+      (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+  lit.snd = domain_separator;
+  return lit;
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.ind_cpa.sample_ring_element_cbd.closure
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector,
+libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const
+generics
+- K= 3
+- ETA2_RANDOMNESS_SIZE= 128
+- ETA2= 2
+*/
+static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_ind_cpa_sample_ring_element_cbd_closure_77(size_t _i) {
+  return libcrux_ml_kem_polynomial_ZERO_89_ea();
+}
+
+/**
+ Sample a vector of ring elements from a centered binomial distribution.
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.ind_cpa.sample_ring_element_cbd
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector,
+libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const
+generics
+- K= 3
+- ETA2_RANDOMNESS_SIZE= 128
+- ETA2= 2
+*/
+static KRML_MUSTINLINE tuple_b0
+libcrux_ml_kem_ind_cpa_sample_ring_element_cbd_ac(uint8_t prf_input[33U],
+                                                  uint8_t domain_separator) {
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 error_1[3U];
+  for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+    error_1[i] = libcrux_ml_kem_polynomial_ZERO_89_ea();
+  }
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_prf_input[33U];
+  memcpy(copy_of_prf_input, prf_input, (size_t)33U * sizeof(uint8_t));
+  uint8_t prf_inputs[3U][33U];
+  for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+    memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t));
+  }
+  for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+    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_PRFxN_f1_93(prf_inputs, prf_outputs);
+  for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+    size_t i0 = i;
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 uu____1 =
+        libcrux_ml_kem_sampling_sample_from_binomial_distribution_c6(
+            Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], uint8_t));
+    error_1[i0] = uu____1;
+  }
+  /* Passing arrays by value in Rust generates a copy in C */
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 copy_of_error_1[3U];
+  memcpy(
+      copy_of_error_1, error_1,
+      (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+  tuple_b0 lit;
+  memcpy(
+      lit.fst, copy_of_error_1,
+      (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+  lit.snd = domain_separator;
+  return lit;
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRF
+with const generics
+- LEN= 128
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_PRF_2b0(
+    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), input);
+  memcpy(ret, digest, (size_t)128U * sizeof(uint8_t));
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::hash_functions::Hash<K> for
+libcrux_ml_kem::hash_functions::portable::PortableHash<K>)}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRF_f1
+with const generics
+- K= 3
+- LEN= 128
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_PRF_f1_ee0(
+    Eurydice_slice input, uint8_t ret[128U]) {
+  libcrux_ml_kem_hash_functions_portable_PRF_2b0(input, ret);
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.matrix.compute_vector_u.closure
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+- K= 3
+*/
+static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_matrix_compute_vector_u_closure_d6(size_t _i) {
+  return libcrux_ml_kem_polynomial_ZERO_89_ea();
+}
+
+/**
+This function found in impl
+{libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0]}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.polynomial.add_error_reduce_89
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_polynomial_add_error_reduce_89_38(
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *self,
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *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_vector_type_PortableVector
+        coefficient_normal_form =
+            libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_0d(
+                self->coefficients[j], (int16_t)1441);
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 =
+        libcrux_ml_kem_vector_portable_barrett_reduce_0d(
+            libcrux_ml_kem_vector_portable_add_0d(coefficient_normal_form,
+                                                  &error->coefficients[j]));
+    self->coefficients[j] = uu____0;
+  }
+}
+
+/**
+ Compute u := InvertNTT(Aᵀ ◦ r̂) + e₁
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.matrix.compute_vector_u
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+- K= 3
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_matrix_compute_vector_u_59(
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 (*a_as_ntt)[3U],
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *r_as_ntt,
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *error_1,
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U]) {
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 result[3U];
+  for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+    result[i] = libcrux_ml_kem_polynomial_ZERO_89_ea();
+  }
+  for (size_t i0 = (size_t)0U;
+       i0 < Eurydice_slice_len(
+                Eurydice_array_to_slice(
+                    (size_t)3U, a_as_ntt,
+                    libcrux_ml_kem_polynomial_PolynomialRingElement_f0[3U]),
+                libcrux_ml_kem_polynomial_PolynomialRingElement_f0[3U]);
+       i0++) {
+    size_t i1 = i0;
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *row = a_as_ntt[i1];
+    for (size_t i = (size_t)0U;
+         i < Eurydice_slice_len(
+                 Eurydice_array_to_slice(
+                     (size_t)3U, row,
+                     libcrux_ml_kem_polynomial_PolynomialRingElement_f0),
+                 libcrux_ml_kem_polynomial_PolynomialRingElement_f0);
+         i++) {
+      size_t j = i;
+      libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *a_element = &row[j];
+      libcrux_ml_kem_polynomial_PolynomialRingElement_f0 product =
+          libcrux_ml_kem_polynomial_ntt_multiply_89_2a(a_element, &r_as_ntt[j]);
+      libcrux_ml_kem_polynomial_add_to_ring_element_89_84(&result[i1],
+                                                          &product);
+    }
+    libcrux_ml_kem_invert_ntt_invert_ntt_montgomery_f6(&result[i1]);
+    libcrux_ml_kem_polynomial_add_error_reduce_89_38(&result[i1], &error_1[i1]);
+  }
+  memcpy(
+      ret, result,
+      (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.vector.traits.decompress_1
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_traits_decompress_1_63(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v) {
+  libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 =
+      libcrux_ml_kem_vector_portable_ZERO_0d();
+  return libcrux_ml_kem_vector_portable_bitwise_and_with_constant_0d(
+      libcrux_ml_kem_vector_portable_sub_0d(uu____0, &v), (int16_t)1665);
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.serialize.deserialize_then_decompress_message with types
+libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics
+
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_serialize_deserialize_then_decompress_message_0d(
+    uint8_t serialized[32U]) {
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re =
+      libcrux_ml_kem_polynomial_ZERO_89_ea();
+  for (size_t i = (size_t)0U; i < (size_t)16U; i++) {
+    size_t i0 = i;
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector
+        coefficient_compressed =
+            libcrux_ml_kem_vector_portable_deserialize_1_0d(
+                Eurydice_array_to_subslice2(serialized, (size_t)2U * i0,
+                                            (size_t)2U * i0 + (size_t)2U,
+                                            uint8_t));
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 =
+        libcrux_ml_kem_vector_traits_decompress_1_63(coefficient_compressed);
+    re.coefficients[i0] = uu____0;
+  }
+  return re;
+}
+
+/**
+This function found in impl
+{libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0]}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.polynomial.add_message_error_reduce_89
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_polynomial_add_message_error_reduce_89_ea(
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *self,
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *message,
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 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_vector_type_PortableVector
+        coefficient_normal_form =
+            libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_0d(
+                result.coefficients[i0], (int16_t)1441);
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector tmp =
+        libcrux_ml_kem_vector_portable_add_0d(self->coefficients[i0],
+                                              &message->coefficients[i0]);
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector tmp0 =
+        libcrux_ml_kem_vector_portable_add_0d(coefficient_normal_form, &tmp);
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 =
+        libcrux_ml_kem_vector_portable_barrett_reduce_0d(tmp0);
+    result.coefficients[i0] = uu____0;
+  }
+  return result;
+}
+
+/**
+ Compute InverseNTT(tᵀ ◦ r̂) + e₂ + message
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.matrix.compute_ring_element_v
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+- K= 3
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_matrix_compute_ring_element_v_54(
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *t_as_ntt,
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *r_as_ntt,
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *error_2,
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *message) {
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 result =
+      libcrux_ml_kem_polynomial_ZERO_89_ea();
+  for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+    size_t i0 = i;
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 product =
+        libcrux_ml_kem_polynomial_ntt_multiply_89_2a(&t_as_ntt[i0],
+                                                     &r_as_ntt[i0]);
+    libcrux_ml_kem_polynomial_add_to_ring_element_89_84(&result, &product);
+  }
+  libcrux_ml_kem_invert_ntt_invert_ntt_montgomery_f6(&result);
+  result = libcrux_ml_kem_polynomial_add_message_error_reduce_89_ea(
+      error_2, message, result);
+  return result;
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.vector.portable.compress.compress
+with const generics
+- COEFFICIENT_BITS= 10
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_compress_compress_02(
+    libcrux_ml_kem_vector_portable_vector_type_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_portable_compress_compress_ciphertext_coefficient(
+            (uint8_t)(int32_t)10, (uint16_t)v.elements[i0]);
+    v.elements[i0] = uu____0;
+  }
+  return v;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.vector.portable.compress_0d
+with const generics
+- COEFFICIENT_BITS= 10
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_compress_0d_28(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v) {
+  return libcrux_ml_kem_vector_portable_compress_compress_02(v);
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.serialize.compress_then_serialize_10
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+- OUT_LEN= 320
+*/
+static KRML_MUSTINLINE void
+libcrux_ml_kem_serialize_compress_then_serialize_10_fc(
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *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_vector_type_PortableVector coefficient =
+        libcrux_ml_kem_vector_portable_compress_0d_28(
+            libcrux_ml_kem_vector_traits_to_unsigned_representative_db(
+                re->coefficients[i0]));
+    uint8_t bytes[20U];
+    libcrux_ml_kem_vector_portable_serialize_10_0d(coefficient, bytes);
+    Eurydice_slice uu____0 = Eurydice_array_to_subslice2(
+        serialized, (size_t)20U * i0, (size_t)20U * i0 + (size_t)20U, uint8_t);
+    Eurydice_slice_copy(
+        uu____0, Eurydice_array_to_slice((size_t)20U, bytes, uint8_t), uint8_t);
+  }
+  memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t));
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.vector.portable.compress.compress
+with const generics
+- COEFFICIENT_BITS= 11
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_compress_compress_020(
+    libcrux_ml_kem_vector_portable_vector_type_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_portable_compress_compress_ciphertext_coefficient(
+            (uint8_t)(int32_t)11, (uint16_t)v.elements[i0]);
+    v.elements[i0] = uu____0;
+  }
+  return v;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.vector.portable.compress_0d
+with const generics
+- COEFFICIENT_BITS= 11
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_compress_0d_280(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v) {
+  return libcrux_ml_kem_vector_portable_compress_compress_020(v);
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.serialize.compress_then_serialize_11
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+- OUT_LEN= 320
+*/
+static KRML_MUSTINLINE void
+libcrux_ml_kem_serialize_compress_then_serialize_11_e1(
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *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_vector_type_PortableVector coefficient =
+        libcrux_ml_kem_vector_portable_compress_0d_280(
+            libcrux_ml_kem_vector_traits_to_unsigned_representative_db(
+                re->coefficients[i0]));
+    uint8_t bytes[22U];
+    libcrux_ml_kem_vector_portable_serialize_11_0d(coefficient, bytes);
+    Eurydice_slice uu____0 = Eurydice_array_to_subslice2(
+        serialized, (size_t)22U * i0, (size_t)22U * i0 + (size_t)22U, uint8_t);
+    Eurydice_slice_copy(
+        uu____0, Eurydice_array_to_slice((size_t)22U, bytes, uint8_t), uint8_t);
+  }
+  memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t));
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.serialize.compress_then_serialize_ring_element_u with types
+libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics
+- COMPRESSION_FACTOR= 10
+- OUT_LEN= 320
+*/
+static KRML_MUSTINLINE void
+libcrux_ml_kem_serialize_compress_then_serialize_ring_element_u_5f(
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, uint8_t ret[320U]) {
+  uint8_t uu____0[320U];
+  libcrux_ml_kem_serialize_compress_then_serialize_10_fc(re, uu____0);
+  memcpy(ret, uu____0, (size_t)320U * sizeof(uint8_t));
+}
+
+/**
+ Call [`compress_then_serialize_ring_element_u`] on each ring element.
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.ind_cpa.compress_then_serialize_u
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+- K= 3
+- OUT_LEN= 960
+- COMPRESSION_FACTOR= 10
+- BLOCK_LEN= 320
+*/
+static inline void libcrux_ml_kem_ind_cpa_compress_then_serialize_u_a7(
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 input[3U],
+    Eurydice_slice out) {
+  for (size_t i = (size_t)0U;
+       i < Eurydice_slice_len(
+               Eurydice_array_to_slice(
+                   (size_t)3U, input,
+                   libcrux_ml_kem_polynomial_PolynomialRingElement_f0),
+               libcrux_ml_kem_polynomial_PolynomialRingElement_f0);
+       i++) {
+    size_t i0 = i;
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re = input[i0];
+    Eurydice_slice uu____0 = Eurydice_slice_subslice2(
+        out, i0 * ((size_t)960U / (size_t)3U),
+        (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U), uint8_t);
+    uint8_t ret[320U];
+    libcrux_ml_kem_serialize_compress_then_serialize_ring_element_u_5f(&re,
+                                                                       ret);
+    Eurydice_slice_copy(
+        uu____0, Eurydice_array_to_slice((size_t)320U, ret, uint8_t), uint8_t);
+  }
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.vector.portable.compress.compress
+with const generics
+- COEFFICIENT_BITS= 4
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_compress_compress_021(
+    libcrux_ml_kem_vector_portable_vector_type_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_portable_compress_compress_ciphertext_coefficient(
+            (uint8_t)(int32_t)4, (uint16_t)v.elements[i0]);
+    v.elements[i0] = uu____0;
+  }
+  return v;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.vector.portable.compress_0d
+with const generics
+- COEFFICIENT_BITS= 4
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_compress_0d_281(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v) {
+  return libcrux_ml_kem_vector_portable_compress_compress_021(v);
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.serialize.compress_then_serialize_4
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static KRML_MUSTINLINE void
+libcrux_ml_kem_serialize_compress_then_serialize_4_9a(
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 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_vector_type_PortableVector coefficient =
+        libcrux_ml_kem_vector_portable_compress_0d_281(
+            libcrux_ml_kem_vector_traits_to_unsigned_representative_db(
+                re.coefficients[i0]));
+    uint8_t bytes[8U];
+    libcrux_ml_kem_vector_portable_serialize_4_0d(coefficient, bytes);
+    Eurydice_slice_copy(
+        Eurydice_slice_subslice2(serialized, (size_t)8U * i0,
+                                 (size_t)8U * i0 + (size_t)8U, uint8_t),
+        Eurydice_array_to_slice((size_t)8U, bytes, uint8_t), uint8_t);
+  }
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.vector.portable.compress.compress
+with const generics
+- COEFFICIENT_BITS= 5
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_compress_compress_022(
+    libcrux_ml_kem_vector_portable_vector_type_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_portable_compress_compress_ciphertext_coefficient(
+            (uint8_t)(int32_t)5, (uint16_t)v.elements[i0]);
+    v.elements[i0] = uu____0;
+  }
+  return v;
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.vector.portable.compress_0d
+with const generics
+- COEFFICIENT_BITS= 5
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_compress_0d_282(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v) {
+  return libcrux_ml_kem_vector_portable_compress_compress_022(v);
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.serialize.compress_then_serialize_5
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static KRML_MUSTINLINE void
+libcrux_ml_kem_serialize_compress_then_serialize_5_1f(
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 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_vector_type_PortableVector coefficients =
+        libcrux_ml_kem_vector_portable_compress_0d_282(
+            libcrux_ml_kem_vector_traits_to_unsigned_representative_db(
+                re.coefficients[i0]));
+    uint8_t bytes[10U];
+    libcrux_ml_kem_vector_portable_serialize_5_0d(coefficients, bytes);
+    Eurydice_slice_copy(
+        Eurydice_slice_subslice2(serialized, (size_t)10U * i0,
+                                 (size_t)10U * i0 + (size_t)10U, uint8_t),
+        Eurydice_array_to_slice((size_t)10U, bytes, uint8_t), uint8_t);
+  }
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.serialize.compress_then_serialize_ring_element_v with types
+libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics
+- COMPRESSION_FACTOR= 4
+- OUT_LEN= 128
+*/
+static KRML_MUSTINLINE void
+libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v_4e(
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re, Eurydice_slice out) {
+  libcrux_ml_kem_serialize_compress_then_serialize_4_9a(re, out);
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.ind_cpa.encrypt
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector,
+libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const
+generics
+- K= 3
+- CIPHERTEXT_SIZE= 1088
+- T_AS_NTT_ENCODED_SIZE= 1152
+- C1_LEN= 960
+- C2_LEN= 128
+- U_COMPRESSION_FACTOR= 10
+- V_COMPRESSION_FACTOR= 4
+- BLOCK_LEN= 320
+- ETA1= 2
+- ETA1_RANDOMNESS_SIZE= 128
+- ETA2= 2
+- ETA2_RANDOMNESS_SIZE= 128
+*/
+static inline void libcrux_ml_kem_ind_cpa_encrypt_60(Eurydice_slice public_key,
+                                                     uint8_t message[32U],
+                                                     Eurydice_slice randomness,
+                                                     uint8_t ret[1088U]) {
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 t_as_ntt[3U];
+  libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_33(
+      Eurydice_slice_subslice_to(public_key, (size_t)1152U, uint8_t, size_t),
+      t_as_ntt);
+  Eurydice_slice seed =
+      Eurydice_slice_subslice_from(public_key, (size_t)1152U, uint8_t, size_t);
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 A[3U][3U];
+  uint8_t ret0[34U];
+  libcrux_ml_kem_utils_into_padded_array_ea1(seed, ret0);
+  libcrux_ml_kem_matrix_sample_matrix_A_38(ret0, false, A);
+  uint8_t prf_input[33U];
+  libcrux_ml_kem_utils_into_padded_array_ea2(randomness, prf_input);
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_prf_input0[33U];
+  memcpy(copy_of_prf_input0, prf_input, (size_t)33U * sizeof(uint8_t));
+  tuple_b0 uu____1 = libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_fc(
+      copy_of_prf_input0, 0U);
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 r_as_ntt[3U];
+  memcpy(
+      r_as_ntt, uu____1.fst,
+      (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+  uint8_t domain_separator0 = uu____1.snd;
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_prf_input[33U];
+  memcpy(copy_of_prf_input, prf_input, (size_t)33U * sizeof(uint8_t));
+  tuple_b0 uu____3 = libcrux_ml_kem_ind_cpa_sample_ring_element_cbd_ac(
+      copy_of_prf_input, domain_separator0);
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 error_1[3U];
+  memcpy(
+      error_1, uu____3.fst,
+      (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+  uint8_t domain_separator = uu____3.snd;
+  prf_input[32U] = domain_separator;
+  uint8_t prf_output[128U];
+  libcrux_ml_kem_hash_functions_portable_PRF_f1_ee0(
+      Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t), prf_output);
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 error_2 =
+      libcrux_ml_kem_sampling_sample_from_binomial_distribution_c6(
+          Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t));
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 u[3U];
+  libcrux_ml_kem_matrix_compute_vector_u_59(A, r_as_ntt, error_1, u);
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_message[32U];
+  memcpy(copy_of_message, message, (size_t)32U * sizeof(uint8_t));
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 message_as_ring_element =
+      libcrux_ml_kem_serialize_deserialize_then_decompress_message_0d(
+          copy_of_message);
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 v =
+      libcrux_ml_kem_matrix_compute_ring_element_v_54(
+          t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element);
+  uint8_t ciphertext[1088U] = {0U};
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 uu____5[3U];
+  memcpy(
+      uu____5, u,
+      (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+  libcrux_ml_kem_ind_cpa_compress_then_serialize_u_a7(
+      uu____5, Eurydice_array_to_subslice2(ciphertext, (size_t)0U, (size_t)960U,
+                                           uint8_t));
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 uu____6 = v;
+  libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v_4e(
+      uu____6, Eurydice_array_to_subslice_from((size_t)1088U, ciphertext,
+                                               (size_t)960U, uint8_t, size_t));
+  memcpy(ret, ciphertext, (size_t)1088U * sizeof(uint8_t));
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::variant::Variant for
+libcrux_ml_kem::variant::MlKem)#1}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.variant.kdf_d8
+with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]]
+with const generics
+- K= 3
+- CIPHERTEXT_SIZE= 1088
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_variant_kdf_d8_41(
+    Eurydice_slice shared_secret, libcrux_ml_kem_mlkem768_MlKem768Ciphertext *_,
+    uint8_t ret[32U]) {
+  uint8_t out[32U] = {0U};
+  Eurydice_slice_copy(Eurydice_array_to_slice((size_t)32U, out, uint8_t),
+                      shared_secret, uint8_t);
+  memcpy(ret, out, (size_t)32U * sizeof(uint8_t));
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.ind_cca.decapsulate
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector,
+libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]],
+libcrux_ml_kem_variant_MlKem with const generics
+- K= 3
+- SECRET_KEY_SIZE= 2400
+- CPA_SECRET_KEY_SIZE= 1152
+- PUBLIC_KEY_SIZE= 1184
+- CIPHERTEXT_SIZE= 1088
+- T_AS_NTT_ENCODED_SIZE= 1152
+- C1_SIZE= 960
+- C2_SIZE= 128
+- VECTOR_U_COMPRESSION_FACTOR= 10
+- VECTOR_V_COMPRESSION_FACTOR= 4
+- C1_BLOCK_SIZE= 320
+- ETA1= 2
+- ETA1_RANDOMNESS_SIZE= 128
+- ETA2= 2
+- ETA2_RANDOMNESS_SIZE= 128
+- IMPLICIT_REJECTION_HASH_INPUT_SIZE= 1120
+*/
+static inline void libcrux_ml_kem_ind_cca_decapsulate_70(
+    libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key,
+    libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) {
+  Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at(
+      Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t),
+      (size_t)1152U, uint8_t, Eurydice_slice_uint8_t_x2);
+  Eurydice_slice ind_cpa_secret_key = uu____0.fst;
+  Eurydice_slice secret_key0 = uu____0.snd;
+  Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at(
+      secret_key0, (size_t)1184U, uint8_t, Eurydice_slice_uint8_t_x2);
+  Eurydice_slice ind_cpa_public_key = uu____1.fst;
+  Eurydice_slice secret_key = uu____1.snd;
+  Eurydice_slice_uint8_t_x2 uu____2 = Eurydice_slice_split_at(
+      secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t,
+      Eurydice_slice_uint8_t_x2);
+  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_43(ind_cpa_secret_key, ciphertext->value,
+                                    decrypted);
+  uint8_t to_hash0[64U];
+  libcrux_ml_kem_utils_into_padded_array_ea(
+      Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t), to_hash0);
+  Eurydice_slice_copy(
+      Eurydice_array_to_subslice_from(
+          (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE,
+          uint8_t, size_t),
+      ind_cpa_public_key_hash, uint8_t);
+  uint8_t hashed[64U];
+  libcrux_ml_kem_hash_functions_portable_G_f1_e4(
+      Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t), hashed);
+  Eurydice_slice_uint8_t_x2 uu____3 = Eurydice_slice_split_at(
+      Eurydice_array_to_slice((size_t)64U, hashed, uint8_t),
+      LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t,
+      Eurydice_slice_uint8_t_x2);
+  Eurydice_slice shared_secret0 = uu____3.fst;
+  Eurydice_slice pseudorandomness = uu____3.snd;
+  uint8_t to_hash[1120U];
+  libcrux_ml_kem_utils_into_padded_array_ea0(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_copy(uu____4, libcrux_ml_kem_types_as_ref_00_24(ciphertext),
+                      uint8_t);
+  uint8_t implicit_rejection_shared_secret0[32U];
+  libcrux_ml_kem_hash_functions_portable_PRF_f1_ee(
+      Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t),
+      implicit_rejection_shared_secret0);
+  Eurydice_slice uu____5 = ind_cpa_public_key;
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_decrypted[32U];
+  memcpy(copy_of_decrypted, decrypted, (size_t)32U * sizeof(uint8_t));
+  uint8_t expected_ciphertext[1088U];
+  libcrux_ml_kem_ind_cpa_encrypt_60(uu____5, copy_of_decrypted,
+                                    pseudorandomness, expected_ciphertext);
+  uint8_t implicit_rejection_shared_secret[32U];
+  libcrux_ml_kem_variant_kdf_d8_41(
+      Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret0,
+                              uint8_t),
+      ciphertext, implicit_rejection_shared_secret);
+  uint8_t shared_secret[32U];
+  libcrux_ml_kem_variant_kdf_d8_41(shared_secret0, ciphertext, shared_secret);
+  uint8_t ret0[32U];
+  libcrux_ml_kem_constant_time_ops_compare_ciphertexts_select_shared_secret_in_constant_time(
+      libcrux_ml_kem_types_as_ref_00_24(ciphertext),
+      Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, uint8_t),
+      Eurydice_array_to_slice((size_t)32U, shared_secret, uint8_t),
+      Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret,
+                              uint8_t),
+      ret0);
+  memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t));
+}
+
+/**
+ Portable decapsulate
+*/
+/**
+A monomorphic instance of
+libcrux_ml_kem.ind_cca.instantiations.portable.decapsulate with const generics
+- K= 3
+- SECRET_KEY_SIZE= 2400
+- CPA_SECRET_KEY_SIZE= 1152
+- PUBLIC_KEY_SIZE= 1184
+- CIPHERTEXT_SIZE= 1088
+- T_AS_NTT_ENCODED_SIZE= 1152
+- C1_SIZE= 960
+- C2_SIZE= 128
+- VECTOR_U_COMPRESSION_FACTOR= 10
+- VECTOR_V_COMPRESSION_FACTOR= 4
+- C1_BLOCK_SIZE= 320
+- ETA1= 2
+- ETA1_RANDOMNESS_SIZE= 128
+- ETA2= 2
+- ETA2_RANDOMNESS_SIZE= 128
+- IMPLICIT_REJECTION_HASH_INPUT_SIZE= 1120
+*/
+static inline void
+libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate_2e(
+    libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key,
+    libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) {
+  libcrux_ml_kem_ind_cca_decapsulate_70(private_key, ciphertext, ret);
+}
+
+/**
+ Decapsulate ML-KEM 768
+
+ Generates an [`MlKemSharedSecret`].
+ The input is a reference to an [`MlKem768PrivateKey`] and an
+ [`MlKem768Ciphertext`].
+*/
+static inline void libcrux_ml_kem_mlkem768_portable_decapsulate(
+    libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key,
+    libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) {
+  libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate_2e(
+      private_key, ciphertext, ret);
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::variant::Variant for
+libcrux_ml_kem::variant::MlKem)#1}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.variant.entropy_preprocess_d8
+with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]]
+with const generics
+- K= 3
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_variant_entropy_preprocess_d8_63(
+    Eurydice_slice randomness, uint8_t ret[32U]) {
+  uint8_t out[32U] = {0U};
+  Eurydice_slice_copy(Eurydice_array_to_slice((size_t)32U, out, uint8_t),
+                      randomness, uint8_t);
+  memcpy(ret, out, (size_t)32U * sizeof(uint8_t));
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::hash_functions::Hash<K> for
+libcrux_ml_kem::hash_functions::portable::PortableHash<K>)}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.hash_functions.portable.H_f1
+with const generics
+- K= 3
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_H_f1_1a(
+    Eurydice_slice input, uint8_t ret[32U]) {
+  libcrux_ml_kem_hash_functions_portable_H(input, ret);
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.ind_cca.encapsulate
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector,
+libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]],
+libcrux_ml_kem_variant_MlKem with const generics
+- K= 3
+- CIPHERTEXT_SIZE= 1088
+- PUBLIC_KEY_SIZE= 1184
+- T_AS_NTT_ENCODED_SIZE= 1152
+- C1_SIZE= 960
+- C2_SIZE= 128
+- VECTOR_U_COMPRESSION_FACTOR= 10
+- VECTOR_V_COMPRESSION_FACTOR= 4
+- VECTOR_U_BLOCK_LEN= 320
+- ETA1= 2
+- ETA1_RANDOMNESS_SIZE= 128
+- ETA2= 2
+- ETA2_RANDOMNESS_SIZE= 128
+*/
+static inline tuple_3c libcrux_ml_kem_ind_cca_encapsulate_cd(
+    libcrux_ml_kem_types_MlKemPublicKey_15 *public_key,
+    uint8_t randomness[32U]) {
+  uint8_t randomness0[32U];
+  libcrux_ml_kem_variant_entropy_preprocess_d8_63(
+      Eurydice_array_to_slice((size_t)32U, randomness, uint8_t), randomness0);
+  uint8_t to_hash[64U];
+  libcrux_ml_kem_utils_into_padded_array_ea(
+      Eurydice_array_to_slice((size_t)32U, randomness0, uint8_t), 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);
+  uint8_t ret[32U];
+  libcrux_ml_kem_hash_functions_portable_H_f1_1a(
+      Eurydice_array_to_slice((size_t)1184U,
+                              libcrux_ml_kem_types_as_slice_cb_50(public_key),
+                              uint8_t),
+      ret);
+  Eurydice_slice_copy(
+      uu____0, Eurydice_array_to_slice((size_t)32U, ret, uint8_t), uint8_t);
+  uint8_t hashed[64U];
+  libcrux_ml_kem_hash_functions_portable_G_f1_e4(
+      Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t), hashed);
+  Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at(
+      Eurydice_array_to_slice((size_t)64U, hashed, uint8_t),
+      LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t,
+      Eurydice_slice_uint8_t_x2);
+  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_as_slice_cb_50(public_key), uint8_t);
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_randomness[32U];
+  memcpy(copy_of_randomness, randomness0, (size_t)32U * sizeof(uint8_t));
+  uint8_t ciphertext[1088U];
+  libcrux_ml_kem_ind_cpa_encrypt_60(uu____2, copy_of_randomness,
+                                    pseudorandomness, ciphertext);
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_ciphertext[1088U];
+  memcpy(copy_of_ciphertext, ciphertext, (size_t)1088U * sizeof(uint8_t));
+  libcrux_ml_kem_mlkem768_MlKem768Ciphertext ciphertext0 =
+      libcrux_ml_kem_types_from_01_9f(copy_of_ciphertext);
+  uint8_t shared_secret_array[32U];
+  libcrux_ml_kem_variant_kdf_d8_41(shared_secret, &ciphertext0,
+                                   shared_secret_array);
+  libcrux_ml_kem_mlkem768_MlKem768Ciphertext uu____5 = ciphertext0;
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_shared_secret_array[32U];
+  memcpy(copy_of_shared_secret_array, shared_secret_array,
+         (size_t)32U * sizeof(uint8_t));
+  tuple_3c lit;
+  lit.fst = uu____5;
+  memcpy(lit.snd, copy_of_shared_secret_array, (size_t)32U * sizeof(uint8_t));
+  return lit;
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.ind_cca.instantiations.portable.encapsulate with const generics
+- K= 3
+- CIPHERTEXT_SIZE= 1088
+- PUBLIC_KEY_SIZE= 1184
+- T_AS_NTT_ENCODED_SIZE= 1152
+- C1_SIZE= 960
+- C2_SIZE= 128
+- VECTOR_U_COMPRESSION_FACTOR= 10
+- VECTOR_V_COMPRESSION_FACTOR= 4
+- VECTOR_U_BLOCK_LEN= 320
+- ETA1= 2
+- ETA1_RANDOMNESS_SIZE= 128
+- ETA2= 2
+- ETA2_RANDOMNESS_SIZE= 128
+*/
+static inline tuple_3c
+libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate_c6(
+    libcrux_ml_kem_types_MlKemPublicKey_15 *public_key,
+    uint8_t randomness[32U]) {
+  libcrux_ml_kem_types_MlKemPublicKey_15 *uu____0 = public_key;
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_randomness[32U];
+  memcpy(copy_of_randomness, randomness, (size_t)32U * sizeof(uint8_t));
+  return libcrux_ml_kem_ind_cca_encapsulate_cd(uu____0, copy_of_randomness);
+}
+
+/**
+ Encapsulate ML-KEM 768
+
+ Generates an ([`MlKem768Ciphertext`], [`MlKemSharedSecret`]) tuple.
+ The input is a reference to an [`MlKem768PublicKey`] and [`SHARED_SECRET_SIZE`]
+ bytes of `randomness`.
+*/
+static inline tuple_3c libcrux_ml_kem_mlkem768_portable_encapsulate(
+    libcrux_ml_kem_types_MlKemPublicKey_15 *public_key,
+    uint8_t randomness[32U]) {
+  libcrux_ml_kem_types_MlKemPublicKey_15 *uu____0 = public_key;
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_randomness[32U];
+  memcpy(copy_of_randomness, randomness, (size_t)32U * sizeof(uint8_t));
+  return libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate_c6(
+      uu____0, copy_of_randomness);
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::variant::Variant for
+libcrux_ml_kem::variant::MlKem)#1}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.variant.cpa_keygen_seed_d8
+with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]]
+with const generics
+- K= 3
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_variant_cpa_keygen_seed_d8_0e(
+    Eurydice_slice key_generation_seed, uint8_t ret[64U]) {
+  uint8_t seed[33U] = {0U};
+  Eurydice_slice_copy(
+      Eurydice_array_to_subslice2(
+          seed, (size_t)0U,
+          LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t),
+      key_generation_seed, uint8_t);
+  seed[LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE] =
+      (uint8_t)(size_t)3U;
+  uint8_t ret0[64U];
+  libcrux_ml_kem_hash_functions_portable_G_f1_e4(
+      Eurydice_array_to_slice((size_t)33U, seed, uint8_t), ret0);
+  memcpy(ret, ret0, (size_t)64U * sizeof(uint8_t));
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.matrix.compute_As_plus_e.closure
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+- K= 3
+*/
+static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_matrix_compute_As_plus_e_closure_87(size_t _i) {
+  return libcrux_ml_kem_polynomial_ZERO_89_ea();
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.vector.traits.to_standard_domain
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_traits_to_standard_domain_59(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector v) {
+  return libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_0d(
+      v, LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS);
+}
+
+/**
+This function found in impl
+{libcrux_ml_kem::polynomial::PolynomialRingElement<Vector>[TraitClause@0]}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.polynomial.add_standard_error_reduce_89
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static KRML_MUSTINLINE void
+libcrux_ml_kem_polynomial_add_standard_error_reduce_89_03(
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *self,
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *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_vector_type_PortableVector
+        coefficient_normal_form =
+            libcrux_ml_kem_vector_traits_to_standard_domain_59(
+                self->coefficients[j]);
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 =
+        libcrux_ml_kem_vector_portable_barrett_reduce_0d(
+            libcrux_ml_kem_vector_portable_add_0d(coefficient_normal_form,
+                                                  &error->coefficients[j]));
+    self->coefficients[j] = uu____0;
+  }
+}
+
+/**
+ Compute Â ◦ ŝ + ê
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.matrix.compute_As_plus_e
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+- K= 3
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_matrix_compute_As_plus_e_60(
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 (*matrix_A)[3U],
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *s_as_ntt,
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *error_as_ntt,
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U]) {
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 result[3U];
+  for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+    result[i] = libcrux_ml_kem_polynomial_ZERO_89_ea();
+  }
+  for (size_t i0 = (size_t)0U;
+       i0 < Eurydice_slice_len(
+                Eurydice_array_to_slice(
+                    (size_t)3U, matrix_A,
+                    libcrux_ml_kem_polynomial_PolynomialRingElement_f0[3U]),
+                libcrux_ml_kem_polynomial_PolynomialRingElement_f0[3U]);
+       i0++) {
+    size_t i1 = i0;
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *row = matrix_A[i1];
+    for (size_t i = (size_t)0U;
+         i < Eurydice_slice_len(
+                 Eurydice_array_to_slice(
+                     (size_t)3U, row,
+                     libcrux_ml_kem_polynomial_PolynomialRingElement_f0),
+                 libcrux_ml_kem_polynomial_PolynomialRingElement_f0);
+         i++) {
+      size_t j = i;
+      libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *matrix_element =
+          &row[j];
+      libcrux_ml_kem_polynomial_PolynomialRingElement_f0 product =
+          libcrux_ml_kem_polynomial_ntt_multiply_89_2a(matrix_element,
+                                                       &s_as_ntt[j]);
+      libcrux_ml_kem_polynomial_add_to_ring_element_89_84(&result[i1],
+                                                          &product);
+    }
+    libcrux_ml_kem_polynomial_add_standard_error_reduce_89_03(
+        &result[i1], &error_as_ntt[i1]);
+  }
+  memcpy(
+      ret, result,
+      (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.serialize.serialize_uncompressed_ring_element with types
+libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics
+
+*/
+static KRML_MUSTINLINE void
+libcrux_ml_kem_serialize_serialize_uncompressed_ring_element_5b(
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *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_vector_type_PortableVector coefficient =
+        libcrux_ml_kem_vector_traits_to_unsigned_representative_db(
+            re->coefficients[i0]);
+    uint8_t bytes[24U];
+    libcrux_ml_kem_vector_portable_serialize_12_0d(coefficient, bytes);
+    Eurydice_slice uu____0 = Eurydice_array_to_subslice2(
+        serialized, (size_t)24U * i0, (size_t)24U * i0 + (size_t)24U, uint8_t);
+    Eurydice_slice_copy(
+        uu____0, Eurydice_array_to_slice((size_t)24U, bytes, uint8_t), uint8_t);
+  }
+  memcpy(ret, serialized, (size_t)384U * sizeof(uint8_t));
+}
+
+/**
+ Call [`serialize_uncompressed_ring_element`] for each ring element.
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.ind_cpa.serialize_secret_key
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+- K= 3
+- OUT_LEN= 1152
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_serialize_secret_key_b5(
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *key,
+    uint8_t ret[1152U]) {
+  uint8_t out[1152U] = {0U};
+  for (size_t i = (size_t)0U;
+       i < Eurydice_slice_len(
+               Eurydice_array_to_slice(
+                   (size_t)3U, key,
+                   libcrux_ml_kem_polynomial_PolynomialRingElement_f0),
+               libcrux_ml_kem_polynomial_PolynomialRingElement_f0);
+       i++) {
+    size_t i0 = i;
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re = key[i0];
+    Eurydice_slice uu____0 = Eurydice_array_to_subslice2(
+        out, i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT,
+        (i0 + (size_t)1U) * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT,
+        uint8_t);
+    uint8_t ret0[384U];
+    libcrux_ml_kem_serialize_serialize_uncompressed_ring_element_5b(&re, ret0);
+    Eurydice_slice_copy(
+        uu____0, Eurydice_array_to_slice((size_t)384U, ret0, uint8_t), uint8_t);
+  }
+  memcpy(ret, out, (size_t)1152U * sizeof(uint8_t));
+}
+
+/**
+ Concatenate `t` and `ρ` into the public key.
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.ind_cpa.serialize_public_key
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+- K= 3
+- RANKED_BYTES_PER_RING_ELEMENT= 1152
+- PUBLIC_KEY_SIZE= 1184
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_serialize_public_key_79(
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *t_as_ntt,
+    Eurydice_slice seed_for_a, uint8_t ret[1184U]) {
+  uint8_t public_key_serialized[1184U] = {0U};
+  Eurydice_slice uu____0 = Eurydice_array_to_subslice2(
+      public_key_serialized, (size_t)0U, (size_t)1152U, uint8_t);
+  uint8_t ret0[1152U];
+  libcrux_ml_kem_ind_cpa_serialize_secret_key_b5(t_as_ntt, ret0);
+  Eurydice_slice_copy(
+      uu____0, Eurydice_array_to_slice((size_t)1152U, ret0, uint8_t), uint8_t);
+  Eurydice_slice_copy(
+      Eurydice_array_to_subslice_from((size_t)1184U, public_key_serialized,
+                                      (size_t)1152U, uint8_t, size_t),
+      seed_for_a, uint8_t);
+  memcpy(ret, public_key_serialized, (size_t)1184U * sizeof(uint8_t));
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector,
+libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]],
+libcrux_ml_kem_variant_MlKem with const generics
+- K= 3
+- PRIVATE_KEY_SIZE= 1152
+- PUBLIC_KEY_SIZE= 1184
+- RANKED_BYTES_PER_RING_ELEMENT= 1152
+- ETA1= 2
+- ETA1_RANDOMNESS_SIZE= 128
+*/
+static inline libcrux_ml_kem_utils_extraction_helper_Keypair768
+libcrux_ml_kem_ind_cpa_generate_keypair_fc(Eurydice_slice key_generation_seed) {
+  uint8_t hashed[64U];
+  libcrux_ml_kem_variant_cpa_keygen_seed_d8_0e(key_generation_seed, hashed);
+  Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at(
+      Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), (size_t)32U,
+      uint8_t, Eurydice_slice_uint8_t_x2);
+  Eurydice_slice seed_for_A0 = uu____0.fst;
+  Eurydice_slice seed_for_secret_and_error = uu____0.snd;
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 A_transpose[3U][3U];
+  uint8_t ret[34U];
+  libcrux_ml_kem_utils_into_padded_array_ea1(seed_for_A0, ret);
+  libcrux_ml_kem_matrix_sample_matrix_A_38(ret, true, A_transpose);
+  uint8_t prf_input[33U];
+  libcrux_ml_kem_utils_into_padded_array_ea2(seed_for_secret_and_error,
+                                             prf_input);
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_prf_input0[33U];
+  memcpy(copy_of_prf_input0, prf_input, (size_t)33U * sizeof(uint8_t));
+  tuple_b0 uu____2 = libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_fc(
+      copy_of_prf_input0, 0U);
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 secret_as_ntt[3U];
+  memcpy(
+      secret_as_ntt, uu____2.fst,
+      (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+  uint8_t domain_separator = uu____2.snd;
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_prf_input[33U];
+  memcpy(copy_of_prf_input, prf_input, (size_t)33U * sizeof(uint8_t));
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 error_as_ntt[3U];
+  memcpy(
+      error_as_ntt,
+      libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_fc(copy_of_prf_input,
+                                                           domain_separator)
+          .fst,
+      (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 t_as_ntt[3U];
+  libcrux_ml_kem_matrix_compute_As_plus_e_60(A_transpose, secret_as_ntt,
+                                             error_as_ntt, t_as_ntt);
+  uint8_t seed_for_A[32U];
+  Result_00 dst;
+  Eurydice_slice_to_array2(&dst, seed_for_A0, Eurydice_slice, uint8_t[32U]);
+  unwrap_41_83(dst, seed_for_A);
+  uint8_t public_key_serialized[1184U];
+  libcrux_ml_kem_ind_cpa_serialize_public_key_79(
+      t_as_ntt, Eurydice_array_to_slice((size_t)32U, seed_for_A, uint8_t),
+      public_key_serialized);
+  uint8_t secret_key_serialized[1152U];
+  libcrux_ml_kem_ind_cpa_serialize_secret_key_b5(secret_as_ntt,
+                                                 secret_key_serialized);
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_secret_key_serialized[1152U];
+  memcpy(copy_of_secret_key_serialized, secret_key_serialized,
+         (size_t)1152U * sizeof(uint8_t));
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_public_key_serialized[1184U];
+  memcpy(copy_of_public_key_serialized, public_key_serialized,
+         (size_t)1184U * sizeof(uint8_t));
+  libcrux_ml_kem_utils_extraction_helper_Keypair768 lit;
+  memcpy(lit.fst, copy_of_secret_key_serialized,
+         (size_t)1152U * sizeof(uint8_t));
+  memcpy(lit.snd, copy_of_public_key_serialized,
+         (size_t)1184U * sizeof(uint8_t));
+  return lit;
+}
+
+/**
+ Serialize the secret key.
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key
+with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]]
+with const generics
+- K= 3
+- SERIALIZED_KEY_LEN= 2400
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_serialize_kem_secret_key_48(
+    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;
+  Eurydice_slice_copy(
+      Eurydice_array_to_subslice2(
+          uu____0, uu____1, uu____2 + Eurydice_slice_len(private_key, uint8_t),
+          uint8_t),
+      private_key, uint8_t);
+  pointer = pointer + Eurydice_slice_len(private_key, uint8_t);
+  uint8_t *uu____3 = out;
+  size_t uu____4 = pointer;
+  size_t uu____5 = pointer;
+  Eurydice_slice_copy(
+      Eurydice_array_to_subslice2(
+          uu____3, uu____4, uu____5 + Eurydice_slice_len(public_key, uint8_t),
+          uint8_t),
+      public_key, uint8_t);
+  pointer = pointer + Eurydice_slice_len(public_key, uint8_t);
+  Eurydice_slice uu____6 = Eurydice_array_to_subslice2(
+      out, pointer, pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t);
+  uint8_t ret0[32U];
+  libcrux_ml_kem_hash_functions_portable_H_f1_1a(public_key, ret0);
+  Eurydice_slice_copy(
+      uu____6, Eurydice_array_to_slice((size_t)32U, ret0, uint8_t), uint8_t);
+  pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE;
+  uint8_t *uu____7 = out;
+  size_t uu____8 = pointer;
+  size_t uu____9 = pointer;
+  Eurydice_slice_copy(
+      Eurydice_array_to_subslice2(
+          uu____7, uu____8,
+          uu____9 + Eurydice_slice_len(implicit_rejection_value, uint8_t),
+          uint8_t),
+      implicit_rejection_value, uint8_t);
+  memcpy(ret, out, (size_t)2400U * sizeof(uint8_t));
+}
+
+/**
+ Packed API
+
+ Generate a key pair.
+
+ Depending on the `Vector` and `Hasher` used, this requires different hardware
+ features
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.ind_cca.generate_keypair
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector,
+libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]],
+libcrux_ml_kem_variant_MlKem with const generics
+- K= 3
+- CPA_PRIVATE_KEY_SIZE= 1152
+- PRIVATE_KEY_SIZE= 2400
+- PUBLIC_KEY_SIZE= 1184
+- BYTES_PER_RING_ELEMENT= 1152
+- ETA1= 2
+- ETA1_RANDOMNESS_SIZE= 128
+*/
+static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair
+libcrux_ml_kem_ind_cca_generate_keypair_8c(uint8_t randomness[64U]) {
+  Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice2(
+      randomness, (size_t)0U,
+      LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t);
+  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);
+  libcrux_ml_kem_utils_extraction_helper_Keypair768 uu____0 =
+      libcrux_ml_kem_ind_cpa_generate_keypair_fc(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));
+  uint8_t secret_key_serialized[2400U];
+  libcrux_ml_kem_ind_cca_serialize_kem_secret_key_48(
+      Eurydice_array_to_slice((size_t)1152U, ind_cpa_private_key, uint8_t),
+      Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t),
+      implicit_rejection_value, secret_key_serialized);
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_secret_key_serialized[2400U];
+  memcpy(copy_of_secret_key_serialized, secret_key_serialized,
+         (size_t)2400U * sizeof(uint8_t));
+  libcrux_ml_kem_types_MlKemPrivateKey_55 private_key =
+      libcrux_ml_kem_types_from_05_f2(copy_of_secret_key_serialized);
+  libcrux_ml_kem_types_MlKemPrivateKey_55 uu____2 = private_key;
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_public_key[1184U];
+  memcpy(copy_of_public_key, public_key, (size_t)1184U * sizeof(uint8_t));
+  return libcrux_ml_kem_types_from_17_35(
+      uu____2, libcrux_ml_kem_types_from_b6_da(copy_of_public_key));
+}
+
+/**
+ Portable generate key pair.
+*/
+/**
+A monomorphic instance of
+libcrux_ml_kem.ind_cca.instantiations.portable.generate_keypair with const
+generics
+- K= 3
+- CPA_PRIVATE_KEY_SIZE= 1152
+- PRIVATE_KEY_SIZE= 2400
+- PUBLIC_KEY_SIZE= 1184
+- BYTES_PER_RING_ELEMENT= 1152
+- ETA1= 2
+- ETA1_RANDOMNESS_SIZE= 128
+*/
+static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair
+libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair_d5(
+    uint8_t randomness[64U]) {
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_randomness[64U];
+  memcpy(copy_of_randomness, randomness, (size_t)64U * sizeof(uint8_t));
+  return libcrux_ml_kem_ind_cca_generate_keypair_8c(copy_of_randomness);
+}
+
+/**
+ Generate ML-KEM 768 Key Pair
+*/
+static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair
+libcrux_ml_kem_mlkem768_portable_generate_key_pair(uint8_t randomness[64U]) {
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_randomness[64U];
+  memcpy(copy_of_randomness, randomness, (size_t)64U * sizeof(uint8_t));
+  return libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair_d5(
+      copy_of_randomness);
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::variant::Variant for
+libcrux_ml_kem::variant::Kyber)}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.variant.kdf_33
+with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]]
+with const generics
+- K= 3
+- CIPHERTEXT_SIZE= 1088
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_variant_kdf_33_f0(
+    Eurydice_slice shared_secret,
+    libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) {
+  uint8_t kdf_input[64U];
+  libcrux_ml_kem_utils_into_padded_array_ea(shared_secret, kdf_input);
+  Eurydice_slice uu____0 = Eurydice_array_to_subslice_from(
+      (size_t)64U, kdf_input, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t,
+      size_t);
+  uint8_t ret0[32U];
+  libcrux_ml_kem_hash_functions_portable_H_f1_1a(
+      Eurydice_array_to_slice((size_t)1088U,
+                              libcrux_ml_kem_types_as_slice_d4_1d(ciphertext),
+                              uint8_t),
+      ret0);
+  Eurydice_slice_copy(
+      uu____0, Eurydice_array_to_slice((size_t)32U, ret0, uint8_t), uint8_t);
+  uint8_t ret1[32U];
+  libcrux_ml_kem_hash_functions_portable_PRF_f1_ee(
+      Eurydice_array_to_slice((size_t)64U, kdf_input, uint8_t), ret1);
+  memcpy(ret, ret1, (size_t)32U * sizeof(uint8_t));
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.ind_cca.decapsulate
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector,
+libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]],
+libcrux_ml_kem_variant_Kyber with const generics
+- K= 3
+- SECRET_KEY_SIZE= 2400
+- CPA_SECRET_KEY_SIZE= 1152
+- PUBLIC_KEY_SIZE= 1184
+- CIPHERTEXT_SIZE= 1088
+- T_AS_NTT_ENCODED_SIZE= 1152
+- C1_SIZE= 960
+- C2_SIZE= 128
+- VECTOR_U_COMPRESSION_FACTOR= 10
+- VECTOR_V_COMPRESSION_FACTOR= 4
+- C1_BLOCK_SIZE= 320
+- ETA1= 2
+- ETA1_RANDOMNESS_SIZE= 128
+- ETA2= 2
+- ETA2_RANDOMNESS_SIZE= 128
+- IMPLICIT_REJECTION_HASH_INPUT_SIZE= 1120
+*/
+static inline void libcrux_ml_kem_ind_cca_decapsulate_700(
+    libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key,
+    libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) {
+  Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at(
+      Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t),
+      (size_t)1152U, uint8_t, Eurydice_slice_uint8_t_x2);
+  Eurydice_slice ind_cpa_secret_key = uu____0.fst;
+  Eurydice_slice secret_key0 = uu____0.snd;
+  Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at(
+      secret_key0, (size_t)1184U, uint8_t, Eurydice_slice_uint8_t_x2);
+  Eurydice_slice ind_cpa_public_key = uu____1.fst;
+  Eurydice_slice secret_key = uu____1.snd;
+  Eurydice_slice_uint8_t_x2 uu____2 = Eurydice_slice_split_at(
+      secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t,
+      Eurydice_slice_uint8_t_x2);
+  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_43(ind_cpa_secret_key, ciphertext->value,
+                                    decrypted);
+  uint8_t to_hash0[64U];
+  libcrux_ml_kem_utils_into_padded_array_ea(
+      Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t), to_hash0);
+  Eurydice_slice_copy(
+      Eurydice_array_to_subslice_from(
+          (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE,
+          uint8_t, size_t),
+      ind_cpa_public_key_hash, uint8_t);
+  uint8_t hashed[64U];
+  libcrux_ml_kem_hash_functions_portable_G_f1_e4(
+      Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t), hashed);
+  Eurydice_slice_uint8_t_x2 uu____3 = Eurydice_slice_split_at(
+      Eurydice_array_to_slice((size_t)64U, hashed, uint8_t),
+      LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t,
+      Eurydice_slice_uint8_t_x2);
+  Eurydice_slice shared_secret0 = uu____3.fst;
+  Eurydice_slice pseudorandomness = uu____3.snd;
+  uint8_t to_hash[1120U];
+  libcrux_ml_kem_utils_into_padded_array_ea0(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_copy(uu____4, libcrux_ml_kem_types_as_ref_00_24(ciphertext),
+                      uint8_t);
+  uint8_t implicit_rejection_shared_secret0[32U];
+  libcrux_ml_kem_hash_functions_portable_PRF_f1_ee(
+      Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t),
+      implicit_rejection_shared_secret0);
+  Eurydice_slice uu____5 = ind_cpa_public_key;
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_decrypted[32U];
+  memcpy(copy_of_decrypted, decrypted, (size_t)32U * sizeof(uint8_t));
+  uint8_t expected_ciphertext[1088U];
+  libcrux_ml_kem_ind_cpa_encrypt_60(uu____5, copy_of_decrypted,
+                                    pseudorandomness, expected_ciphertext);
+  uint8_t implicit_rejection_shared_secret[32U];
+  libcrux_ml_kem_variant_kdf_33_f0(
+      Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret0,
+                              uint8_t),
+      ciphertext, implicit_rejection_shared_secret);
+  uint8_t shared_secret[32U];
+  libcrux_ml_kem_variant_kdf_33_f0(shared_secret0, ciphertext, shared_secret);
+  uint8_t ret0[32U];
+  libcrux_ml_kem_constant_time_ops_compare_ciphertexts_select_shared_secret_in_constant_time(
+      libcrux_ml_kem_types_as_ref_00_24(ciphertext),
+      Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, uint8_t),
+      Eurydice_array_to_slice((size_t)32U, shared_secret, uint8_t),
+      Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret,
+                              uint8_t),
+      ret0);
+  memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t));
+}
+
+/**
+ Portable decapsulate
+*/
+/**
+A monomorphic instance of
+libcrux_ml_kem.ind_cca.instantiations.portable.kyber_decapsulate with const
+generics
+- K= 3
+- SECRET_KEY_SIZE= 2400
+- CPA_SECRET_KEY_SIZE= 1152
+- PUBLIC_KEY_SIZE= 1184
+- CIPHERTEXT_SIZE= 1088
+- T_AS_NTT_ENCODED_SIZE= 1152
+- C1_SIZE= 960
+- C2_SIZE= 128
+- VECTOR_U_COMPRESSION_FACTOR= 10
+- VECTOR_V_COMPRESSION_FACTOR= 4
+- C1_BLOCK_SIZE= 320
+- ETA1= 2
+- ETA1_RANDOMNESS_SIZE= 128
+- ETA2= 2
+- ETA2_RANDOMNESS_SIZE= 128
+- IMPLICIT_REJECTION_HASH_INPUT_SIZE= 1120
+*/
+static inline void
+libcrux_ml_kem_ind_cca_instantiations_portable_kyber_decapsulate_fc(
+    libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key,
+    libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) {
+  libcrux_ml_kem_ind_cca_decapsulate_700(private_key, ciphertext, ret);
+}
+
+/**
+ Decapsulate Kyber 768
+
+ Generates an [`MlKemSharedSecret`].
+ The input is a reference to an [`MlKem768PrivateKey`] and an
+ [`MlKem768Ciphertext`].
+*/
+static inline void libcrux_ml_kem_mlkem768_portable_kyber_decapsulate(
+    libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key,
+    libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) {
+  libcrux_ml_kem_ind_cca_instantiations_portable_kyber_decapsulate_fc(
+      private_key, ciphertext, ret);
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::variant::Variant for
+libcrux_ml_kem::variant::Kyber)}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.variant.entropy_preprocess_33
+with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]]
+with const generics
+- K= 3
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_variant_entropy_preprocess_33_8a(
+    Eurydice_slice randomness, uint8_t ret[32U]) {
+  libcrux_ml_kem_hash_functions_portable_H_f1_1a(randomness, ret);
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.ind_cca.encapsulate
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector,
+libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]],
+libcrux_ml_kem_variant_Kyber with const generics
+- K= 3
+- CIPHERTEXT_SIZE= 1088
+- PUBLIC_KEY_SIZE= 1184
+- T_AS_NTT_ENCODED_SIZE= 1152
+- C1_SIZE= 960
+- C2_SIZE= 128
+- VECTOR_U_COMPRESSION_FACTOR= 10
+- VECTOR_V_COMPRESSION_FACTOR= 4
+- VECTOR_U_BLOCK_LEN= 320
+- ETA1= 2
+- ETA1_RANDOMNESS_SIZE= 128
+- ETA2= 2
+- ETA2_RANDOMNESS_SIZE= 128
+*/
+static inline tuple_3c libcrux_ml_kem_ind_cca_encapsulate_cd0(
+    libcrux_ml_kem_types_MlKemPublicKey_15 *public_key,
+    uint8_t randomness[32U]) {
+  uint8_t randomness0[32U];
+  libcrux_ml_kem_variant_entropy_preprocess_33_8a(
+      Eurydice_array_to_slice((size_t)32U, randomness, uint8_t), randomness0);
+  uint8_t to_hash[64U];
+  libcrux_ml_kem_utils_into_padded_array_ea(
+      Eurydice_array_to_slice((size_t)32U, randomness0, uint8_t), 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);
+  uint8_t ret[32U];
+  libcrux_ml_kem_hash_functions_portable_H_f1_1a(
+      Eurydice_array_to_slice((size_t)1184U,
+                              libcrux_ml_kem_types_as_slice_cb_50(public_key),
+                              uint8_t),
+      ret);
+  Eurydice_slice_copy(
+      uu____0, Eurydice_array_to_slice((size_t)32U, ret, uint8_t), uint8_t);
+  uint8_t hashed[64U];
+  libcrux_ml_kem_hash_functions_portable_G_f1_e4(
+      Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t), hashed);
+  Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at(
+      Eurydice_array_to_slice((size_t)64U, hashed, uint8_t),
+      LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t,
+      Eurydice_slice_uint8_t_x2);
+  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_as_slice_cb_50(public_key), uint8_t);
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_randomness[32U];
+  memcpy(copy_of_randomness, randomness0, (size_t)32U * sizeof(uint8_t));
+  uint8_t ciphertext[1088U];
+  libcrux_ml_kem_ind_cpa_encrypt_60(uu____2, copy_of_randomness,
+                                    pseudorandomness, ciphertext);
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_ciphertext[1088U];
+  memcpy(copy_of_ciphertext, ciphertext, (size_t)1088U * sizeof(uint8_t));
+  libcrux_ml_kem_mlkem768_MlKem768Ciphertext ciphertext0 =
+      libcrux_ml_kem_types_from_01_9f(copy_of_ciphertext);
+  uint8_t shared_secret_array[32U];
+  libcrux_ml_kem_variant_kdf_33_f0(shared_secret, &ciphertext0,
+                                   shared_secret_array);
+  libcrux_ml_kem_mlkem768_MlKem768Ciphertext uu____5 = ciphertext0;
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_shared_secret_array[32U];
+  memcpy(copy_of_shared_secret_array, shared_secret_array,
+         (size_t)32U * sizeof(uint8_t));
+  tuple_3c lit;
+  lit.fst = uu____5;
+  memcpy(lit.snd, copy_of_shared_secret_array, (size_t)32U * sizeof(uint8_t));
+  return lit;
+}
+
+/**
+ Portable encapsulate
+*/
+/**
+A monomorphic instance of
+libcrux_ml_kem.ind_cca.instantiations.portable.kyber_encapsulate with const
+generics
+- K= 3
+- CIPHERTEXT_SIZE= 1088
+- PUBLIC_KEY_SIZE= 1184
+- T_AS_NTT_ENCODED_SIZE= 1152
+- C1_SIZE= 960
+- C2_SIZE= 128
+- VECTOR_U_COMPRESSION_FACTOR= 10
+- VECTOR_V_COMPRESSION_FACTOR= 4
+- VECTOR_U_BLOCK_LEN= 320
+- ETA1= 2
+- ETA1_RANDOMNESS_SIZE= 128
+- ETA2= 2
+- ETA2_RANDOMNESS_SIZE= 128
+*/
+static inline tuple_3c
+libcrux_ml_kem_ind_cca_instantiations_portable_kyber_encapsulate_7a(
+    libcrux_ml_kem_types_MlKemPublicKey_15 *public_key,
+    uint8_t randomness[32U]) {
+  libcrux_ml_kem_types_MlKemPublicKey_15 *uu____0 = public_key;
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_randomness[32U];
+  memcpy(copy_of_randomness, randomness, (size_t)32U * sizeof(uint8_t));
+  return libcrux_ml_kem_ind_cca_encapsulate_cd0(uu____0, copy_of_randomness);
+}
+
+/**
+ Encapsulate Kyber 768
+
+ Generates an ([`MlKem768Ciphertext`], [`MlKemSharedSecret`]) tuple.
+ The input is a reference to an [`MlKem768PublicKey`] and [`SHARED_SECRET_SIZE`]
+ bytes of `randomness`.
+*/
+static inline tuple_3c libcrux_ml_kem_mlkem768_portable_kyber_encapsulate(
+    libcrux_ml_kem_types_MlKemPublicKey_15 *public_key,
+    uint8_t randomness[32U]) {
+  libcrux_ml_kem_types_MlKemPublicKey_15 *uu____0 = public_key;
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_randomness[32U];
+  memcpy(copy_of_randomness, randomness, (size_t)32U * sizeof(uint8_t));
+  return libcrux_ml_kem_ind_cca_instantiations_portable_kyber_encapsulate_7a(
+      uu____0, copy_of_randomness);
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::variant::Variant for
+libcrux_ml_kem::variant::Kyber)}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.variant.cpa_keygen_seed_33
+with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]]
+with const generics
+- K= 3
+*/
+static KRML_MUSTINLINE void libcrux_ml_kem_variant_cpa_keygen_seed_33_b6(
+    Eurydice_slice key_generation_seed, uint8_t ret[64U]) {
+  libcrux_ml_kem_hash_functions_portable_G_f1_e4(key_generation_seed, ret);
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector,
+libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]],
+libcrux_ml_kem_variant_Kyber with const generics
+- K= 3
+- PRIVATE_KEY_SIZE= 1152
+- PUBLIC_KEY_SIZE= 1184
+- RANKED_BYTES_PER_RING_ELEMENT= 1152
+- ETA1= 2
+- ETA1_RANDOMNESS_SIZE= 128
+*/
+static inline libcrux_ml_kem_utils_extraction_helper_Keypair768
+libcrux_ml_kem_ind_cpa_generate_keypair_fc0(
+    Eurydice_slice key_generation_seed) {
+  uint8_t hashed[64U];
+  libcrux_ml_kem_variant_cpa_keygen_seed_33_b6(key_generation_seed, hashed);
+  Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at(
+      Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), (size_t)32U,
+      uint8_t, Eurydice_slice_uint8_t_x2);
+  Eurydice_slice seed_for_A0 = uu____0.fst;
+  Eurydice_slice seed_for_secret_and_error = uu____0.snd;
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 A_transpose[3U][3U];
+  uint8_t ret[34U];
+  libcrux_ml_kem_utils_into_padded_array_ea1(seed_for_A0, ret);
+  libcrux_ml_kem_matrix_sample_matrix_A_38(ret, true, A_transpose);
+  uint8_t prf_input[33U];
+  libcrux_ml_kem_utils_into_padded_array_ea2(seed_for_secret_and_error,
+                                             prf_input);
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_prf_input0[33U];
+  memcpy(copy_of_prf_input0, prf_input, (size_t)33U * sizeof(uint8_t));
+  tuple_b0 uu____2 = libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_fc(
+      copy_of_prf_input0, 0U);
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 secret_as_ntt[3U];
+  memcpy(
+      secret_as_ntt, uu____2.fst,
+      (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+  uint8_t domain_separator = uu____2.snd;
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_prf_input[33U];
+  memcpy(copy_of_prf_input, prf_input, (size_t)33U * sizeof(uint8_t));
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 error_as_ntt[3U];
+  memcpy(
+      error_as_ntt,
+      libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_fc(copy_of_prf_input,
+                                                           domain_separator)
+          .fst,
+      (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 t_as_ntt[3U];
+  libcrux_ml_kem_matrix_compute_As_plus_e_60(A_transpose, secret_as_ntt,
+                                             error_as_ntt, t_as_ntt);
+  uint8_t seed_for_A[32U];
+  Result_00 dst;
+  Eurydice_slice_to_array2(&dst, seed_for_A0, Eurydice_slice, uint8_t[32U]);
+  unwrap_41_83(dst, seed_for_A);
+  uint8_t public_key_serialized[1184U];
+  libcrux_ml_kem_ind_cpa_serialize_public_key_79(
+      t_as_ntt, Eurydice_array_to_slice((size_t)32U, seed_for_A, uint8_t),
+      public_key_serialized);
+  uint8_t secret_key_serialized[1152U];
+  libcrux_ml_kem_ind_cpa_serialize_secret_key_b5(secret_as_ntt,
+                                                 secret_key_serialized);
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_secret_key_serialized[1152U];
+  memcpy(copy_of_secret_key_serialized, secret_key_serialized,
+         (size_t)1152U * sizeof(uint8_t));
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_public_key_serialized[1184U];
+  memcpy(copy_of_public_key_serialized, public_key_serialized,
+         (size_t)1184U * sizeof(uint8_t));
+  libcrux_ml_kem_utils_extraction_helper_Keypair768 lit;
+  memcpy(lit.fst, copy_of_secret_key_serialized,
+         (size_t)1152U * sizeof(uint8_t));
+  memcpy(lit.snd, copy_of_public_key_serialized,
+         (size_t)1184U * sizeof(uint8_t));
+  return lit;
+}
+
+/**
+ Packed API
+
+ Generate a key pair.
+
+ Depending on the `Vector` and `Hasher` used, this requires different hardware
+ features
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.ind_cca.generate_keypair
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector,
+libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]],
+libcrux_ml_kem_variant_Kyber with const generics
+- K= 3
+- CPA_PRIVATE_KEY_SIZE= 1152
+- PRIVATE_KEY_SIZE= 2400
+- PUBLIC_KEY_SIZE= 1184
+- BYTES_PER_RING_ELEMENT= 1152
+- ETA1= 2
+- ETA1_RANDOMNESS_SIZE= 128
+*/
+static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair
+libcrux_ml_kem_ind_cca_generate_keypair_8c0(uint8_t randomness[64U]) {
+  Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice2(
+      randomness, (size_t)0U,
+      LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t);
+  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);
+  libcrux_ml_kem_utils_extraction_helper_Keypair768 uu____0 =
+      libcrux_ml_kem_ind_cpa_generate_keypair_fc0(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));
+  uint8_t secret_key_serialized[2400U];
+  libcrux_ml_kem_ind_cca_serialize_kem_secret_key_48(
+      Eurydice_array_to_slice((size_t)1152U, ind_cpa_private_key, uint8_t),
+      Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t),
+      implicit_rejection_value, secret_key_serialized);
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_secret_key_serialized[2400U];
+  memcpy(copy_of_secret_key_serialized, secret_key_serialized,
+         (size_t)2400U * sizeof(uint8_t));
+  libcrux_ml_kem_types_MlKemPrivateKey_55 private_key =
+      libcrux_ml_kem_types_from_05_f2(copy_of_secret_key_serialized);
+  libcrux_ml_kem_types_MlKemPrivateKey_55 uu____2 = private_key;
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_public_key[1184U];
+  memcpy(copy_of_public_key, public_key, (size_t)1184U * sizeof(uint8_t));
+  return libcrux_ml_kem_types_from_17_35(
+      uu____2, libcrux_ml_kem_types_from_b6_da(copy_of_public_key));
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.ind_cca.instantiations.portable.kyber_generate_keypair with const
+generics
+- K= 3
+- CPA_PRIVATE_KEY_SIZE= 1152
+- PRIVATE_KEY_SIZE= 2400
+- PUBLIC_KEY_SIZE= 1184
+- BYTES_PER_RING_ELEMENT= 1152
+- ETA1= 2
+- ETA1_RANDOMNESS_SIZE= 128
+*/
+static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair
+libcrux_ml_kem_ind_cca_instantiations_portable_kyber_generate_keypair_9b(
+    uint8_t randomness[64U]) {
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_randomness[64U];
+  memcpy(copy_of_randomness, randomness, (size_t)64U * sizeof(uint8_t));
+  return libcrux_ml_kem_ind_cca_generate_keypair_8c0(copy_of_randomness);
+}
+
+/**
+ Generate Kyber 768 Key Pair
+*/
+static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair
+libcrux_ml_kem_mlkem768_portable_kyber_generate_key_pair(
+    uint8_t randomness[64U]) {
+  /* Passing arrays by value in Rust generates a copy in C */
+  uint8_t copy_of_randomness[64U];
+  memcpy(copy_of_randomness, randomness, (size_t)64U * sizeof(uint8_t));
+  return libcrux_ml_kem_ind_cca_instantiations_portable_kyber_generate_keypair_9b(
+      copy_of_randomness);
+}
+
+/**
+ Validate an ML-KEM private key.
+
+ This implements the Hash check in 7.3 3.
+ Note that the size checks in 7.2 1 and 2 are covered by the `SECRET_KEY_SIZE`
+ and `CIPHERTEXT_SIZE` in the `private_key` and `ciphertext` types.
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key
+with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]]
+with const generics
+- K= 3
+- SECRET_KEY_SIZE= 2400
+- CIPHERTEXT_SIZE= 1088
+*/
+static KRML_MUSTINLINE bool libcrux_ml_kem_ind_cca_validate_private_key_e7(
+    libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key,
+    libcrux_ml_kem_mlkem768_MlKem768Ciphertext *_ciphertext) {
+  uint8_t t[32U];
+  libcrux_ml_kem_hash_functions_portable_H_f1_1a(
+      Eurydice_array_to_subslice2(private_key->value, (size_t)384U * (size_t)3U,
+                                  (size_t)768U * (size_t)3U + (size_t)32U,
+                                  uint8_t),
+      t);
+  Eurydice_slice expected = Eurydice_array_to_subslice2(
+      private_key->value, (size_t)768U * (size_t)3U + (size_t)32U,
+      (size_t)768U * (size_t)3U + (size_t)64U, uint8_t);
+  return core_array_equality___core__cmp__PartialEq__0___Slice_U____for__Array_T__N___3__eq(
+      (size_t)32U, t, &expected, uint8_t, uint8_t, bool);
+}
+
+/**
+ Portable private key validation
+*/
+/**
+A monomorphic instance of
+libcrux_ml_kem.ind_cca.instantiations.portable.validate_private_key with const
+generics
+- K= 3
+- SECRET_KEY_SIZE= 2400
+- CIPHERTEXT_SIZE= 1088
+*/
+static KRML_MUSTINLINE bool
+libcrux_ml_kem_ind_cca_instantiations_portable_validate_private_key_9c(
+    libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key,
+    libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext) {
+  return libcrux_ml_kem_ind_cca_validate_private_key_e7(private_key,
+                                                        ciphertext);
+}
+
+/**
+ Validate a private key.
+
+ Returns `true` if valid, and `false` otherwise.
+*/
+static inline bool libcrux_ml_kem_mlkem768_portable_validate_private_key(
+    libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key,
+    libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext) {
+  return libcrux_ml_kem_ind_cca_instantiations_portable_validate_private_key_9c(
+      private_key, ciphertext);
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.serialize.deserialize_ring_elements_reduced.closure with types
+libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics
+- PUBLIC_KEY_SIZE= 1184
+- K= 3
+*/
+static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_closure_cd0(
+    size_t _i) {
+  return libcrux_ml_kem_polynomial_ZERO_89_ea();
+}
+
+/**
+ This function deserializes ring elements and reduces the result by the field
+ modulus.
+
+ This function MUST NOT be used on secret inputs.
+*/
+/**
+A monomorphic instance of
+libcrux_ml_kem.serialize.deserialize_ring_elements_reduced with types
+libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics
+- PUBLIC_KEY_SIZE= 1184
+- K= 3
+*/
+static KRML_MUSTINLINE void
+libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_330(
+    Eurydice_slice public_key,
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U]) {
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 deserialized_pk[3U];
+  for (size_t i = (size_t)0U; i < (size_t)3U; i++) {
+    deserialized_pk[i] = libcrux_ml_kem_polynomial_ZERO_89_ea();
+  }
+  for (size_t i = (size_t)0U;
+       i < Eurydice_slice_len(public_key, uint8_t) /
+               LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT;
+       i++) {
+    size_t i0 = i;
+    Eurydice_slice ring_element = Eurydice_slice_subslice2(
+        public_key, i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT,
+        i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT +
+            LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT,
+        uint8_t);
+    libcrux_ml_kem_polynomial_PolynomialRingElement_f0 uu____0 =
+        libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element_4c(
+            ring_element);
+    deserialized_pk[i0] = uu____0;
+  }
+  memcpy(
+      ret, deserialized_pk,
+      (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+}
+
+/**
+ Validate an ML-KEM public key.
+
+ This implements the Modulus check in 7.2 2.
+ Note that the size check in 7.2 1 is covered by the `PUBLIC_KEY_SIZE` in the
+ `public_key` type.
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.ind_cca.validate_public_key
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+- K= 3
+- RANKED_BYTES_PER_RING_ELEMENT= 1152
+- PUBLIC_KEY_SIZE= 1184
+*/
+static KRML_MUSTINLINE bool libcrux_ml_kem_ind_cca_validate_public_key_19(
+    uint8_t *public_key) {
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 deserialized_pk[3U];
+  libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_330(
+      Eurydice_array_to_subslice_to((size_t)1184U, public_key, (size_t)1152U,
+                                    uint8_t, size_t),
+      deserialized_pk);
+  libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *uu____0 = deserialized_pk;
+  uint8_t public_key_serialized[1184U];
+  libcrux_ml_kem_ind_cpa_serialize_public_key_79(
+      uu____0,
+      Eurydice_array_to_subslice_from((size_t)1184U, public_key, (size_t)1152U,
+                                      uint8_t, size_t),
+      public_key_serialized);
+  return core_array_equality___core__cmp__PartialEq__Array_U__N___for__Array_T__N____eq(
+      (size_t)1184U, public_key, public_key_serialized, uint8_t, uint8_t, bool);
+}
+
+/**
+ Portable public key validation
+*/
+/**
+A monomorphic instance of
+libcrux_ml_kem.ind_cca.instantiations.portable.validate_public_key with const
+generics
+- K= 3
+- RANKED_BYTES_PER_RING_ELEMENT= 1152
+- PUBLIC_KEY_SIZE= 1184
+*/
+static KRML_MUSTINLINE bool
+libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key_4b(
+    uint8_t *public_key) {
+  return libcrux_ml_kem_ind_cca_validate_public_key_19(public_key);
+}
+
+/**
+ Validate a public key.
+
+ Returns `true` if valid, and `false` otherwise.
+*/
+static inline bool libcrux_ml_kem_mlkem768_portable_validate_public_key(
+    libcrux_ml_kem_types_MlKemPublicKey_15 *public_key) {
+  return libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key_4b(
+      public_key->value);
+}
+
+/**
+This function found in impl {(core::clone::Clone for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_vector_type_clone_3b(
+    libcrux_ml_kem_vector_portable_vector_type_PortableVector *self) {
+  return self[0U];
+}
+
+typedef int16_t libcrux_ml_kem_vector_portable_vector_type_FieldElement;
+
+typedef int16_t
+    libcrux_ml_kem_vector_portable_arithmetic_MontgomeryFieldElement;
+
+typedef int16_t
+    libcrux_ml_kem_vector_portable_arithmetic_FieldElementTimesMontgomeryR;
+
+#if defined(__cplusplus)
+}
+#endif
+
+#define __libcrux_mlkem768_portable_H_DEFINED
+#endif
+
+
+/* rename some types to be a bit more ergonomic */
+#define libcrux_mlkem768_keypair libcrux_ml_kem_mlkem768_MlKem768KeyPair_s
+#define libcrux_mlkem768_pk_valid_result Option_92_s
+#define libcrux_mlkem768_pk libcrux_ml_kem_types_MlKemPublicKey_15_s
+#define libcrux_mlkem768_sk libcrux_ml_kem_types_MlKemPrivateKey_55_s
+#define libcrux_mlkem768_ciphertext libcrux_ml_kem_mlkem768_MlKem768Ciphertext_s
+#define libcrux_mlkem768_enc_result tuple_3c_s
+/* defines for PRNG inputs */
+#define LIBCRUX_ML_KEM_KEY_PAIR_PRNG_LEN 64
+#define LIBCRUX_ML_KEM_ENC_PRNG_LEN 32
diff --git a/usr.bin/ssh/mlkem768.sh b/usr.bin/ssh/mlkem768.sh
new file mode 100755 (executable)
index 0000000..bdac0a9
--- /dev/null
@@ -0,0 +1,148 @@
+#!/bin/sh
+#       $OpenBSD: mlkem768.sh,v 1.1 2024/09/02 12:13:56 djm Exp $
+#       Placed in the Public Domain.
+#
+
+WANT_LIBCRUX_REVISION="origin/main"
+
+FILES="
+       libcrux/libcrux-ml-kem/cg/eurydice_glue.h
+       libcrux/libcrux-ml-kem/cg/libcrux_core.h
+       libcrux/libcrux-ml-kem/cg/libcrux_ct_ops.h
+       libcrux/libcrux-ml-kem/cg/libcrux_sha3_portable.h
+       libcrux/libcrux-ml-kem/cg/libcrux_mlkem768_portable.h
+"
+
+START="$PWD"
+die() {
+       echo "$@" 1>&2
+       exit 1
+}
+
+set -xeuo pipefail
+test -d libcrux || git clone https://github.com/cryspen/libcrux
+cd libcrux
+test `git diff | wc -l` -ne 0 && die "tree has unstaged changes"
+git fetch
+git checkout -B extract 1>&2
+git reset --hard $WANT_LIBCRUX_REVISION 1>&2
+LIBCRUX_REVISION=`git rev-parse HEAD`
+set +x
+
+cd $START
+(
+echo -n '/*  $OpenBSD: mlkem768.sh,v 1.1 2024/09/02 12:13:56 djm Exp $ */'
+echo
+echo "/* Extracted from libcrux revision $LIBCRUX_REVISION */"
+echo
+echo '/*'
+cat libcrux/LICENSE-MIT | sed 's/^/ * /;s/ *$//'
+echo ' */'
+echo
+echo '#if !defined(__GNUC__) || (__GNUC__ < 2)'
+echo '# define __attribute__(x)'
+echo '#endif'
+echo '#define KRML_MUSTINLINE inline'
+echo '#define KRML_NOINLINE __attribute__((noinline, unused))'
+echo '#define KRML_HOST_EPRINTF(...)'
+echo '#define KRML_HOST_EXIT(x) fatal_f("internal error")'
+echo
+for i in $FILES; do
+       echo "/* from $i */"
+       # Changes to all files:
+       #  - remove all includes, we inline everything required.
+       #  - cleanup whitespace
+       sed -e "/#include/d" \
+           -e 's/[      ]*$//' \
+           $i | \
+       case "$i" in
+       # XXX per-file handling goes here.
+       # Default: pass through.
+       *)
+           cat
+           ;;
+       esac
+       echo
+done
+
+echo
+echo '/* rename some types to be a bit more ergonomic */'
+echo '#define libcrux_mlkem768_keypair libcrux_ml_kem_mlkem768_MlKem768KeyPair_s'
+echo '#define libcrux_mlkem768_pk_valid_result Option_92_s'
+echo '#define libcrux_mlkem768_pk libcrux_ml_kem_types_MlKemPublicKey_15_s'
+echo '#define libcrux_mlkem768_sk libcrux_ml_kem_types_MlKemPrivateKey_55_s'
+echo '#define libcrux_mlkem768_ciphertext libcrux_ml_kem_mlkem768_MlKem768Ciphertext_s'
+echo '#define libcrux_mlkem768_enc_result tuple_3c_s'
+) > libcrux_mlkem768_sha3.h_new
+
+# Do some checks on the resultant file
+
+cat > libcrux_mlkem768_sha3_check.c << _EOF
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <signal.h>
+#include <err.h>
+#include "crypto_api.h"
+#define fatal_f(x) exit(1)
+#include "libcrux_mlkem768_sha3.h_new"
+int main(void) {
+       struct libcrux_mlkem768_keypair keypair = {0};
+       struct libcrux_mlkem768_pk pk = {0};
+       struct libcrux_mlkem768_sk sk = {0};
+       struct libcrux_mlkem768_ciphertext ct = {0};
+       struct libcrux_mlkem768_enc_result enc_result = {0};
+       uint8_t kp_seed[64] = {0}, enc_seed[32] = {0};
+       uint8_t shared_key[crypto_kem_mlkem768_BYTES];
+
+       if (sizeof(keypair.pk.value) != crypto_kem_mlkem768_PUBLICKEYBYTES)
+               errx(1, "keypair.pk bad");
+       if (sizeof(keypair.sk.value) != crypto_kem_mlkem768_SECRETKEYBYTES)
+               errx(1, "keypair.sk bad");
+       if (sizeof(pk.value) != crypto_kem_mlkem768_PUBLICKEYBYTES)
+               errx(1, "pk bad");
+       if (sizeof(sk.value) != crypto_kem_mlkem768_SECRETKEYBYTES)
+               errx(1, "sk bad");
+       if (sizeof(ct.value) != crypto_kem_mlkem768_CIPHERTEXTBYTES)
+               errx(1, "ct bad");
+       if (sizeof(enc_result.fst.value) != crypto_kem_mlkem768_CIPHERTEXTBYTES)
+               errx(1, "enc_result ct bad");
+       if (sizeof(enc_result.snd) != crypto_kem_mlkem768_BYTES)
+               errx(1, "enc_result shared key bad");
+
+       keypair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(kp_seed);
+       if (!libcrux_ml_kem_mlkem768_portable_validate_public_key(&keypair.pk))
+               errx(1, "valid smoke failed");
+       enc_result = libcrux_ml_kem_mlkem768_portable_encapsulate(&keypair.pk,
+           enc_seed);
+       libcrux_ml_kem_mlkem768_portable_decapsulate(&keypair.sk,
+           &enc_result.fst, shared_key);
+       if (memcmp(shared_key, enc_result.snd, sizeof(shared_key)) != 0)
+               errx(1, "smoke failed");
+       return 0;
+}
+_EOF
+cc -Wall -Wextra -Wno-unused-parameter -o libcrux_mlkem768_sha3_check \
+       libcrux_mlkem768_sha3_check.c
+./libcrux_mlkem768_sha3_check
+
+# Extract PRNG inputs; there's no nice #defines for these
+key_pair_rng_len=`sed -e '/^libcrux_ml_kem_mlkem768_portable_kyber_generate_key_pair[(]$/,/[)] {$/!d' < libcrux_mlkem768_sha3.h_new | grep 'uint8_t randomness\[[0-9]*U\][)]' | sed 's/.*randomness\[\([0-9]*\)U\].*/\1/'`
+enc_rng_len=`sed -e '/^static inline tuple_3c libcrux_ml_kem_mlkem768_portable_kyber_encapsulate[(]$/,/[)] {$/!d' < libcrux_mlkem768_sha3.h_new | grep 'uint8_t randomness\[[0-9]*U\][)]' | sed 's/.*randomness\[\([0-9]*\)U\].*/\1/'`
+test -z "$key_pair_rng_len" && die "couldn't find size of libcrux_ml_kem_mlkem768_portable_kyber_generate_key_pair randomness argument"
+test -z "$enc_rng_len" && die "couldn't find size of libcrux_ml_kem_mlkem768_portable_kyber_encapsulate randomness argument"
+
+(
+echo "/* defines for PRNG inputs */"
+echo "#define LIBCRUX_ML_KEM_KEY_PAIR_PRNG_LEN $key_pair_rng_len"
+echo "#define LIBCRUX_ML_KEM_ENC_PRNG_LEN $enc_rng_len"
+) >> libcrux_mlkem768_sha3.h_new
+
+mv libcrux_mlkem768_sha3.h_new libcrux_mlkem768_sha3.h
+rm libcrux_mlkem768_sha3_check libcrux_mlkem768_sha3_check.c
+echo 1>&2
+echo "libcrux_mlkem768_sha3.h OK" 1>&2
+
index 0ada9a5..255e37e 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor.c,v 1.240 2024/06/06 17:15:25 djm Exp $ */
+/* $OpenBSD: monitor.c,v 1.241 2024/09/02 12:13:56 djm Exp $ */
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
  * Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -1456,6 +1456,9 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor)
 #endif
        kex->kex[KEX_C25519_SHA256] = kex_gen_server;
        kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server;
+#ifdef WITH_MLKEM
+       kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_server;
+#endif
        kex->load_host_public_key=&get_hostkey_public_by_type;
        kex->load_host_private_key=&get_hostkey_private_by_type;
        kex->host_key_index=&get_hostkey_index;
index befc61c..e941c21 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keyscan.c,v 1.158 2024/06/14 00:25:25 djm Exp $ */
+/* $OpenBSD: ssh-keyscan.c,v 1.159 2024/09/02 12:13:56 djm Exp $ */
 /*
  * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
  *
@@ -277,6 +277,9 @@ keygrab_ssh2(con *c)
 #endif
        c->c_ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client;
        c->c_ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_client;
+#ifdef WITH_MLKEM
+       c->c_ssh->kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_client;
+#endif
        ssh_set_verify_host_key_callback(c->c_ssh, key_print_wrapper);
        /*
         * do the key-exchange until an error occurs or until
index e496403..9897bb8 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh_api.c,v 1.29 2024/05/17 00:30:24 djm Exp $ */
+/* $OpenBSD: ssh_api.c,v 1.30 2024/09/02 12:13:56 djm Exp $ */
 /*
  * Copyright (c) 2012 Markus Friedl.  All rights reserved.
  *
@@ -130,6 +130,9 @@ ssh_init(struct ssh **sshp, int is_server, struct kex_params *kex_params)
 #endif /* WITH_OPENSSL */
                ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_server;
                ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server;
+#ifdef WITH_MLKEM
+               ssh->kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_server;
+#endif
                ssh->kex->load_host_public_key=&_ssh_host_public_key;
                ssh->kex->load_host_private_key=&_ssh_host_private_key;
                ssh->kex->sign=&_ssh_host_key_sign;
@@ -146,6 +149,9 @@ ssh_init(struct ssh **sshp, int is_server, struct kex_params *kex_params)
 #endif /* WITH_OPENSSL */
                ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client;
                ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_client;
+#ifdef WITH_MLKEM
+               ssh->kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_client;
+#endif
                ssh->kex->verify_host_key =&_ssh_verify_host_key;
        }
        *sshp = ssh;
index 8e0b07e..0228cbc 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect2.c,v 1.373 2024/05/17 06:38:00 jsg Exp $ */
+/* $OpenBSD: sshconnect2.c,v 1.374 2024/09/02 12:13:56 djm Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  * Copyright (c) 2008 Damien Miller.  All rights reserved.
@@ -267,6 +267,9 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
 #endif
        ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client;
        ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_client;
+#ifdef WITH_MLKEM
+       ssh->kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_client;
+#endif
        ssh->kex->verify_host_key=&verify_host_key_callback;
 
        ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &ssh->kex->done);
index fcb690f..172e02b 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshd-session.c,v 1.6 2024/07/31 12:00:18 dlg Exp $ */
+/* $OpenBSD: sshd-session.c,v 1.7 2024/09/02 12:13:56 djm Exp $ */
 /*
  * SSH2 implementation:
  * Privilege Separation:
@@ -1334,6 +1334,7 @@ do_ssh2_kex(struct ssh *ssh)
 #endif
        kex->kex[KEX_C25519_SHA256] = kex_gen_server;
        kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server;
+       kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_server;
        kex->load_host_public_key=&get_hostkey_public_by_type;
        kex->load_host_private_key=&get_hostkey_private_by_type;
        kex->host_key_index=&get_hostkey_index;