You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nss/SOURCES/nss-3.101-replace-xyber_wit...

21478 lines
791 KiB

diff -up ./cmd/lib/secutil.c.mlkem ./cmd/lib/secutil.c
--- ./cmd/lib/secutil.c.mlkem 2024-10-31 14:54:15.444515725 -0700
+++ ./cmd/lib/secutil.c 2024-10-31 14:54:15.458515881 -0700
@@ -4179,43 +4179,40 @@ SECU_ParseSSLVersionRangeString(const ch
return SECSuccess;
}
+#define NAME_AND_LEN(s) sizeof(s)-1,s
+static const struct SSLNamedGroupString {
+ int len;
+ char *name;
+ SSLNamedGroup grp;
+} sslNamedGroupStringArray[] = {
+ { NAME_AND_LEN("P256"), ssl_grp_ec_secp256r1 },
+ { NAME_AND_LEN("P384"), ssl_grp_ec_secp384r1 },
+ { NAME_AND_LEN("P521"), ssl_grp_ec_secp521r1 },
+ { NAME_AND_LEN("x25519"), ssl_grp_ec_curve25519 },
+ { NAME_AND_LEN("FF2048"), ssl_grp_ffdhe_2048 },
+ { NAME_AND_LEN("FF3072"), ssl_grp_ffdhe_3072 },
+ { NAME_AND_LEN("FF4096"), ssl_grp_ffdhe_4096 },
+ { NAME_AND_LEN("FF6144"), ssl_grp_ffdhe_6144 },
+ { NAME_AND_LEN("FF8192"), ssl_grp_ffdhe_8192 },
+ { NAME_AND_LEN("mlkem768x25519"), ssl_grp_kem_mlkem768x25519 },
+ { NAME_AND_LEN("mlkem768secp256r1"), ssl_grp_kem_mlkem768secp256r1 },
+};
+
+static const size_t sslNamedGroupStringLen=PR_ARRAY_SIZE(sslNamedGroupStringArray);
+
+
static SSLNamedGroup
groupNameToNamedGroup(char *name)
{
- if (PL_strlen(name) == 4) {
- if (!strncmp(name, "P256", 4)) {
- return ssl_grp_ec_secp256r1;
- }
- if (!strncmp(name, "P384", 4)) {
- return ssl_grp_ec_secp384r1;
- }
- if (!strncmp(name, "P521", 4)) {
- return ssl_grp_ec_secp521r1;
- }
- }
- if (PL_strlen(name) == 6) {
- if (!strncmp(name, "x25519", 6)) {
- return ssl_grp_ec_curve25519;
- }
- if (!strncmp(name, "FF2048", 6)) {
- return ssl_grp_ffdhe_2048;
- }
- if (!strncmp(name, "FF3072", 6)) {
- return ssl_grp_ffdhe_3072;
- }
- if (!strncmp(name, "FF4096", 6)) {
- return ssl_grp_ffdhe_4096;
- }
- if (!strncmp(name, "FF6144", 6)) {
- return ssl_grp_ffdhe_6144;
- }
- if (!strncmp(name, "FF8192", 6)) {
- return ssl_grp_ffdhe_8192;
- }
- }
- if (PL_strlen(name) == 11) {
- if (!strncmp(name, "xyber768d00", 11)) {
- return ssl_grp_kem_xyber768d00;
+ int len = PL_strlen(name);
+ int i;
+
+ for (i=0; i < sslNamedGroupStringLen; i++) {
+ const struct SSLNamedGroupString *ngs = &sslNamedGroupStringArray[i];
+ if (len == ngs->len) {
+ if (!strncmp(name, ngs->name, len)) {
+ return ngs->grp;
+ }
}
}
@@ -4285,6 +4282,26 @@ done:
return SECSuccess;
}
+const char *
+SECU_NamedGroupToGroupName(SSLNamedGroup grp) {
+ int i;
+ static char unknownBuf[32];
+
+ if (grp == ssl_grp_none) {
+ return "None";
+ }
+
+ for (i=0; i < sslNamedGroupStringLen; i++) {
+ const struct SSLNamedGroupString *ngs = &sslNamedGroupStringArray[i];
+ if (grp == ngs->grp) {
+ return ngs->name;
+ }
+ }
+ snprintf(unknownBuf, sizeof(unknownBuf), "Unknown %d\n", grp);
+
+ return unknownBuf;
+}
+
SSLSignatureScheme
schemeNameToScheme(const char *name)
{
diff -up ./cmd/lib/secutil.h.mlkem ./cmd/lib/secutil.h
--- ./cmd/lib/secutil.h.mlkem 2024-10-31 14:54:15.444515725 -0700
+++ ./cmd/lib/secutil.h 2024-10-31 14:54:15.458515881 -0700
@@ -409,6 +409,8 @@ SECStatus parseGroupList(const char *arg
SECStatus parseSigSchemeList(const char *arg,
const SSLSignatureScheme **enabledSigSchemes,
unsigned int *enabledSigSchemeCount);
+const char *SECU_NamedGroupToGroupName(SSLNamedGroup grp);
+
typedef struct {
SECItem label;
PRBool hasContext;
diff -up ./cmd/selfserv/selfserv.c.mlkem ./cmd/selfserv/selfserv.c
--- ./cmd/selfserv/selfserv.c.mlkem 2024-10-31 14:54:15.445515736 -0700
+++ ./cmd/selfserv/selfserv.c 2024-10-31 14:54:15.458515881 -0700
@@ -229,7 +229,7 @@ PrintParameterUsage()
"-I comma separated list of enabled groups for TLS key exchange.\n"
" The following values are valid:\n"
" P256, P384, P521, x25519, FF2048, FF3072, FF4096, FF6144, FF8192,\n"
- " xyber768d00\n"
+ " mlkem768x25519, mlkem768secp256r1\n"
"-J comma separated list of enabled signature schemes in preference order.\n"
" The following values are valid:\n"
" rsa_pkcs1_sha1, rsa_pkcs1_sha256, rsa_pkcs1_sha384, rsa_pkcs1_sha512,\n"
@@ -422,9 +422,11 @@ printSecurityInfo(PRFileDesc *fd)
channel.isFIPS ? " FIPS" : "");
FPRINTF(stderr,
"selfserv: Server Auth: %d-bit %s, Key Exchange: %d-bit %s\n"
+ " Key Exchange Group:%s\n"
" Compression: %s, Extended Master Secret: %s\n",
channel.authKeyBits, suite.authAlgorithmName,
- channel.keaKeyBits, suite.keaTypeName,
+ channel.keaKeyBits, suite.keaTypeName,
+ SECU_NamedGroupToGroupName(channel.keaGroup),
channel.compressionMethodName,
channel.extendedMasterSecretUsed ? "Yes" : "No");
}
diff -up ./cmd/strsclnt/strsclnt.c.mlkem ./cmd/strsclnt/strsclnt.c
--- ./cmd/strsclnt/strsclnt.c.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./cmd/strsclnt/strsclnt.c 2024-10-31 14:54:15.458515881 -0700
@@ -298,9 +298,11 @@ printSecurityInfo(PRFileDesc *fd)
channel.isFIPS ? " FIPS" : "");
FPRINTF(stderr,
"strsclnt: Server Auth: %d-bit %s, Key Exchange: %d-bit %s\n"
+ " Key Exchange Group:%s\n"
" Compression: %s\n",
channel.authKeyBits, suite.authAlgorithmName,
channel.keaKeyBits, suite.keaTypeName,
+ SECU_NamedGroupToGroupName(channel.keaGroup),
channel.compressionMethodName);
}
}
diff -up ./cmd/tstclnt/tstclnt.c.mlkem ./cmd/tstclnt/tstclnt.c
--- ./cmd/tstclnt/tstclnt.c.mlkem 2024-10-31 14:54:15.445515736 -0700
+++ ./cmd/tstclnt/tstclnt.c 2024-10-31 14:54:15.459515892 -0700
@@ -177,10 +177,12 @@ printSecurityInfo(PRFileDesc *fd)
channel.isFIPS ? " FIPS" : "");
FPRINTF(stderr,
"tstclnt: Server Auth: %d-bit %s, Key Exchange: %d-bit %s\n"
+ " Key Exchange Group:%s\n"
" Compression: %s, Extended Master Secret: %s\n"
" Signature Scheme: %s\n",
channel.authKeyBits, suite.authAlgorithmName,
channel.keaKeyBits, suite.keaTypeName,
+ SECU_NamedGroupToGroupName(channel.keaGroup),
channel.compressionMethodName,
channel.extendedMasterSecretUsed ? "Yes" : "No",
signatureSchemeName(channel.signatureScheme));
@@ -307,7 +309,7 @@ PrintParameterUsage()
fprintf(stderr, "%-20s Comma separated list of enabled groups for TLS key exchange.\n"
"%-20s The following values are valid:\n"
"%-20s P256, P384, P521, x25519, FF2048, FF3072, FF4096, FF6144, FF8192\n"
- "%-20s xyber768d00\n",
+ "%-20s mlkem768x25519, mlkem768secp256r1\n",
"-I", "", "", "");
fprintf(stderr, "%-20s Comma separated list of signature schemes in preference order.\n"
"%-20s The following values are valid:\n"
diff -up ./gtests/nss_bogo_shim/config.json.mlkem ./gtests/nss_bogo_shim/config.json
--- ./gtests/nss_bogo_shim/config.json.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./gtests/nss_bogo_shim/config.json 2024-10-31 14:54:15.459515892 -0700
@@ -65,6 +65,8 @@
"KyberKeyShareIncludedSecond":"Boring sends Xyber768 even if is not the client's first preference",
"KyberKeyShareIncludedThird":"Boring sends Xyber768 even if is not the client's first preference",
+ "NoCommonSignatureAlgorithms-TLS12-Fallback":"Boring will consider RSA key exchange if a common signature algorithm cannot be found",
+
"####################":"####################",
"### TLS1/11 failures due to unsupported signature algorithms":"",
"####################":"####################",
diff -up ./gtests/nss_bogo_shim/nss_bogo_shim.cc.mlkem ./gtests/nss_bogo_shim/nss_bogo_shim.cc
--- ./gtests/nss_bogo_shim/nss_bogo_shim.cc.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./gtests/nss_bogo_shim/nss_bogo_shim.cc 2024-10-31 14:54:15.459515892 -0700
@@ -435,13 +435,6 @@ class TestAgent {
if (rv != SECSuccess) {
return false;
}
- // Xyber768 is disabled by policy by default, so if it's requested
- // we need to update the policy flags as well.
- for (auto group : groups) {
- if (group == ssl_grp_kem_xyber768d00) {
- NSS_SetAlgorithmPolicy(SEC_OID_XYBER768D00, NSS_USE_ALG_IN_SSL_KX, 0);
- }
- }
}
return true;
diff -up ./gtests/pk11_gtest/pk11_kem_unittest.cc.mlkem ./gtests/pk11_gtest/pk11_kem_unittest.cc
--- ./gtests/pk11_gtest/pk11_kem_unittest.cc.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./gtests/pk11_gtest/pk11_kem_unittest.cc 2024-10-31 14:54:15.459515892 -0700
@@ -13,7 +13,9 @@
namespace nss_test {
-class Pkcs11KEMTest : public ::testing::Test {
+class Pkcs11KEMTest
+ : public ::testing::Test,
+ public ::testing::WithParamInterface<CK_NSS_KEM_PARAMETER_SET_TYPE> {
protected:
PK11SymKey *Encapsulate(const ScopedSECKEYPublicKey &pub,
CK_MECHANISM_TYPE target, PK11AttrFlags attrFlags,
@@ -65,22 +67,46 @@ class Pkcs11KEMTest : public ::testing::
SECITEM_FreeItem(&attrValue, PR_FALSE);
}
+
+ CK_MECHANISM_TYPE keyGenMech() {
+ switch (GetParam()) {
+ case CKP_NSS_KYBER_768_ROUND3:
+ return CKM_NSS_KYBER_KEY_PAIR_GEN;
+ case CKP_NSS_ML_KEM_768:
+ return CKM_NSS_ML_KEM_KEY_PAIR_GEN;
+ default:
+ EXPECT_TRUE(false);
+ return 0;
+ }
+ }
+
+ CK_MECHANISM_TYPE encapsMech() {
+ switch (GetParam()) {
+ case CKP_NSS_KYBER_768_ROUND3:
+ return CKM_NSS_KYBER;
+ case CKP_NSS_ML_KEM_768:
+ return CKM_NSS_ML_KEM;
+ default:
+ EXPECT_TRUE(false);
+ return 0;
+ }
+ }
};
-TEST_F(Pkcs11KEMTest, KemConsistencyTest) {
- Pkcs11KeyPairGenerator generator(CKM_NSS_KYBER_KEY_PAIR_GEN);
+TEST_P(Pkcs11KEMTest, KemConsistencyTest) {
+ Pkcs11KeyPairGenerator generator(keyGenMech());
ScopedSECKEYPrivateKey priv;
ScopedSECKEYPublicKey pub;
generator.GenerateKey(&priv, &pub, false);
- ASSERT_EQ((unsigned int)KYBER768_PUBLIC_KEY_BYTES,
- (unsigned int)pub->u.kyber.publicValue.len);
+ ASSERT_NE(nullptr, pub);
+ ASSERT_NE(nullptr, priv);
// Copy the public key to simulate receiving the key as an octet string
ScopedSECKEYPublicKey pubCopy(SECKEY_CopyPublicKey(pub.get()));
ASSERT_NE(nullptr, pubCopy);
- ScopedPK11SlotInfo slot(PK11_GetBestSlot(CKM_NSS_KYBER, nullptr));
+ ScopedPK11SlotInfo slot(PK11_GetBestSlot(encapsMech(), nullptr));
ASSERT_NE(nullptr, slot);
ASSERT_NE((unsigned int)CK_INVALID_HANDLE,
@@ -91,9 +117,6 @@ TEST_F(Pkcs11KEMTest, KemConsistencyTest
pubCopy, CKM_SALSA20_POLY1305, PK11_ATTR_PRIVATE | PK11_ATTR_UNMODIFIABLE,
CKF_ENCRYPT, &ciphertext));
- ASSERT_EQ((unsigned int)KYBER768_CIPHERTEXT_BYTES,
- (unsigned int)ciphertext->len);
-
ASSERT_EQ(CKM_SALSA20_POLY1305, PK11_GetMechanism(sharedSecret.get()));
CK_BBOOL ckTrue = CK_TRUE;
@@ -119,4 +142,7 @@ TEST_F(Pkcs11KEMTest, KemConsistencyTest
EXPECT_EQ(0, SECITEM_CompareItem(item1, item2));
}
+INSTANTIATE_TEST_SUITE_P(Pkcs11KEMTest, Pkcs11KEMTest,
+ ::testing::Values(CKP_NSS_ML_KEM_768));
+
} // namespace nss_test
diff -up ./gtests/pk11_gtest/pk11_keygen.cc.mlkem ./gtests/pk11_gtest/pk11_keygen.cc
--- ./gtests/pk11_gtest/pk11_keygen.cc.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./gtests/pk11_gtest/pk11_keygen.cc 2024-10-31 14:54:15.459515892 -0700
@@ -158,6 +158,11 @@ std::unique_ptr<ParamHolder> Pkcs11KeyPa
return std::unique_ptr<ParamHolder>(
new KyberParamHolder(CKP_NSS_KYBER_768_ROUND3));
+ case CKM_NSS_ML_KEM_KEY_PAIR_GEN:
+ std::cerr << "Generate ML-KEM768 pair" << std::endl;
+ return std::unique_ptr<ParamHolder>(
+ new KyberParamHolder(CKP_NSS_ML_KEM_768));
+
default:
ADD_FAILURE() << "unknown OID " << mech_;
}
diff -up ./gtests/ssl_gtest/manifest.mn.mlkem ./gtests/ssl_gtest/manifest.mn
--- ./gtests/ssl_gtest/manifest.mn.mlkem 2024-10-31 14:54:15.419515446 -0700
+++ ./gtests/ssl_gtest/manifest.mn 2024-10-31 14:54:15.459515892 -0700
@@ -13,6 +13,7 @@ CSRCS = \
CPPSRCS = \
bloomfilter_unittest.cc \
+ selfencrypt_unittest.cc \
ssl_0rtt_unittest.cc \
ssl_aead_unittest.cc \
ssl_agent_unittest.cc \
@@ -42,24 +43,23 @@ CPPSRCS = \
ssl_record_unittest.cc \
ssl_recordsep_unittest.cc \
ssl_recordsize_unittest.cc \
- ssl_resumption_unittest.cc \
ssl_renegotiation_unittest.cc \
+ ssl_resumption_unittest.cc \
ssl_skip_unittest.cc \
ssl_staticrsa_unittest.cc \
ssl_tls13compat_unittest.cc \
ssl_v2_client_hello_unittest.cc \
ssl_version_unittest.cc \
ssl_versionpolicy_unittest.cc \
- selfencrypt_unittest.cc \
test_io.cc \
tls_agent.cc \
tls_connect.cc \
- tls_hkdf_unittest.cc \
tls_filter.cc \
+ tls_hkdf_unittest.cc \
+ tls_mlkem_unittest.cc \
tls_protect.cc \
tls_psk_unittest.cc \
tls_subcerts_unittest.cc \
- tls_xyber_unittest.cc \
$(SSLKEYLOGFILE_FILES) \
$(NULL)
diff -up ./gtests/ssl_gtest/ssl_0rtt_unittest.cc.mlkem ./gtests/ssl_gtest/ssl_0rtt_unittest.cc
--- ./gtests/ssl_gtest/ssl_0rtt_unittest.cc.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./gtests/ssl_gtest/ssl_0rtt_unittest.cc 2024-10-31 14:54:15.459515892 -0700
@@ -197,8 +197,9 @@ TEST_P(TlsZeroRttReplayTest, ZeroRttRepl
TEST_P(TlsConnectTls13, ZeroRttOptionsSetLate) {
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
Connect();
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
SendReceive(); // Need to read so that we absorb the session ticket.
- CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+ CheckKeys();
Reset();
StartConnect();
// Now turn on 0-RTT but too late for the ticket.
diff -up ./gtests/ssl_gtest/ssl_auth_unittest.cc.mlkem ./gtests/ssl_gtest/ssl_auth_unittest.cc
--- ./gtests/ssl_gtest/ssl_auth_unittest.cc.mlkem 2024-10-31 14:54:15.452515814 -0700
+++ ./gtests/ssl_gtest/ssl_auth_unittest.cc 2024-10-31 14:54:15.459515892 -0700
@@ -46,6 +46,7 @@ TEST_P(TlsConnectTls12Plus, ServerAuthRs
PR_ARRAY_SIZE(kSignatureSchemePss));
server_->SetSignatureSchemes(kSignatureSchemePss,
PR_ARRAY_SIZE(kSignatureSchemePss));
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
Connect();
CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_pss,
ssl_sig_rsa_pss_pss_sha256);
@@ -76,6 +77,7 @@ TEST_P(TlsConnectTls12Plus, ServerAuthRs
PR_ARRAY_SIZE(kSignatureSchemePss));
server_->SetSignatureSchemes(kSignatureSchemePss,
PR_ARRAY_SIZE(kSignatureSchemePss));
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
Connect();
CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_pss,
ssl_sig_rsa_pss_pss_sha256);
@@ -919,7 +921,7 @@ TEST_P(TlsConnectClientAuth, ClientAuthE
client_->SetupClientAuth(std::get<2>(GetParam()), true);
server_->RequestClientAuth(true);
Connect();
- CheckKeys(ssl_kea_ecdh, ssl_auth_ecdsa);
+ CheckKeys(ssl_auth_ecdsa);
}
TEST_P(TlsConnectClientAuth, ClientAuthWithEch) {
@@ -932,7 +934,7 @@ TEST_P(TlsConnectClientAuth, ClientAuthW
client_->SetupClientAuth(std::get<2>(GetParam()), true);
server_->RequestClientAuth(true);
Connect();
- CheckKeys(ssl_kea_ecdh, ssl_auth_ecdsa);
+ CheckKeys(ssl_auth_ecdsa);
}
TEST_P(TlsConnectClientAuth, ClientAuthBigRsa) {
@@ -1276,14 +1278,14 @@ static const SSLSignatureScheme kSignatu
static const SSLSignatureScheme kSignatureSchemeRsaSha256[] = {
ssl_sig_rsa_pkcs1_sha256};
-static SSLNamedGroup NamedGroupForEcdsa384(uint16_t version) {
+static SSLNamedGroup NamedGroupForEcdsa384(const TlsConnectTestBase *ctbase) {
// NSS tries to match the group size to the symmetric cipher. In TLS 1.1 and
// 1.0, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA is the highest priority suite, so
// we use P-384. With TLS 1.2 on we pick AES-128 GCM so use x25519.
- if (version <= SSL_LIBRARY_VERSION_TLS_1_1) {
+ if (ctbase->GetVersion() <= SSL_LIBRARY_VERSION_TLS_1_1) {
return ssl_grp_ec_secp384r1;
}
- return ssl_grp_ec_curve25519;
+ return ctbase->GetDefaultGroupFromKEA(ctbase->GetDefaultKEA());
}
// When signature algorithms match up, this should connect successfully; even
@@ -1295,7 +1297,7 @@ TEST_P(TlsConnectGeneric, SignatureAlgor
server_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
Connect();
- CheckKeys(ssl_kea_ecdh, NamedGroupForEcdsa384(version_), ssl_auth_ecdsa,
+ CheckKeys(GetDefaultKEA(), NamedGroupForEcdsa384(this), ssl_auth_ecdsa,
ssl_sig_ecdsa_secp384r1_sha384);
}
@@ -1314,7 +1316,7 @@ TEST_P(TlsConnectGeneric, SignatureAlgor
SSL_SignaturePrefSet(client_->ssl_fd(), clientAlgorithms,
PR_ARRAY_SIZE(clientAlgorithms)));
Connect();
- CheckKeys(ssl_kea_ecdh, NamedGroupForEcdsa384(version_), ssl_auth_ecdsa,
+ CheckKeys(GetDefaultKEA(), NamedGroupForEcdsa384(this), ssl_auth_ecdsa,
ssl_sig_ecdsa_secp384r1_sha384);
}
@@ -1325,7 +1327,7 @@ TEST_P(TlsConnectGeneric, SignatureAlgor
server_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
Connect();
- CheckKeys(ssl_kea_ecdh, NamedGroupForEcdsa384(version_), ssl_auth_ecdsa,
+ CheckKeys(GetDefaultKEA(), NamedGroupForEcdsa384(this), ssl_auth_ecdsa,
ssl_sig_ecdsa_secp384r1_sha384);
}
@@ -1417,6 +1419,7 @@ TEST_P(TlsConnectTls12, SignatureAlgorit
TEST_P(TlsConnectTls13, UnsupportedSignatureSchemeAlert) {
EnsureTlsSetup();
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
auto filter =
MakeTlsFilter<TlsReplaceSignatureSchemeFilter>(server_, ssl_sig_none);
filter->EnableDecryption();
@@ -1428,6 +1431,8 @@ TEST_P(TlsConnectTls13, UnsupportedSigna
TEST_P(TlsConnectTls13, InconsistentSignatureSchemeAlert) {
EnsureTlsSetup();
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
+ server_->ConfigNamedGroups(kNonPQDHEGroups);
// This won't work because we use an RSA cert by default.
auto filter = MakeTlsFilter<TlsReplaceSignatureSchemeFilter>(
@@ -1575,6 +1580,7 @@ static SECStatus AuthCompleteBlock(TlsAg
// processed by the client, SSL_AuthCertificateComplete() is called.
TEST_F(TlsConnectDatagram13, AuthCompleteBeforeFinished) {
client_->SetAuthCertificateCallback(AuthCompleteBlock);
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
MakeTlsFilter<BeforeFinished13>(server_, client_, [this]() {
EXPECT_EQ(SECSuccess, SSL_AuthCertificateComplete(client_->ssl_fd(), 0));
});
@@ -2008,8 +2014,7 @@ class TlsSignatureSchemeConfiguration
EnsureTlsSetup();
configPeer->SetSignatureSchemes(&signature_scheme_, 1);
Connect();
- CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, auth_type_,
- signature_scheme_);
+ CheckKeys(auth_type_, signature_scheme_);
}
std::string certificate_;
@@ -2043,7 +2048,7 @@ TEST_P(TlsSignatureSchemeConfiguration,
client_->SetSignatureSchemes(&signature_scheme_, 1);
server_->SetSignatureSchemes(&signature_scheme_, 1);
Connect();
- CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, auth_type_, signature_scheme_);
+ CheckKeys(auth_type_, signature_scheme_);
}
class Tls12CertificateRequestReplacer : public TlsHandshakeFilter {
diff -up ./gtests/ssl_gtest/ssl_damage_unittest.cc.mlkem ./gtests/ssl_gtest/ssl_damage_unittest.cc
--- ./gtests/ssl_gtest/ssl_damage_unittest.cc.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./gtests/ssl_gtest/ssl_damage_unittest.cc 2024-10-31 14:54:15.459515892 -0700
@@ -60,6 +60,8 @@ TEST_F(TlsConnectTest, DamageSecretHandl
TEST_P(TlsConnectGenericPre13, DamageServerSignature) {
EnsureTlsSetup();
+ server_->ConfigNamedGroups(kNonPQDHEGroups);
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
auto filter = MakeTlsFilter<TlsLastByteDamager>(
server_, kTlsHandshakeServerKeyExchange);
ExpectAlert(client_, kTlsAlertDecryptError);
@@ -70,6 +72,8 @@ TEST_P(TlsConnectGenericPre13, DamageSer
TEST_P(TlsConnectTls13, DamageServerSignature) {
EnsureTlsSetup();
+ server_->ConfigNamedGroups(kNonPQDHEGroups);
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
auto filter = MakeTlsFilter<TlsLastByteDamager>(
server_, kTlsHandshakeCertificateVerify);
filter->EnableDecryption();
diff -up ./gtests/ssl_gtest/ssl_dhe_unittest.cc.mlkem ./gtests/ssl_gtest/ssl_dhe_unittest.cc
--- ./gtests/ssl_gtest/ssl_dhe_unittest.cc.mlkem 2024-10-31 14:54:15.452515814 -0700
+++ ./gtests/ssl_gtest/ssl_dhe_unittest.cc 2024-10-31 14:54:15.459515892 -0700
@@ -29,7 +29,7 @@ TEST_P(TlsConnectGeneric, ConnectDhe) {
TEST_P(TlsConnectTls13, SharesForBothEcdheAndDhe) {
EnsureTlsSetup();
- client_->ConfigNamedGroups(kAllDHEGroups);
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
auto groups_capture =
std::make_shared<TlsExtensionCapture>(client_, ssl_supported_groups_xtn);
@@ -41,7 +41,7 @@ TEST_P(TlsConnectTls13, SharesForBothEcd
Connect();
- CheckKeys();
+ CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
bool ec, dh;
auto track_group_type = [&ec, &dh](SSLNamedGroup group) {
diff -up ./gtests/ssl_gtest/ssl_drop_unittest.cc.mlkem ./gtests/ssl_gtest/ssl_drop_unittest.cc
--- ./gtests/ssl_gtest/ssl_drop_unittest.cc.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./gtests/ssl_gtest/ssl_drop_unittest.cc 2024-10-31 14:54:15.460515903 -0700
@@ -201,6 +201,8 @@ class TlsDropDatagram13 : public TlsConn
// ACKs
TEST_P(TlsDropDatagram13, DropClientFirstFlightOnce) {
client_filters_.drop_->Reset({0});
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
+ server_->ConfigNamedGroups(kNonPQDHEGroups);
StartConnect();
client_->Handshake();
server_->Handshake();
@@ -210,6 +212,8 @@ TEST_P(TlsDropDatagram13, DropClientFirs
TEST_P(TlsDropDatagram13, DropServerFirstFlightOnce) {
server_filters_.drop_->Reset(0xff);
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
+ server_->ConfigNamedGroups(kNonPQDHEGroups);
StartConnect();
client_->Handshake();
// Send the first flight, all dropped.
@@ -224,6 +228,8 @@ TEST_P(TlsDropDatagram13, DropServerFirs
// TODO(ekr@rtfm.com): We should generate an empty ACK.
TEST_P(TlsDropDatagram13, DropServerFirstRecordOnce) {
server_filters_.drop_->Reset({0});
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
+ server_->ConfigNamedGroups(kNonPQDHEGroups);
StartConnect();
client_->Handshake();
server_->Handshake();
@@ -236,6 +242,8 @@ TEST_P(TlsDropDatagram13, DropServerFirs
// produce an ACK.
TEST_P(TlsDropDatagram13, DropServerSecondRecordOnce) {
server_filters_.drop_->Reset({1});
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
+ server_->ConfigNamedGroups(kNonPQDHEGroups);
StartConnect();
client_->Handshake();
server_->Handshake();
@@ -299,6 +307,8 @@ TEST_P(TlsDropDatagram13, DropClientCert
// Shrink the MTU down so that certs get split and drop the first piece.
TEST_P(TlsDropDatagram13, DropFirstHalfOfServerCertificate) {
server_filters_.drop_->Reset({2});
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
+ server_->ConfigNamedGroups(kNonPQDHEGroups);
StartConnect();
ShrinkPostServerHelloMtu();
client_->Handshake();
@@ -326,6 +336,8 @@ TEST_P(TlsDropDatagram13, DropFirstHalfO
// Shrink the MTU down so that certs get split and drop the second piece.
TEST_P(TlsDropDatagram13, DropSecondHalfOfServerCertificate) {
server_filters_.drop_->Reset({3});
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
+ server_->ConfigNamedGroups(kNonPQDHEGroups);
StartConnect();
ShrinkPostServerHelloMtu();
client_->Handshake();
@@ -414,6 +426,8 @@ class TlsFragmentationAndRecoveryTest :
private:
void FirstFlightDropCertificate() {
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
+ server_->ConfigNamedGroups(kNonPQDHEGroups);
StartConnect();
client_->Handshake();
@@ -561,6 +575,8 @@ TEST_P(TlsDropDatagram13, NoDropsDuringZ
TEST_P(TlsDropDatagram13, DropEEDuringZeroRtt) {
SetupForZeroRtt();
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
+ server_->ConfigNamedGroups(kNonPQDHEGroups);
SetFilters();
std::cerr << "Starting second handshake" << std::endl;
client_->Set0RttEnabled(true);
@@ -606,6 +622,8 @@ class TlsReorderDatagram13 : public TlsD
// of the flight and will still produce an ACK.
TEST_P(TlsDropDatagram13, ReorderServerEE) {
server_filters_.drop_->Reset({1});
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
+ server_->ConfigNamedGroups(kNonPQDHEGroups);
StartConnect();
client_->Handshake();
server_->Handshake();
@@ -684,6 +702,8 @@ TEST_F(TlsConnectDatagram13, SendOutOfOr
// Shrink the MTU down so that certs get split and then swap the first and
// second pieces of the server certificate.
TEST_P(TlsReorderDatagram13, ReorderServerCertificate) {
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
+ server_->ConfigNamedGroups(kNonPQDHEGroups);
StartConnect();
ShrinkPostServerHelloMtu();
client_->Handshake();
diff -up ./gtests/ssl_gtest/ssl_ecdh_unittest.cc.mlkem ./gtests/ssl_gtest/ssl_ecdh_unittest.cc
--- ./gtests/ssl_gtest/ssl_ecdh_unittest.cc.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./gtests/ssl_gtest/ssl_ecdh_unittest.cc 2024-10-31 14:54:15.460515903 -0700
@@ -490,7 +490,7 @@ TEST_P(TlsKeyExchangeTest13, EqualPriori
Connect();
- CheckKeys();
+ CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
const std::vector<SSLNamedGroup> shares = {ssl_grp_ec_curve25519};
CheckKEXDetails(client_groups, shares);
}
diff -up ./gtests/ssl_gtest/ssl_exporter_unittest.cc.mlkem ./gtests/ssl_gtest/ssl_exporter_unittest.cc
--- ./gtests/ssl_gtest/ssl_exporter_unittest.cc.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./gtests/ssl_gtest/ssl_exporter_unittest.cc 2024-10-31 14:54:15.460515903 -0700
@@ -82,8 +82,11 @@ TEST_P(TlsConnectGenericPre13, ExporterC
0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF};
EnsureTlsSetup();
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
+ server_->ConfigNamedGroups(kNonPQDHEGroups);
Connect();
- CheckKeys();
+ CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+
static const size_t exporter_len = 10;
uint8_t client_value[exporter_len] = {0};
diff -up ./gtests/ssl_gtest/ssl_extension_unittest.cc.mlkem ./gtests/ssl_gtest/ssl_extension_unittest.cc
--- ./gtests/ssl_gtest/ssl_extension_unittest.cc.mlkem 2024-10-31 14:54:15.452515814 -0700
+++ ./gtests/ssl_gtest/ssl_extension_unittest.cc 2024-10-31 14:54:15.460515903 -0700
@@ -1314,6 +1314,9 @@ TEST_P(TlsDisallowedUnadvertisedExtensio
TEST_P(TlsConnectStream, IncludePadding) {
EnsureTlsSetup();
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
+ server_->ConfigNamedGroups(kNonPQDHEGroups);
+
SSL_EnableTls13GreaseEch(client_->ssl_fd(), PR_FALSE); // Don't GREASE
// This needs to be long enough to push a TLS 1.0 ClientHello over 255, but
@@ -1372,7 +1375,7 @@ TEST_F(TlsConnectStreamTls13, ClientHell
PR_TRUE) == SECSuccess);
Connect();
SendReceive();
- CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_psk, ssl_sig_none);
+ CheckKeys(ssl_kea_ecdh_hybrid, ssl_grp_kem_mlkem768x25519, ssl_auth_psk, ssl_sig_none);
}
/* This test checks that the ClientHello extension order is actually permuted
diff -up ./gtests/ssl_gtest/ssl_gtest.gyp.mlkem ./gtests/ssl_gtest/ssl_gtest.gyp
--- ./gtests/ssl_gtest/ssl_gtest.gyp.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./gtests/ssl_gtest/ssl_gtest.gyp 2024-10-31 14:54:15.460515903 -0700
@@ -31,8 +31,8 @@
'ssl_ems_unittest.cc',
'ssl_exporter_unittest.cc',
'ssl_extension_unittest.cc',
- 'ssl_fuzz_unittest.cc',
'ssl_fragment_unittest.cc',
+ 'ssl_fuzz_unittest.cc',
'ssl_gather_unittest.cc',
'ssl_gtest.cc',
'ssl_hrr_unittest.cc',
@@ -43,8 +43,8 @@
'ssl_record_unittest.cc',
'ssl_recordsep_unittest.cc',
'ssl_recordsize_unittest.cc',
- 'ssl_resumption_unittest.cc',
'ssl_renegotiation_unittest.cc',
+ 'ssl_resumption_unittest.cc',
'ssl_skip_unittest.cc',
'ssl_staticrsa_unittest.cc',
'ssl_tls13compat_unittest.cc',
@@ -54,13 +54,14 @@
'test_io.cc',
'tls_agent.cc',
'tls_connect.cc',
+ 'tls_ech_unittest.cc',
'tls_filter.cc',
+ 'tls_grease_unittest.cc',
'tls_hkdf_unittest.cc',
- 'tls_ech_unittest.cc',
+ 'tls_mlkem_unittest.cc',
'tls_protect.cc',
'tls_psk_unittest.cc',
'tls_subcerts_unittest.cc',
- 'tls_grease_unittest.cc',
'tls_xyber_unittest.cc',
],
'dependencies': [
diff -up ./gtests/ssl_gtest/ssl_hrr_unittest.cc.mlkem ./gtests/ssl_gtest/ssl_hrr_unittest.cc
--- ./gtests/ssl_gtest/ssl_hrr_unittest.cc.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./gtests/ssl_gtest/ssl_hrr_unittest.cc 2024-10-31 14:54:15.460515903 -0700
@@ -22,6 +22,7 @@ TEST_P(TlsConnectTls13, HelloRetryReques
const PRInt32 k0RttDataLen = static_cast<PRInt32>(strlen(k0RttData));
SetupForZeroRtt(); // initial handshake as normal
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
static const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1,
ssl_grp_ec_secp521r1};
@@ -107,6 +108,7 @@ TEST_P(TlsConnectTls13, SecondClientHell
auto orig_client =
std::make_shared<TlsAgent>(client_->name(), TlsAgent::CLIENT, variant_);
client_.swap(orig_client);
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
SSL_LIBRARY_VERSION_TLS_1_3);
client_->ConfigureSessionCache(RESUME_BOTH);
@@ -370,6 +372,7 @@ TEST_P(TlsConnectTls13, RetryCallbackRet
size_t cb_called = 0;
EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(server_->ssl_fd(),
RetryHello, &cb_called));
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
// Do the first message exchange.
StartConnect();
@@ -417,6 +420,7 @@ TEST_P(TlsConnectTls13, RetryCallbackRet
size_t cb_called = 0;
EXPECT_EQ(SECSuccess, SSL_HelloRetryRequestCallback(server_->ssl_fd(),
RetryHello, &cb_called));
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
// Do the first message exchange.
StartConnect();
@@ -950,7 +954,7 @@ TEST_P(TlsKeyExchange13, ConnectEcdhePre
client_->ConfigNamedGroups(client_groups);
server_->ConfigNamedGroups(server_groups);
Connect();
- CheckKeys();
+ CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519);
static const std::vector<SSLNamedGroup> expectedShares = {
ssl_grp_ec_secp384r1};
CheckKEXDetails(client_groups, expectedShares, ssl_grp_ec_curve25519);
@@ -997,7 +1001,7 @@ TEST_P(TlsKeyExchange13, ConnectEcdhePre
EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1));
Connect();
- CheckKeys();
+ CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519);
CheckKEXDetails(client_groups, client_groups);
}
@@ -1043,7 +1047,7 @@ TEST_P(TlsKeyExchange13,
EXPECT_EQ(2U, cb_called);
EXPECT_TRUE(shares_capture2_->captured()) << "client should send shares";
- CheckKeys();
+ CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519);
static const std::vector<SSLNamedGroup> client_shares(
client_groups.begin(), client_groups.begin() + 2);
CheckKEXDetails(client_groups, client_shares, server_groups[0]);
diff -up ./gtests/ssl_gtest/ssl_keyupdate_unittest.cc.mlkem ./gtests/ssl_gtest/ssl_keyupdate_unittest.cc
--- ./gtests/ssl_gtest/ssl_keyupdate_unittest.cc.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./gtests/ssl_gtest/ssl_keyupdate_unittest.cc 2024-10-31 14:54:15.460515903 -0700
@@ -1180,6 +1180,8 @@ TEST_F(TlsConnectDatagram13, DTLSKU_Wron
TEST_F(TlsConnectDatagram13, DTLSKU_DamagedLength) {
EnsureTlsSetup();
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
+ server_->ConfigNamedGroups(kNonPQDHEGroups);
// Filter replacing the length value with 0.
auto filter = MakeTlsFilter<TLSKeyUpdateDamager>(client_, 3, 0);
filter->EnableDecryption();
@@ -1217,6 +1219,8 @@ TEST_F(TlsConnectDatagram13, DTLSKU_Dama
TEST_F(TlsConnectDatagram13, DTLSKU_DamagedFragmentLength) {
EnsureTlsSetup();
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
+ server_->ConfigNamedGroups(kNonPQDHEGroups);
// Filter replacing the fragment length with 1.
auto filter = MakeTlsFilter<TLSKeyUpdateDamager>(client_, 10, 1);
filter->EnableDecryption();
@@ -1498,4 +1502,4 @@ TEST_F(TlsConnectDatagram13, DTLSKU_TooE
client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT);
}
-} // namespace nss_test
\ No newline at end of file
+} // namespace nss_test
diff -up ./gtests/ssl_gtest/ssl_loopback_unittest.cc.mlkem ./gtests/ssl_gtest/ssl_loopback_unittest.cc
--- ./gtests/ssl_gtest/ssl_loopback_unittest.cc.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./gtests/ssl_gtest/ssl_loopback_unittest.cc 2024-10-31 14:54:15.460515903 -0700
@@ -37,7 +37,7 @@ TEST_P(TlsConnectGeneric, ConnectEcdsa)
SetExpectedVersion(std::get<1>(GetParam()));
Reset(TlsAgent::kServerEcdsa256);
Connect();
- CheckKeys(ssl_kea_ecdh, ssl_auth_ecdsa);
+ CheckKeys(ssl_auth_ecdsa);
}
TEST_P(TlsConnectGeneric, CipherSuiteMismatch) {
diff -up ./gtests/ssl_gtest/ssl_recordsep_unittest.cc.mlkem ./gtests/ssl_gtest/ssl_recordsep_unittest.cc
--- ./gtests/ssl_gtest/ssl_recordsep_unittest.cc.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./gtests/ssl_gtest/ssl_recordsep_unittest.cc 2024-10-31 14:54:15.460515903 -0700
@@ -344,6 +344,8 @@ static void SendForwardReceive(std::shar
}
TEST_P(TlsConnectStream, ReplaceRecordLayer) {
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
+ server_->ConfigNamedGroups(kNonPQDHEGroups);
StartConnect();
client_->SetServerKeyBits(server_->server_key_bits());
@@ -387,7 +389,7 @@ TEST_P(TlsConnectStream, ReplaceRecordLa
client_stage.ForwardAll(server_, TlsAgent::STATE_CONNECTED);
server_stage.ForwardAll(client_, TlsAgent::STATE_CONNECTED);
}
- CheckKeys();
+ CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign); // why?
// Reading and writing application data should work.
SendForwardReceive(client_, client_stage, server_);
@@ -445,6 +447,8 @@ static SECStatus AuthCompleteBlock(TlsAg
}
TEST_P(TlsConnectStream, ReplaceRecordLayerAsyncLateAuth) {
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
+ server_->ConfigNamedGroups(kNonPQDHEGroups);
StartConnect();
client_->SetServerKeyBits(server_->server_key_bits());
@@ -494,7 +498,7 @@ TEST_P(TlsConnectStream, ReplaceRecordLa
client_stage.ForwardAll(server_, TlsAgent::STATE_CONNECTED);
server_stage.ForwardAll(client_, TlsAgent::STATE_CONNECTED);
}
- CheckKeys();
+ CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign); // why?
// Reading and writing application data should work.
SendForwardReceive(client_, client_stage, server_);
diff -up ./gtests/ssl_gtest/ssl_recordsize_unittest.cc.mlkem ./gtests/ssl_gtest/ssl_recordsize_unittest.cc
--- ./gtests/ssl_gtest/ssl_recordsize_unittest.cc.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./gtests/ssl_gtest/ssl_recordsize_unittest.cc 2024-10-31 14:54:15.461515914 -0700
@@ -275,6 +275,7 @@ TEST_F(TlsConnectStreamTls13, ClientHell
auto filter =
MakeTlsFilter<TlsHandshakeRecorder>(client_, kTlsHandshakeClientHello);
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
// Add PSK with label long enough to push CH length into [256, 511].
std::vector<uint8_t> label(100);
EXPECT_EQ(SECSuccess,
@@ -723,4 +724,4 @@ TEST_P(TlsConnectGeneric, RecordSizeLimi
}
}
-} // namespace nss_test
\ No newline at end of file
+} // namespace nss_test
diff -up ./gtests/ssl_gtest/ssl_resumption_unittest.cc.mlkem ./gtests/ssl_gtest/ssl_resumption_unittest.cc
--- ./gtests/ssl_gtest/ssl_resumption_unittest.cc.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./gtests/ssl_gtest/ssl_resumption_unittest.cc 2024-10-31 14:54:15.461515914 -0700
@@ -175,11 +175,15 @@ TEST_P(TlsConnectGenericResumption, Conn
TEST_P(TlsConnectGenericPre13, ResumeWithHigherVersionTls13) {
uint16_t lower_version = version_;
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
+ server_->ConfigNamedGroups(kNonPQDHEGroups);
Connect();
SendReceive();
CheckKeys();
Reset();
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
+ server_->ConfigNamedGroups(kNonPQDHEGroups);
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
EnsureTlsSetup();
auto psk_ext = std::make_shared<TlsExtensionCapture>(
@@ -244,6 +248,8 @@ TEST_P(TlsConnectGenericPre13, ResumeWit
// connection. This looks like compatibility mode, we just want to ensure
// that we get TLS 1.3 rather than 1.2 (and no resumption).
Reset();
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
+ server_->ConfigNamedGroups(kNonPQDHEGroups);
auto client_sid = MakeTlsFilter<CaptureSessionId>(client_);
auto server_sid = MakeTlsFilter<CaptureSessionId>(server_);
ConfigureSessionCache(RESUME_SESSIONID, RESUME_SESSIONID);
@@ -359,12 +365,14 @@ TEST_P(TlsConnectGenericResumption, Conn
TEST_P(TlsConnectGeneric, ConnectWithExpiredTicketAtServer) {
// This causes a ticket resumption.
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
Connect();
SendReceive();
Reset();
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
ExpectResumption(RESUME_NONE);
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
SSLExtensionType xtn = (version_ >= SSL_LIBRARY_VERSION_TLS_1_3)
? ssl_tls13_pre_shared_key_xtn
@@ -453,7 +461,7 @@ TEST_P(TlsConnectGeneric, ServerSNICertT
Connect();
ScopedCERTCertificate cert2(SSL_PeerCertificate(client_->ssl_fd()));
ASSERT_NE(nullptr, cert2.get());
- CheckKeys(ssl_kea_ecdh, ssl_auth_ecdsa);
+ CheckKeys(ssl_auth_ecdsa);
EXPECT_TRUE(SECITEM_ItemsAreEqual(&cert1->derCert, &cert2->derCert));
}
@@ -613,7 +621,7 @@ TEST_P(TlsConnectGenericResumption, Resu
client_->EnableSingleCipher(ChooseOneCipher(version_));
Connect();
SendReceive();
- CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+ CheckKeys(ssl_auth_rsa_sign);
Reset();
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
@@ -628,7 +636,7 @@ TEST_P(TlsConnectGenericResumption, Resu
auto ticket_capture =
MakeTlsFilter<TlsExtensionCapture>(client_, ticket_extension);
Connect();
- CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+ CheckKeys(ssl_auth_rsa_sign);
EXPECT_EQ(0U, ticket_capture->extension().len());
}
@@ -655,7 +663,7 @@ TEST_P(TlsConnectStream, ResumptionOverr
server_->EnableSingleCipher(ChooseOneCipher(version_));
Connect();
SendReceive();
- CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+ CheckKeys();
Reset();
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
@@ -793,8 +801,7 @@ TEST_F(TlsConnectTest, TestTls13Resumpti
MakeTlsFilter<TlsExtensionCapture>(client_, ssl_tls13_pre_shared_key_xtn);
Connect();
SendReceive();
- CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign,
- ssl_sig_rsa_pss_rsae_sha256);
+ CheckKeys(ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256);
// The filter will go away when we reset, so save the captured extension.
DataBuffer initialTicket(c1->extension());
ASSERT_LT(0U, initialTicket.len());
@@ -811,8 +818,7 @@ TEST_F(TlsConnectTest, TestTls13Resumpti
ExpectResumption(RESUME_TICKET);
Connect();
SendReceive();
- CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign,
- ssl_sig_rsa_pss_rsae_sha256);
+ CheckKeys(ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256);
ASSERT_LT(0U, c2->extension().len());
ScopedCERTCertificate cert2(SSL_PeerCertificate(client_->ssl_fd()));
@@ -1089,7 +1095,7 @@ TEST_F(TlsConnectTest, TestTls13Resumpti
Handshake();
SendReceive();
- CheckKeys();
+ CheckKeys(ssl_kea_ecdh);
}
TEST_F(TlsConnectTest, TestTls13ResumptionForcedDowngrade) {
@@ -1144,15 +1150,15 @@ TEST_P(TlsConnectGenericResumption, ReCo
server_->EnableSingleCipher(ChooseOneCipher(version_));
Connect();
SendReceive();
- CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign,
- ssl_sig_rsa_pss_rsae_sha256);
+ CheckKeys(ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256);
// Resume
Reset();
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
ExpectResumption(RESUME_TICKET);
Connect();
// Only the client knows this.
- CheckKeysResumption(ssl_kea_ecdh, ssl_grp_none, ssl_grp_ec_curve25519,
+ CheckKeysResumption(GetDefaultKEA(), ssl_grp_none,
+ GetDefaultGroupFromKEA(GetDefaultKEA()),
ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256);
}
@@ -1161,13 +1167,13 @@ TEST_P(TlsConnectGenericPre13, ReConnect
server_->EnableSingleCipher(ChooseOneCipher(version_));
Connect();
SendReceive();
- CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign,
- ssl_sig_rsa_pss_rsae_sha256);
+ CheckKeys(ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256);
// Resume
Reset();
ExpectResumption(RESUME_SESSIONID);
Connect();
- CheckKeysResumption(ssl_kea_ecdh, ssl_grp_none, ssl_grp_ec_curve25519,
+ CheckKeysResumption(GetDefaultKEA(), ssl_grp_none,
+ GetDefaultGroupFromKEA(GetDefaultKEA()),
ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256);
}
@@ -1176,15 +1182,15 @@ TEST_P(TlsConnectGenericResumption, ReCo
server_->EnableSingleCipher(ChooseOneCipher(version_));
Connect();
SendReceive();
- CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign,
- ssl_sig_rsa_pss_rsae_sha256);
+ CheckKeys(ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256);
// Resume
Reset();
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
ExpectResumption(RESUME_TICKET);
Connect();
// Only the client knows this.
- CheckKeysResumption(ssl_kea_ecdh, ssl_grp_none, ssl_grp_ec_curve25519,
+ CheckKeysResumption(GetDefaultKEA(), ssl_grp_none,
+ GetDefaultGroupFromKEA(GetDefaultKEA()),
ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256);
// Resume connection again
Reset();
@@ -1192,7 +1198,8 @@ TEST_P(TlsConnectGenericResumption, ReCo
ExpectResumption(RESUME_TICKET, 2);
Connect();
// Only the client knows this.
- CheckKeysResumption(ssl_kea_ecdh, ssl_grp_none, ssl_grp_ec_curve25519,
+ CheckKeysResumption(GetDefaultKEA(), ssl_grp_none,
+ GetDefaultGroupFromKEA(GetDefaultKEA()),
ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256);
}
@@ -1219,11 +1226,15 @@ void CheckGetInfoResult(PRTime now, uint
// when resuming using an external token.
TEST_P(TlsConnectGenericResumptionToken, CheckSessionId) {
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
+ server_->ConfigNamedGroups(kNonPQDHEGroups);
auto original_sid = MakeTlsFilter<CaptureSessionId>(client_);
Connect();
SendReceive();
Reset();
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
+ server_->ConfigNamedGroups(kNonPQDHEGroups);
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
ExpectResumption(RESUME_TICKET);
diff -up ./gtests/ssl_gtest/ssl_skip_unittest.cc.mlkem ./gtests/ssl_gtest/ssl_skip_unittest.cc
--- ./gtests/ssl_gtest/ssl_skip_unittest.cc.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./gtests/ssl_gtest/ssl_skip_unittest.cc 2024-10-31 14:54:15.461515914 -0700
@@ -114,6 +114,9 @@ class Tls13SkipTest : public TlsConnectT
void SetUp() override {
TlsConnectTestBase::SetUp();
EnsureTlsSetup();
+ // until we can fix filters to work with MLKEM
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
+ server_->ConfigNamedGroups(kNonPQDHEGroups);
}
void ServerSkipTest(std::shared_ptr<TlsRecordFilter> filter, int32_t error) {
diff -up ./gtests/ssl_gtest/ssl_tls13compat_unittest.cc.mlkem ./gtests/ssl_gtest/ssl_tls13compat_unittest.cc
--- ./gtests/ssl_gtest/ssl_tls13compat_unittest.cc.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./gtests/ssl_gtest/ssl_tls13compat_unittest.cc 2024-10-31 14:54:15.461515914 -0700
@@ -482,6 +482,7 @@ TEST_F(TlsConnectDatagram13, CompatModeD
client_->SetOption(SSL_ENABLE_TLS13_COMPAT_MODE, PR_TRUE);
auto client_records = MakeTlsFilter<TlsRecordRecorder>(client_);
auto server_records = MakeTlsFilter<TlsRecordRecorder>(server_);
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
Connect();
ASSERT_EQ(2U, client_records->count()); // CH, Fin
@@ -522,6 +523,7 @@ class AddSessionIdFilter : public TlsHan
// mode. It should be ignored instead.
TEST_F(TlsConnectDatagram13, CompatModeDtlsServer) {
EnsureTlsSetup();
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
auto client_records = std::make_shared<TlsRecordRecorder>(client_);
client_->SetFilter(
std::make_shared<ChainedPacketFilter>(ChainedPacketFilterInit(
diff -up ./gtests/ssl_gtest/ssl_version_unittest.cc.mlkem ./gtests/ssl_gtest/ssl_version_unittest.cc
--- ./gtests/ssl_gtest/ssl_version_unittest.cc.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./gtests/ssl_gtest/ssl_version_unittest.cc 2024-10-31 14:54:15.461515914 -0700
@@ -370,6 +370,7 @@ TEST_F(DtlsConnectTest, DtlsSupportedVer
SSL_LIBRARY_VERSION_TLS_1_3);
auto capture = MakeTlsFilter<TlsExtensionCapture>(
client_, ssl_tls13_supported_versions_xtn);
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
Connect();
ASSERT_EQ(7U, capture->extension().len());
@@ -393,6 +394,7 @@ TEST_F(DtlsConnectTest, Dtls13VersionWor
// Toggle the workaround, then verify both encodings are present.
EnsureTlsSetup();
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
SSL_SetDtls13VersionWorkaround(client_->ssl_fd(), PR_TRUE);
SSL_SetDtls13VersionWorkaround(client_->ssl_fd(), PR_FALSE);
SSL_SetDtls13VersionWorkaround(client_->ssl_fd(), PR_TRUE);
diff -up ./gtests/ssl_gtest/tls_agent.cc.mlkem ./gtests/ssl_gtest/tls_agent.cc
--- ./gtests/ssl_gtest/tls_agent.cc.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./gtests/ssl_gtest/tls_agent.cc 2024-10-31 14:54:15.461515914 -0700
@@ -493,15 +493,21 @@ void TlsAgent::DisableAllCiphers() {
// Not actually all groups, just the ones that we are actually willing
// to use.
const std::vector<SSLNamedGroup> kAllDHEGroups = {
- ssl_grp_ec_curve25519, ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1,
- ssl_grp_ec_secp521r1, ssl_grp_ffdhe_2048, ssl_grp_ffdhe_3072,
- ssl_grp_ffdhe_4096, ssl_grp_ffdhe_6144, ssl_grp_ffdhe_8192,
- ssl_grp_kem_xyber768d00,
+ ssl_grp_ec_curve25519, ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1,
+ ssl_grp_ec_secp521r1, ssl_grp_ffdhe_2048, ssl_grp_ffdhe_3072,
+ ssl_grp_ffdhe_4096, ssl_grp_ffdhe_6144, ssl_grp_ffdhe_8192,
+ ssl_grp_kem_mlkem768x25519, ssl_grp_kem_mlkem768secp256r1,
+};
+
+const std::vector<SSLNamedGroup> kNonPQDHEGroups = {
+ ssl_grp_ec_curve25519, ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1,
+ ssl_grp_ec_secp521r1, ssl_grp_ffdhe_2048, ssl_grp_ffdhe_3072,
+ ssl_grp_ffdhe_4096, ssl_grp_ffdhe_6144, ssl_grp_ffdhe_8192,
};
const std::vector<SSLNamedGroup> kECDHEGroups = {
ssl_grp_ec_curve25519, ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1,
- ssl_grp_ec_secp521r1, ssl_grp_kem_xyber768d00,
+ ssl_grp_ec_secp521r1,
};
const std::vector<SSLNamedGroup> kFFDHEGroups = {
@@ -510,12 +516,14 @@ const std::vector<SSLNamedGroup> kFFDHEG
// Defined because the big DHE groups are ridiculously slow.
const std::vector<SSLNamedGroup> kFasterDHEGroups = {
- ssl_grp_ec_curve25519, ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1,
- ssl_grp_ffdhe_2048, ssl_grp_ffdhe_3072, ssl_grp_kem_xyber768d00,
+ ssl_grp_ec_curve25519, ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1,
+ ssl_grp_ffdhe_2048, ssl_grp_ffdhe_3072,
+ ssl_grp_kem_mlkem768x25519, ssl_grp_kem_mlkem768secp256r1,
};
const std::vector<SSLNamedGroup> kEcdhHybridGroups = {
- ssl_grp_kem_xyber768d00,
+ ssl_grp_kem_mlkem768x25519,
+ ssl_grp_kem_mlkem768secp256r1,
};
void TlsAgent::EnableCiphersByKeyExchange(SSLKEAType kea) {
@@ -683,9 +691,10 @@ void TlsAgent::CheckKEA(SSLKEAType kea,
if (kea_size == 0) {
switch (kea_group) {
case ssl_grp_ec_curve25519:
- case ssl_grp_kem_xyber768d00:
+ case ssl_grp_kem_mlkem768x25519:
kea_size = 255;
break;
+ case ssl_grp_kem_mlkem768secp256r1:
case ssl_grp_ec_secp256r1:
kea_size = 256;
break;
@@ -1315,6 +1324,10 @@ void TlsAgentTestBase::Reset(const std::
if (version_) {
agent_->SetVersionRange(version_, version_);
}
+ const std::vector<SSLNamedGroup> groups = {
+ ssl_grp_ec_curve25519, ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1,
+ ssl_grp_ffdhe_2048};
+ agent_->ConfigNamedGroups(groups);
agent_->adapter()->SetPeer(sink_adapter_);
agent_->StartConnect();
}
diff -up ./gtests/ssl_gtest/tls_agent.h.mlkem ./gtests/ssl_gtest/tls_agent.h
--- ./gtests/ssl_gtest/tls_agent.h.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./gtests/ssl_gtest/tls_agent.h 2024-10-31 14:54:15.461515914 -0700
@@ -52,6 +52,7 @@ class TlsCipherSpec;
struct TlsRecord;
const extern std::vector<SSLNamedGroup> kAllDHEGroups;
+const extern std::vector<SSLNamedGroup> kNonPQDHEGroups;
const extern std::vector<SSLNamedGroup> kECDHEGroups;
const extern std::vector<SSLNamedGroup> kFFDHEGroups;
const extern std::vector<SSLNamedGroup> kFasterDHEGroups;
diff -up ./gtests/ssl_gtest/tls_connect.cc.mlkem ./gtests/ssl_gtest/tls_connect.cc
--- ./gtests/ssl_gtest/tls_connect.cc.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./gtests/ssl_gtest/tls_connect.cc 2024-10-31 14:54:15.461515914 -0700
@@ -505,21 +505,23 @@ void TlsConnectTestBase::CheckEarlyDataL
EXPECT_EQ(expected_size, static_cast<size_t>(preinfo.maxEarlyDataSize));
}
-void TlsConnectTestBase::CheckKeys(SSLKEAType kea_type, SSLNamedGroup kea_group,
- SSLAuthType auth_type,
- SSLSignatureScheme sig_scheme) const {
- if (kea_group != ssl_grp_none) {
- client_->CheckKEA(kea_type, kea_group);
- server_->CheckKEA(kea_type, kea_group);
+SSLKEAType TlsConnectTestBase::GetDefaultKEA(void) const {
+ if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
+ return ssl_kea_ecdh_hybrid;
}
- server_->CheckAuthType(auth_type, sig_scheme);
- client_->CheckAuthType(auth_type, sig_scheme);
+ return ssl_kea_ecdh;
}
-void TlsConnectTestBase::CheckKeys(SSLKEAType kea_type,
- SSLAuthType auth_type) const {
+SSLAuthType TlsConnectTestBase::GetDefaultAuth(void) const {
+ return ssl_auth_rsa_sign;
+}
+
+SSLNamedGroup TlsConnectTestBase::GetDefaultGroupFromKEA(SSLKEAType kea_type) const {
SSLNamedGroup group;
switch (kea_type) {
+ case ssl_kea_ecdh_hybrid:
+ group = ssl_grp_kem_mlkem768x25519;
+ break;
case ssl_kea_ecdh:
group = ssl_grp_ec_curve25519;
break;
@@ -534,7 +536,10 @@ void TlsConnectTestBase::CheckKeys(SSLKE
group = ssl_grp_none;
break;
}
+ return group;
+}
+SSLSignatureScheme TlsConnectTestBase::GetDefaultSchemeFromAuth(SSLAuthType auth_type) const {
SSLSignatureScheme scheme;
switch (auth_type) {
case ssl_auth_rsa_decrypt:
@@ -561,11 +566,54 @@ void TlsConnectTestBase::CheckKeys(SSLKE
scheme = static_cast<SSLSignatureScheme>(0x0100);
break;
}
+ return scheme;
+}
+void TlsConnectTestBase::CheckKeys(SSLKEAType kea_type, SSLNamedGroup kea_group,
+ SSLAuthType auth_type,
+ SSLSignatureScheme sig_scheme) const {
+ if (kea_group != ssl_grp_none) {
+ client_->CheckKEA(kea_type, kea_group);
+ server_->CheckKEA(kea_type, kea_group);
+ }
+ server_->CheckAuthType(auth_type, sig_scheme);
+ client_->CheckAuthType(auth_type, sig_scheme);
+}
+
+void TlsConnectTestBase::CheckKeys(SSLKEAType kea_type,
+ SSLNamedGroup kea_group) const {
+ SSLAuthType auth_type = GetDefaultAuth();
+ SSLSignatureScheme scheme = GetDefaultSchemeFromAuth(auth_type);
+ CheckKeys(kea_type, kea_group, auth_type, scheme);
+}
+
+void TlsConnectTestBase::CheckKeys( SSLAuthType auth_type,
+ SSLSignatureScheme sig_scheme) const {
+ SSLKEAType kea_type = GetDefaultKEA();
+ SSLNamedGroup group = GetDefaultGroupFromKEA(kea_type);
+ CheckKeys(kea_type, group, auth_type, sig_scheme);
+}
+
+void TlsConnectTestBase::CheckKeys(SSLKEAType kea_type,
+ SSLAuthType auth_type) const {
+ SSLNamedGroup group = GetDefaultGroupFromKEA(kea_type);
+ SSLSignatureScheme scheme = GetDefaultSchemeFromAuth(auth_type);
CheckKeys(kea_type, group, auth_type, scheme);
}
+void TlsConnectTestBase::CheckKeys(SSLKEAType kea_type) const {
+ SSLAuthType auth_type = GetDefaultAuth();
+ CheckKeys(kea_type, auth_type);
+}
+
+void TlsConnectTestBase::CheckKeys(SSLAuthType auth_type) const {
+ SSLKEAType kea_type = GetDefaultKEA();
+ CheckKeys(kea_type, auth_type);
+}
+
void TlsConnectTestBase::CheckKeys() const {
- CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+ SSLKEAType kea_type = GetDefaultKEA();
+ SSLAuthType auth_type = GetDefaultAuth();
+ CheckKeys(kea_type, auth_type);
}
void TlsConnectTestBase::CheckKeysResumption(SSLKEAType kea_type,
diff -up ./gtests/ssl_gtest/tls_connect.h.mlkem ./gtests/ssl_gtest/tls_connect.h
--- ./gtests/ssl_gtest/tls_connect.h.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./gtests/ssl_gtest/tls_connect.h 2024-10-31 14:54:15.461515914 -0700
@@ -83,11 +83,23 @@ class TlsConnectTestBase : public ::test
void ConnectWithCipherSuite(uint16_t cipher_suite);
void CheckEarlyDataLimit(const std::shared_ptr<TlsAgent>& agent,
size_t expected_size);
+ // Get the default KEA for our tls version
+ SSLKEAType GetDefaultKEA(void) const;
+ // Get the default auth for our tls version
+ SSLAuthType GetDefaultAuth(void) const;
+ // Find the default group for a given KEA
+ SSLNamedGroup GetDefaultGroupFromKEA(SSLKEAType kea_type) const;
+ // Find the default scheam for a given auth
+ SSLSignatureScheme GetDefaultSchemeFromAuth(SSLAuthType auth_type) const;
// Check that the keys used in the handshake match expectations.
void CheckKeys(SSLKEAType kea_type, SSLNamedGroup kea_group,
SSLAuthType auth_type, SSLSignatureScheme sig_scheme) const;
- // This version guesses some of the values.
+ // These version guesses some of the values.
+ void CheckKeys(SSLKEAType kea_type, SSLNamedGroup kea_group) const;
+ void CheckKeys(SSLAuthType auth_type, SSLSignatureScheme sig_scheme) const;
void CheckKeys(SSLKEAType kea_type, SSLAuthType auth_type) const;
+ void CheckKeys(SSLKEAType kea_type) const;
+ void CheckKeys(SSLAuthType auth_type) const;
// This version assumes defaults.
void CheckKeys() const;
// Check that keys on resumed sessions.
@@ -103,6 +115,7 @@ class TlsConnectTestBase : public ::test
void ConfigureVersion(uint16_t version);
void SetExpectedVersion(uint16_t version);
+ uint16_t GetVersion(void) const { return version_; };
// Expect resumption of a particular type.
void ExpectResumption(SessionResumptionMode expected,
uint8_t num_resumed = 1);
diff -up ./gtests/ssl_gtest/tls_mlkem_unittest.cc.mlkem ./gtests/ssl_gtest/tls_mlkem_unittest.cc
--- ./gtests/ssl_gtest/tls_mlkem_unittest.cc.mlkem 2024-10-31 14:54:15.462515926 -0700
+++ ./gtests/ssl_gtest/tls_mlkem_unittest.cc 2024-10-31 14:54:15.462515926 -0700
@@ -0,0 +1,516 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "ssl.h"
+#include "sslerr.h"
+#include "sslproto.h"
+#include "secmodti.h" /* for SEC_OID_MLKEM768SECP256R1, remove when shipped upstream */
+
+extern "C" {
+// This is not something that should make you happy.
+#include "libssl_internals.h"
+}
+
+#include "gtest_utils.h"
+#include "nss_scoped_ptrs.h"
+#include "tls_connect.h"
+#include "tls_filter.h"
+#include "tls_parser.h"
+
+namespace nss_test {
+
+TEST_P(TlsKeyExchangeTest13, Mlkem768x25519Supported) {
+ EnsureKeyShareSetup();
+ ConfigNamedGroups({ssl_grp_kem_mlkem768x25519});
+
+ Connect();
+ CheckKeys(ssl_kea_ecdh_hybrid, ssl_grp_kem_mlkem768x25519, ssl_auth_rsa_sign,
+ ssl_sig_rsa_pss_rsae_sha256);
+}
+
+TEST_P(TlsKeyExchangeTest13, Mlkem768Secp256r1Supported) {
+ EnsureKeyShareSetup();
+ ConfigNamedGroups({ssl_grp_kem_mlkem768secp256r1});
+
+ Connect();
+ CheckKeys(ssl_kea_ecdh_hybrid, ssl_grp_kem_mlkem768secp256r1,
+ ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256);
+}
+
+TEST_P(TlsKeyExchangeTest, Tls12ClientMlkem768StartNotSupported) {
+ EnsureKeyShareSetup();
+ client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
+ SSL_LIBRARY_VERSION_TLS_1_2);
+ server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
+ SSL_LIBRARY_VERSION_TLS_1_3);
+ client_->DisableAllCiphers();
+ client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);
+ client_->EnableCiphersByKeyExchange(ssl_kea_ecdh_hybrid);
+ EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(
+ client_->ssl_fd(),
+ kECDHEGroups.size() + kEcdhHybridGroups.size()));
+
+ Connect();
+ std::vector<SSLNamedGroup> groups = GetGroupDetails(groups_capture_);
+ for (auto group : groups) {
+ EXPECT_NE(group, ssl_grp_kem_mlkem768x25519);
+ EXPECT_NE(group, ssl_grp_kem_mlkem768secp256r1);
+ }
+}
+
+TEST_P(TlsKeyExchangeTest13, Tls12ServerMlkem768x25519NotSupported) {
+ if (variant_ == ssl_variant_datagram) {
+ /* Bug 1874451 - reenable this test */
+ return;
+ }
+
+ EnsureKeyShareSetup();
+
+ client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
+ SSL_LIBRARY_VERSION_TLS_1_3);
+ server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
+ SSL_LIBRARY_VERSION_TLS_1_2);
+
+ client_->DisableAllCiphers();
+ client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);
+ client_->EnableCiphersByKeyExchange(ssl_kea_ecdh_hybrid);
+ client_->ConfigNamedGroups(
+ {ssl_grp_kem_mlkem768x25519, ssl_grp_ec_curve25519});
+ EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1));
+
+ server_->EnableCiphersByKeyExchange(ssl_kea_ecdh);
+ server_->EnableCiphersByKeyExchange(ssl_kea_ecdh_hybrid);
+ server_->ConfigNamedGroups(
+ {ssl_grp_kem_mlkem768x25519, ssl_grp_ec_curve25519});
+
+ Connect();
+ CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_sign,
+ ssl_sig_rsa_pss_rsae_sha256);
+}
+
+TEST_P(TlsKeyExchangeTest13, Tls12ServerMlkem768Secp256r1NotSupported) {
+ if (variant_ == ssl_variant_datagram) {
+ /* Bug 1874451 - reenable this test */
+ return;
+ }
+
+ EnsureKeyShareSetup();
+
+ client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
+ SSL_LIBRARY_VERSION_TLS_1_3);
+ server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
+ SSL_LIBRARY_VERSION_TLS_1_2);
+
+ client_->DisableAllCiphers();
+ client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);
+ client_->EnableCiphersByKeyExchange(ssl_kea_ecdh_hybrid);
+ client_->ConfigNamedGroups(
+ {ssl_grp_kem_mlkem768secp256r1, ssl_grp_ec_secp256r1});
+ EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1));
+
+ server_->EnableCiphersByKeyExchange(ssl_kea_ecdh);
+ server_->EnableCiphersByKeyExchange(ssl_kea_ecdh_hybrid);
+ server_->ConfigNamedGroups(
+ {ssl_grp_kem_mlkem768secp256r1, ssl_grp_ec_secp256r1});
+
+ Connect();
+ CheckKeys(ssl_kea_ecdh, ssl_grp_ec_secp256r1, ssl_auth_rsa_sign,
+ ssl_sig_rsa_pss_rsae_sha256);
+}
+
+TEST_P(TlsKeyExchangeTest13, Mlkem768x25519ClientDisabledByPolicy) {
+ EnsureKeyShareSetup();
+ client_->SetPolicy(SEC_OID_MLKEM768X25519, 0, NSS_USE_ALG_IN_SSL_KX);
+ ConfigNamedGroups({ssl_grp_kem_mlkem768x25519, ssl_grp_ec_secp256r1});
+
+ Connect();
+ CheckKEXDetails({ssl_grp_ec_secp256r1}, {ssl_grp_ec_secp256r1});
+}
+
+TEST_P(TlsKeyExchangeTest13, Mlkem768x25519ServerDisabledByPolicy) {
+ EnsureKeyShareSetup();
+ server_->SetPolicy(SEC_OID_MLKEM768X25519, 0, NSS_USE_ALG_IN_SSL_KX);
+ ConfigNamedGroups({ssl_grp_kem_mlkem768x25519, ssl_grp_ec_secp256r1});
+
+ Connect();
+ CheckKEXDetails({ssl_grp_kem_mlkem768x25519, ssl_grp_ec_secp256r1},
+ {ssl_grp_kem_mlkem768x25519}, ssl_grp_ec_secp256r1);
+}
+
+TEST_P(TlsKeyExchangeTest13, Mlkem768Secp256r1ClientDisabledByPolicy) {
+ EnsureKeyShareSetup();
+ client_->SetPolicy(SEC_OID_MLKEM768SECP256R1, 0, NSS_USE_ALG_IN_SSL_KX);
+ ConfigNamedGroups({ssl_grp_kem_mlkem768secp256r1, ssl_grp_ec_secp256r1});
+
+ Connect();
+ CheckKEXDetails({ssl_grp_ec_secp256r1}, {ssl_grp_ec_secp256r1});
+}
+
+TEST_P(TlsKeyExchangeTest13, Mlkem768Secp256r1ServerDisabledByPolicy) {
+ if (variant_ == ssl_variant_datagram) {
+ /* Bug 1874451 - reenable this test */
+ return;
+ }
+ EnsureKeyShareSetup();
+ server_->SetPolicy(SEC_OID_MLKEM768SECP256R1, 0, NSS_USE_ALG_IN_SSL_KX);
+ ConfigNamedGroups({ssl_grp_kem_mlkem768secp256r1, ssl_grp_ec_secp256r1});
+
+ Connect();
+ CheckKEXDetails({ssl_grp_kem_mlkem768secp256r1, ssl_grp_ec_secp256r1},
+ {ssl_grp_kem_mlkem768secp256r1}, ssl_grp_ec_secp256r1);
+}
+
+static void CheckECDHShareReuse(
+ const std::shared_ptr<TlsExtensionCapture>& capture) {
+ EXPECT_TRUE(capture->captured());
+ const DataBuffer& ext = capture->extension();
+ DataBuffer hybrid_share[4];
+ DataBuffer ecdh_share[4];
+ int hybrid_offset[4];
+ SSLNamedGroup hybrid_ec_type[4];
+ SSLNamedGroup ec_type[4];
+ int ecdh_index[4];
+ int nextHybrid = 0;
+ int nextECDH = 0;
+
+ size_t offset = 0;
+ uint32_t ext_len;
+ ext.Read(0, 2, &ext_len);
+ EXPECT_EQ(ext.len() - 2, ext_len);
+ offset += 2;
+
+ uint32_t named_group;
+ uint32_t named_group_len;
+ ext.Read(offset, 2, &named_group);
+ ext.Read(offset + 2, 2, &named_group_len);
+ while (offset < ext.len()) {
+ switch (named_group) {
+ case ssl_grp_kem_mlkem768x25519:
+ hybrid_share[nextHybrid] = DataBuffer(ext.data() + offset + 2 + 2, named_group_len);
+ hybrid_offset[nextHybrid] = KYBER768_PUBLIC_KEY_BYTES;
+ hybrid_ec_type[nextHybrid] = ssl_grp_ec_curve25519;
+ nextHybrid++;
+ break;
+ case ssl_grp_kem_mlkem768secp256r1:
+ hybrid_share[nextHybrid] = DataBuffer(ext.data() + offset + 2 + 2, named_group_len);
+ hybrid_offset[nextHybrid] = 0;
+ hybrid_ec_type[nextHybrid] = ssl_grp_ec_secp256r1;
+ nextHybrid++;
+ case ssl_grp_ec_curve25519:
+ case ssl_grp_ec_secp256r1:
+ ecdh_share[nextECDH] = DataBuffer(ext.data() + offset + 2 + 2, named_group_len);
+ ec_type[nextECDH] = (SSLNamedGroup) named_group;
+ nextECDH++;
+ }
+ offset += 2 + 2 + named_group_len;
+ ext.Read(offset, 2, &named_group);
+ ext.Read(offset + 2, 2, &named_group_len);
+ }
+ EXPECT_EQ(offset, ext.len());
+
+ ASSERT_TRUE(nextECDH > 0);
+ ASSERT_TRUE(nextHybrid > 0);
+ /* setup the hybrid ecdh indeces */
+ for (int i=0; i < nextHybrid; i++) {
+ ecdh_index[i] = -1;
+ for (int j=0; j < nextECDH; j++) {
+ if (hybrid_ec_type[i] == ec_type[j]) {
+ ecdh_index[i] = j;
+ break;
+ }
+ }
+ ASSERT_TRUE(ecdh_index[i] != -1);
+ }
+ for (int i=0; i < nextECDH; i++) {
+ ASSERT_TRUE(ecdh_share[i].data());
+ }
+ for (int i=0; i < nextHybrid; i++) {
+ int j = ecdh_index[i];
+ ASSERT_TRUE(hybrid_share[i].data());
+ ASSERT_GT(hybrid_share[i].len(), ecdh_share[j].len());
+ EXPECT_EQ(0, memcmp(hybrid_share[i].data() + hybrid_offset[i],
+ ecdh_share[j].data(), ecdh_share[j].len()));
+ }
+}
+
+TEST_P(TlsKeyExchangeTest13, Mlkem768x25519ShareReuseFirst) {
+ if (variant_ == ssl_variant_datagram) {
+ /* Bug 1874451 - reenable this test */
+ return;
+ }
+ EnsureKeyShareSetup();
+ ConfigNamedGroups({ssl_grp_kem_mlkem768x25519, ssl_grp_ec_curve25519});
+ EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1));
+
+ Connect();
+
+ CheckKEXDetails({ssl_grp_kem_mlkem768x25519, ssl_grp_ec_curve25519},
+ {ssl_grp_kem_mlkem768x25519, ssl_grp_ec_curve25519});
+ CheckECDHShareReuse(shares_capture_);
+}
+
+TEST_P(TlsKeyExchangeTest13, Mlkem768x25519ShareReuseSecond) {
+ if (variant_ == ssl_variant_datagram) {
+ /* Bug 1874451 - reenable this test */
+ return;
+ }
+ EnsureKeyShareSetup();
+ ConfigNamedGroups({ssl_grp_ec_curve25519, ssl_grp_kem_mlkem768x25519});
+ EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1));
+
+ Connect();
+
+ CheckKEXDetails({ssl_grp_ec_curve25519, ssl_grp_kem_mlkem768x25519},
+ {ssl_grp_ec_curve25519, ssl_grp_kem_mlkem768x25519});
+ CheckECDHShareReuse(shares_capture_);
+}
+
+TEST_P(TlsKeyExchangeTest13, Mlkem768Secp256r1ShareReuseFirst) {
+ if (variant_ == ssl_variant_datagram) {
+ /* Bug 1874451 - reenable this test */
+ return;
+ }
+ EnsureKeyShareSetup();
+ ConfigNamedGroups({ssl_grp_kem_mlkem768secp256r1, ssl_grp_ec_secp256r1});
+ EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1));
+
+ Connect();
+
+ CheckKEXDetails({ssl_grp_kem_mlkem768secp256r1, ssl_grp_ec_secp256r1},
+ {ssl_grp_kem_mlkem768secp256r1, ssl_grp_ec_secp256r1});
+ CheckECDHShareReuse(shares_capture_);
+}
+
+TEST_P(TlsKeyExchangeTest13, Mlkem768Secp256r1ShareReuseSecond) {
+ if (variant_ == ssl_variant_datagram) {
+ /* Bug 1874451 - reenable this test */
+ return;
+ }
+ EnsureKeyShareSetup();
+ ConfigNamedGroups({ssl_grp_ec_secp256r1, ssl_grp_kem_mlkem768secp256r1});
+ EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1));
+
+ Connect();
+
+ CheckKEXDetails({ssl_grp_ec_secp256r1, ssl_grp_kem_mlkem768secp256r1},
+ {ssl_grp_ec_secp256r1, ssl_grp_kem_mlkem768secp256r1});
+ CheckECDHShareReuse(shares_capture_);
+}
+
+class Mlkem768x25519ShareDamager : public TlsExtensionFilter {
+ public:
+ typedef enum {
+ downgrade,
+ extend,
+ truncate,
+ zero_ecdh,
+ modify_ecdh,
+ modify_mlkem,
+ modify_mlkem_pubkey_mod_q,
+ } damage_type;
+
+ Mlkem768x25519ShareDamager(const std::shared_ptr<TlsAgent>& a,
+ damage_type damage)
+ : TlsExtensionFilter(a), damage_(damage) {}
+
+ virtual PacketFilter::Action FilterExtension(uint16_t extension_type,
+ const DataBuffer& input,
+ DataBuffer* output) {
+ if (extension_type != ssl_tls13_key_share_xtn) {
+ return KEEP;
+ }
+
+ // Find the Mlkem768x25519 share
+ size_t offset = 0;
+ if (agent()->role() == TlsAgent::CLIENT) {
+ offset += 2; // skip KeyShareClientHello length
+ }
+
+ uint32_t named_group;
+ uint32_t named_group_len;
+ input.Read(offset, 2, &named_group);
+ input.Read(offset + 2, 2, &named_group_len);
+ while (named_group != ssl_grp_kem_mlkem768x25519) {
+ offset += 2 + 2 + named_group_len;
+ input.Read(offset, 2, &named_group);
+ input.Read(offset + 2, 2, &named_group_len);
+ }
+ EXPECT_EQ(named_group, ssl_grp_kem_mlkem768x25519);
+
+ DataBuffer hybrid_key_share(input.data() + offset, 2 + 2 + named_group_len);
+
+ // Damage the Mlkem768x25519 share
+ uint32_t mlkem_component_len =
+ hybrid_key_share.len() - 2 - 2 - X25519_PUBLIC_KEY_BYTES;
+ unsigned char* ecdh_component =
+ hybrid_key_share.data() + 2 + 2 + mlkem_component_len;
+ unsigned char* mlkem_component = hybrid_key_share.data() + 2 + 2;
+ switch (damage_) {
+ case Mlkem768x25519ShareDamager::downgrade:
+ // Downgrade a Mlkem768x25519 share to X25519
+ memcpy(mlkem_component, ecdh_component, X25519_PUBLIC_KEY_BYTES);
+ hybrid_key_share.Truncate(2 + 2 + X25519_PUBLIC_KEY_BYTES);
+ hybrid_key_share.Write(0, ssl_grp_ec_curve25519, 2);
+ hybrid_key_share.Write(2, X25519_PUBLIC_KEY_BYTES, 2);
+ break;
+ case Mlkem768x25519ShareDamager::truncate:
+ // Truncate a Mlkem768x25519 share before the X25519 component
+ hybrid_key_share.Truncate(2 + 2 + mlkem_component_len);
+ hybrid_key_share.Write(2, mlkem_component_len, 2);
+ break;
+ case Mlkem768x25519ShareDamager::extend:
+ // Append 4 bytes to a Mlkem768x25519 share
+ uint32_t current_len;
+ hybrid_key_share.Read(2, 2, &current_len);
+ hybrid_key_share.Write(hybrid_key_share.len(), current_len, 4);
+ hybrid_key_share.Write(2, current_len + 4, 2);
+ break;
+ case Mlkem768x25519ShareDamager::zero_ecdh:
+ // Replace an X25519 component with 0s
+ memset(ecdh_component, 0, X25519_PUBLIC_KEY_BYTES);
+ break;
+ case Mlkem768x25519ShareDamager::modify_ecdh:
+ // Flip a bit in the X25519 component
+ ecdh_component[0] ^= 0x01;
+ break;
+ case Mlkem768x25519ShareDamager::modify_mlkem:
+ // Flip a bit in the mlkem component
+ mlkem_component[0] ^= 0x01;
+ break;
+ case Mlkem768x25519ShareDamager::modify_mlkem_pubkey_mod_q:
+ if (agent()->role() == TlsAgent::CLIENT) {
+ // Replace the client's public key with an sequence of 12-bit values
+ // in the same equivalence class mod 3329. The FIPS-203 input
+ // validation check should fail.
+ for (size_t i = 0; i < mlkem_component_len - 32; i += 3) {
+ // Pairs of 12-bit coefficients are packed into 3 bytes.
+ // Unpack them, change equivalence class if possible, and repack.
+ uint16_t coeff0 =
+ mlkem_component[i] | ((mlkem_component[i + 1] & 0x0f) << 8);
+ uint16_t coeff1 = (mlkem_component[i + 1] & 0xf0 >> 4) |
+ ((mlkem_component[i + 2]) << 4);
+ if (coeff0 < 4096 - 3329) {
+ coeff0 += 3329;
+ }
+ if (coeff1 < 4096 - 3329) {
+ coeff1 += 3329;
+ }
+ mlkem_component[i] = coeff0;
+ mlkem_component[i + 1] = (coeff0 >> 8) + ((coeff1 & 0x0f) << 4);
+ mlkem_component[i + 2] = coeff1 >> 4;
+ }
+ }
+ break;
+ }
+
+ *output = input;
+ output->Splice(hybrid_key_share, offset, 2 + 2 + named_group_len);
+
+ // Fix the KeyShareClientHello length if necessary
+ if (agent()->role() == TlsAgent::CLIENT &&
+ hybrid_key_share.len() != 2 + 2 + named_group_len) {
+ output->Write(0, output->len() - 2, 2);
+ }
+
+ return CHANGE;
+ }
+
+ private:
+ damage_type damage_;
+};
+
+class TlsMlkem768x25519DamageTest
+ : public TlsConnectTestBase,
+ public ::testing::WithParamInterface<
+ Mlkem768x25519ShareDamager::damage_type> {
+ public:
+ TlsMlkem768x25519DamageTest()
+ : TlsConnectTestBase(ssl_variant_stream, SSL_LIBRARY_VERSION_TLS_1_3) {}
+
+ protected:
+ void Damage(const std::shared_ptr<TlsAgent>& agent) {
+ EnsureTlsSetup();
+ client_->ConfigNamedGroups(
+ {ssl_grp_ec_curve25519, ssl_grp_kem_mlkem768x25519});
+ server_->ConfigNamedGroups(
+ {ssl_grp_kem_mlkem768x25519, ssl_grp_ec_curve25519});
+ EXPECT_EQ(SECSuccess, SSL_SendAdditionalKeyShares(client_->ssl_fd(), 1));
+ MakeTlsFilter<Mlkem768x25519ShareDamager>(agent, GetParam());
+ }
+};
+
+TEST_P(TlsMlkem768x25519DamageTest, DamageClientShare) {
+ Damage(client_);
+
+ switch (GetParam()) {
+ case Mlkem768x25519ShareDamager::extend:
+ case Mlkem768x25519ShareDamager::truncate:
+ ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
+ server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_HYBRID_KEY_SHARE);
+ break;
+ case Mlkem768x25519ShareDamager::zero_ecdh:
+ ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
+ server_->CheckErrorCode(SEC_ERROR_INVALID_KEY);
+ break;
+ case Mlkem768x25519ShareDamager::modify_mlkem_pubkey_mod_q:
+ ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
+ server_->CheckErrorCode(SEC_ERROR_INVALID_ARGS);
+ break;
+ case Mlkem768x25519ShareDamager::downgrade:
+ case Mlkem768x25519ShareDamager::modify_ecdh:
+ case Mlkem768x25519ShareDamager::modify_mlkem:
+ client_->ExpectSendAlert(kTlsAlertBadRecordMac);
+ server_->ExpectSendAlert(kTlsAlertBadRecordMac);
+ ConnectExpectFail();
+ client_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ);
+ server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ);
+ break;
+ }
+}
+
+TEST_P(TlsMlkem768x25519DamageTest, DamageServerShare) {
+ Damage(server_);
+
+ switch (GetParam()) {
+ case Mlkem768x25519ShareDamager::extend:
+ case Mlkem768x25519ShareDamager::truncate:
+ client_->ExpectSendAlert(kTlsAlertIllegalParameter);
+ server_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
+ ConnectExpectFail();
+ client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_HYBRID_KEY_SHARE);
+ break;
+ case Mlkem768x25519ShareDamager::zero_ecdh:
+ client_->ExpectSendAlert(kTlsAlertIllegalParameter);
+ server_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
+ ConnectExpectFail();
+ client_->CheckErrorCode(SEC_ERROR_INVALID_KEY);
+ break;
+ case Mlkem768x25519ShareDamager::downgrade:
+ case Mlkem768x25519ShareDamager::modify_ecdh:
+ case Mlkem768x25519ShareDamager::modify_mlkem:
+ client_->ExpectSendAlert(kTlsAlertBadRecordMac);
+ server_->ExpectSendAlert(kTlsAlertBadRecordMac);
+ ConnectExpectFail();
+ client_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ);
+ server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ);
+ break;
+ case Mlkem768x25519ShareDamager::modify_mlkem_pubkey_mod_q:
+ // The server doesn't send a public key, so nothing is changed.
+ break;
+ }
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ TlsMlkem768x25519DamageTest, TlsMlkem768x25519DamageTest,
+ ::testing::Values(Mlkem768x25519ShareDamager::downgrade,
+ Mlkem768x25519ShareDamager::extend,
+ Mlkem768x25519ShareDamager::truncate,
+ Mlkem768x25519ShareDamager::zero_ecdh,
+ Mlkem768x25519ShareDamager::modify_ecdh,
+ Mlkem768x25519ShareDamager::modify_mlkem,
+ Mlkem768x25519ShareDamager::modify_mlkem_pubkey_mod_q));
+
+} // namespace nss_test
diff -up ./gtests/ssl_gtest/tls_psk_unittest.cc.mlkem ./gtests/ssl_gtest/tls_psk_unittest.cc
--- ./gtests/ssl_gtest/tls_psk_unittest.cc.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./gtests/ssl_gtest/tls_psk_unittest.cc 2024-10-31 14:54:15.462515926 -0700
@@ -68,7 +68,7 @@ TEST_P(Tls13PskTest, NormalExternal) {
AddPsk(scoped_psk_, kPskDummyLabel_, kPskHash_);
Connect();
SendReceive();
- CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_psk, ssl_sig_none);
+ CheckKeys(ssl_kea_ecdh_hybrid, ssl_grp_kem_mlkem768x25519, ssl_auth_psk, ssl_sig_none);
client_->RemovePsk(kPskDummyLabel_);
server_->RemovePsk(kPskDummyLabel_);
@@ -91,7 +91,7 @@ TEST_P(Tls13PskTest, KeyTooLarge) {
AddPsk(scoped_psk_, kPskDummyLabel_, kPskHash_);
Connect();
SendReceive();
- CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_psk, ssl_sig_none);
+ CheckKeys(ssl_kea_ecdh_hybrid, ssl_grp_kem_mlkem768x25519, ssl_auth_psk, ssl_sig_none);
}
// Attempt to use a PSK with the wrong PRF hash.
@@ -117,7 +117,7 @@ TEST_P(Tls13PskTest, LabelMismatch) {
client_->AddPsk(scoped_psk_, std::string("foo"), kPskHash_);
server_->AddPsk(scoped_psk_, std::string("bar"), kPskHash_);
Connect();
- CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+ CheckKeys();
}
SSLHelloRetryRequestAction RetryFirstHello(
@@ -148,7 +148,7 @@ TEST_P(Tls13PskTest, ResPskRetryStateles
Handshake();
CheckConnected();
EXPECT_EQ(2U, cb_called);
- CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+ CheckKeys();
SendReceive();
}
@@ -174,7 +174,7 @@ TEST_P(Tls13PskTest, ExtPskRetryStateles
Handshake();
CheckConnected();
SendReceive();
- CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_psk, ssl_sig_none);
+ CheckKeys(ssl_kea_ecdh_hybrid, ssl_grp_kem_mlkem768x25519, ssl_auth_psk, ssl_sig_none);
}
// Server not configured with PSK and sends a certificate instead of
@@ -182,7 +182,7 @@ TEST_P(Tls13PskTest, ExtPskRetryStateles
TEST_P(Tls13PskTest, ClientOnly) {
client_->AddPsk(scoped_psk_, kPskDummyLabel_, kPskHash_);
Connect();
- CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+ CheckKeys();
}
// Set a PSK, remove psk_key_exchange_modes.
@@ -247,7 +247,7 @@ TEST_P(Tls13PskTest, PreferEpsk) {
Handshake();
CheckConnected();
SendReceive();
- CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_psk, ssl_sig_none);
+ CheckKeys(ssl_kea_ecdh_hybrid, ssl_grp_kem_mlkem768x25519, ssl_auth_psk, ssl_sig_none);
}
// Enable resumption, but connect (initially) with an EPSK.
@@ -260,7 +260,7 @@ TEST_P(Tls13PskTest, SuppressNewSessionT
nst_capture->EnableDecryption();
Connect();
SendReceive();
- CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_psk, ssl_sig_none);
+ CheckKeys(ssl_kea_ecdh_hybrid, ssl_grp_kem_mlkem768x25519, ssl_auth_psk, ssl_sig_none);
EXPECT_EQ(SECFailure, SSL_SendSessionTicket(server_->ssl_fd(), nullptr, 0));
EXPECT_EQ(0U, nst_capture->buffer().len());
if (variant_ == ssl_variant_stream) {
@@ -275,7 +275,7 @@ TEST_P(Tls13PskTest, SuppressNewSessionT
ExpectResumption(RESUME_NONE);
Connect();
SendReceive();
- CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_psk, ssl_sig_none);
+ CheckKeys(ssl_kea_ecdh_hybrid, ssl_grp_kem_mlkem768x25519, ssl_auth_psk, ssl_sig_none);
}
TEST_P(Tls13PskTest, BadConfigValues) {
@@ -314,7 +314,7 @@ TEST_P(Tls13PskTest, FallbackUnsupported
client_->EnableSingleCipher(TLS_AES_128_GCM_SHA256);
Connect();
SendReceive();
- CheckKeys(ssl_kea_ecdh, ssl_auth_rsa_sign);
+ CheckKeys();
}
// That fallback should not occur if there is no cipher overlap.
@@ -342,7 +342,7 @@ TEST_P(Tls13PskTest, SuppressHandshakeCe
Connect();
SendReceive();
- CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_psk, ssl_sig_none);
+ CheckKeys(ssl_kea_ecdh_hybrid, ssl_grp_kem_mlkem768x25519, ssl_auth_psk, ssl_sig_none);
EXPECT_EQ(0U, cr_cert_capture->buffer().len());
}
@@ -422,7 +422,7 @@ TEST_P(Tls13PskTestWithCiphers, 0RttCiph
ExpectEarlyDataAccepted(true);
CheckConnected();
SendReceive();
- CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_psk, ssl_sig_none);
+ CheckKeys(ssl_kea_ecdh_hybrid, ssl_grp_kem_mlkem768x25519, ssl_auth_psk, ssl_sig_none);
}
TEST_P(Tls13PskTestWithCiphers, 0RttMaxEarlyData) {
diff -up ./gtests/ssl_gtest/tls_subcerts_unittest.cc.mlkem ./gtests/ssl_gtest/tls_subcerts_unittest.cc
--- ./gtests/ssl_gtest/tls_subcerts_unittest.cc.mlkem 2024-10-31 14:54:15.441515691 -0700
+++ ./gtests/ssl_gtest/tls_subcerts_unittest.cc 2024-10-31 14:54:15.462515926 -0700
@@ -448,6 +448,7 @@ class ReplaceDCSigScheme : public TlsHan
// Aborted because of incorrect DC signature algorithm indication.
TEST_P(TlsConnectTls13, DCAbortBadExpectedCertVerifyAlg) {
Reset(kEcdsaDelegatorId);
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
client_->EnableDelegatedCredentials();
server_->AddDelegatedCredential(TlsAgent::kServerEcdsa256,
ssl_sig_ecdsa_secp256r1_sha256, kDCValidFor,
@@ -568,6 +569,7 @@ TEST_P(TlsConnectTls13, DCConnectClientN
// Connected without DC because server doesn't support TLS 1.3.
TEST_P(TlsConnectTls13, DCConnectServerNoTls13) {
Reset(kEcdsaDelegatorId);
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
client_->EnableDelegatedCredentials();
server_->AddDelegatedCredential(kDCId, kDCScheme, kDCValidFor, now());
@@ -612,6 +614,7 @@ TEST_P(TlsConnectTls13, DCConnectExpecte
TEST_P(TlsConnectTls13, DCCheckPreliminaryInfo) {
Reset(kEcdsaDelegatorId);
EnsureTlsSetup();
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
client_->EnableDelegatedCredentials();
server_->AddDelegatedCredential(TlsAgent::kServerEcdsa256,
ssl_sig_ecdsa_secp256r1_sha256, kDCValidFor,
@@ -637,6 +640,7 @@ TEST_P(TlsConnectTls13, DCCheckPrelimina
TEST_P(TlsConnectTls13, DCCheckPreliminaryInfoNoDC) {
Reset(kEcdsaDelegatorId);
EnsureTlsSetup();
+ client_->ConfigNamedGroups(kNonPQDHEGroups);
client_->EnableDelegatedCredentials();
auto filter = MakeTlsFilter<TlsHandshakeDropper>(server_);
filter->SetHandshakeTypes(
diff -up ./lib/freebl/kyber.c.mlkem ./lib/freebl/kyber.c
--- ./lib/freebl/kyber.c.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./lib/freebl/kyber.c 2024-10-31 14:54:15.462515926 -0700
@@ -14,6 +14,9 @@
#include "kyber-pqcrystals-ref.h"
#include "kyber.h"
+#include "verified/internal/libcrux_core.h"
+#include "verified/libcrux_mlkem768_portable.h"
+#include "verified/libcrux_mlkem768.h"
/* Consistency check between kyber-pqcrystals-ref.h and kyber.h */
PR_STATIC_ASSERT(KYBER768_PUBLIC_KEY_BYTES == pqcrystals_kyber768_PUBLICKEYBYTES);
@@ -23,12 +26,22 @@ PR_STATIC_ASSERT(KYBER_SHARED_SECRET_BYT
PR_STATIC_ASSERT(KYBER_KEYPAIR_COIN_BYTES == pqcrystals_kyber768_KEYPAIRCOINBYTES);
PR_STATIC_ASSERT(KYBER_ENC_COIN_BYTES == pqcrystals_kyber768_ENCCOINBYTES);
+/* Consistency check between libcrux_mlkem768_portable.h and kyber.h */
+PR_STATIC_ASSERT(KYBER768_PUBLIC_KEY_BYTES == LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE_768);
+PR_STATIC_ASSERT(KYBER768_PRIVATE_KEY_BYTES == LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768);
+PR_STATIC_ASSERT(KYBER768_CIPHERTEXT_BYTES == LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768);
+PR_STATIC_ASSERT(KYBER_SHARED_SECRET_BYTES == LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE);
+PR_STATIC_ASSERT(KYBER_KEYPAIR_COIN_BYTES == 64);
+PR_STATIC_ASSERT(KYBER_ENC_COIN_BYTES == 32);
+
static bool
valid_params(KyberParams params)
{
switch (params) {
case params_kyber768_round3:
case params_kyber768_round3_test_mode:
+ case params_ml_kem768:
+ case params_ml_kem768_test_mode:
return true;
default:
return false;
@@ -41,6 +54,8 @@ valid_pubkey(KyberParams params, const S
switch (params) {
case params_kyber768_round3:
case params_kyber768_round3_test_mode:
+ case params_ml_kem768:
+ case params_ml_kem768_test_mode:
return pubkey && pubkey->len == KYBER768_PUBLIC_KEY_BYTES;
default:
return false;
@@ -53,6 +68,8 @@ valid_privkey(KyberParams params, const
switch (params) {
case params_kyber768_round3:
case params_kyber768_round3_test_mode:
+ case params_ml_kem768:
+ case params_ml_kem768_test_mode:
return privkey && privkey->len == KYBER768_PRIVATE_KEY_BYTES;
default:
return false;
@@ -65,6 +82,8 @@ valid_ciphertext(KyberParams params, con
switch (params) {
case params_kyber768_round3:
case params_kyber768_round3_test_mode:
+ case params_ml_kem768:
+ case params_ml_kem768_test_mode:
return ciphertext && ciphertext->len == KYBER768_CIPHERTEXT_BYTES;
default:
return false;
@@ -77,6 +96,8 @@ valid_secret(KyberParams params, const S
switch (params) {
case params_kyber768_round3:
case params_kyber768_round3_test_mode:
+ case params_ml_kem768:
+ case params_ml_kem768_test_mode:
return secret && secret->len == KYBER_SHARED_SECRET_BYTES;
default:
return false;
@@ -89,6 +110,8 @@ valid_keypair_seed(KyberParams params, c
switch (params) {
case params_kyber768_round3:
case params_kyber768_round3_test_mode:
+ case params_ml_kem768:
+ case params_ml_kem768_test_mode:
return !seed || seed->len == KYBER_KEYPAIR_COIN_BYTES;
default:
return false;
@@ -100,8 +123,10 @@ valid_enc_seed(KyberParams params, const
{
switch (params) {
case params_kyber768_round3:
+ case params_ml_kem768:
return !seed;
case params_kyber768_round3_test_mode:
+ case params_ml_kem768_test_mode:
return !seed || seed->len == KYBER_SHARED_SECRET_BYTES;
default:
return false;
@@ -135,6 +160,10 @@ Kyber_NewKey(KyberParams params, const S
NSS_CLASSIFY(coins, KYBER_KEYPAIR_COIN_BYTES);
if (params == params_kyber768_round3 || params == params_kyber768_round3_test_mode) {
pqcrystals_kyber768_ref_keypair_derand(pubkey->data, privkey->data, coins);
+ } else if (params == params_ml_kem768 || params == params_ml_kem768_test_mode) {
+ libcrux_ml_kem_mlkem768_MlKem768KeyPair keys = libcrux_ml_kem_mlkem768_portable_generate_key_pair(coins);
+ memcpy(pubkey->data, keys.pk.value, KYBER768_PUBLIC_KEY_BYTES);
+ memcpy(privkey->data, keys.sk.value, KYBER768_PRIVATE_KEY_BYTES);
} else {
/* unreachable */
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
@@ -171,6 +200,19 @@ Kyber_Encapsulate(KyberParams params, co
NSS_CLASSIFY(coins, KYBER_ENC_COIN_BYTES);
if (params == params_kyber768_round3 || params == params_kyber768_round3_test_mode) {
pqcrystals_kyber768_ref_enc_derand(ciphertext->data, secret->data, pubkey->data, coins);
+ } else if (params == params_ml_kem768 || params == params_ml_kem768_test_mode) {
+ libcrux_ml_kem_types_MlKemPublicKey_15 pk_value;
+ memcpy(pk_value.value, pubkey->data, KYBER768_PUBLIC_KEY_BYTES);
+
+ bool valid_pk = libcrux_ml_kem_mlkem768_portable_validate_public_key(&pk_value);
+ if (!valid_pk) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ tuple_3c encap = libcrux_ml_kem_mlkem768_portable_encapsulate(&pk_value, coins);
+ memcpy(ciphertext->data, encap.fst.value, KYBER768_CIPHERTEXT_BYTES);
+ memcpy(secret->data, encap.snd, KYBER_SHARED_SECRET_BYTES);
} else {
/* unreachable */
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
@@ -195,6 +237,20 @@ Kyber_Decapsulate(KyberParams params, co
if (params == params_kyber768_round3 || params == params_kyber768_round3_test_mode) {
pqcrystals_kyber768_ref_dec(secret->data, ciphertext->data, privkey->data);
+ } else if (params == params_ml_kem768 || params == params_ml_kem768_test_mode) {
+ libcrux_ml_kem_types_MlKemPrivateKey_55 private_key;
+ memcpy(private_key.value, privkey->data, KYBER768_PRIVATE_KEY_BYTES);
+
+ libcrux_ml_kem_mlkem768_MlKem768Ciphertext cipher_text;
+ memcpy(cipher_text.value, ciphertext->data, KYBER768_CIPHERTEXT_BYTES);
+
+ bool valid = libcrux_ml_kem_mlkem768_portable_validate_private_key(&private_key, &cipher_text);
+ if (!valid) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+
+ libcrux_ml_kem_mlkem768_portable_decapsulate(&private_key, &cipher_text, secret->data);
} else {
// unreachable
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
diff -up ./lib/freebl/Makefile.mlkem ./lib/freebl/Makefile
--- ./lib/freebl/Makefile.mlkem 2024-10-31 14:54:15.437515647 -0700
+++ ./lib/freebl/Makefile 2024-10-31 14:54:15.462515926 -0700
@@ -610,6 +610,14 @@ endif # NSS_DISABLE_CHACHAPOLY
VERIFIED_SRCS += Hacl_Hash_SHA3.c Hacl_P256.c Hacl_P384.c Hacl_P521.c
VERIFIED_SRCS += Hacl_Ed25519.c
VERIFIED_SRCS += Hacl_Curve25519_51.c
+VERIFIED_SRCS += libcrux_mlkem768_portable.c libcrux_mlkem_portable.c libcrux_core.c
+
+# Bug 1918767 / Bug 1918711 - by setting KRML_MUSTINLINE=inline here, we
+# avoid it being defined to `inline __forceinline` (for msvc) or `inline
+# __attribute__((always_inline))` (for gcc/clang) in
+# verified/karamel/include/krml/internal/target.h. These other
+# configurations can cause excessive stack usage.
+DEFINES += -DKRML_MUSTINLINE=inline
ifeq (,$(filter-out x86_64 aarch64,$(CPU_ARCH)))
# All 64-bit architectures get the 64 bit version.
diff -up ./lib/freebl/verified/eurydice_glue.h.mlkem ./lib/freebl/verified/eurydice_glue.h
--- ./lib/freebl/verified/eurydice_glue.h.mlkem 2024-10-31 14:54:15.462515926 -0700
+++ ./lib/freebl/verified/eurydice_glue.h 2024-10-31 14:54:15.462515926 -0700
@@ -0,0 +1,385 @@
+#pragma once
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef _MSC_VER
+#include <intrin.h>
+#endif
+
+#include "krml/internal/target.h"
+#include "krml/lowstar_endianness.h"
+
+#define LowStar_Ignore_ignore(e, t, _ret_t) ((void)e)
+
+// SLICES, ARRAYS, ETC.
+
+#if defined(__cplusplus)
+#define CLITERAL(type) type
+#else
+#define CLITERAL(type) (type)
+#endif
+
+// We represent a slice as a pair of an (untyped) pointer, along with the length
+// of the slice, i.e. the number of elements in the slice (this is NOT the
+// number of bytes). This design choice has two important consequences.
+// - if you need to use `ptr`, you MUST cast it to a proper type *before*
+// performing pointer
+// arithmetic on it (remember that C desugars pointer arithmetic based on the
+// type of the address)
+// - if you need to use `len` for a C style function (e.g. memcpy, memcmp), you
+// need to multiply it
+// by sizeof t, where t is the type of the elements.
+typedef struct {
+ void *ptr;
+ size_t len;
+} Eurydice_slice;
+
+// Helper macro to create a slice out of a pointer x, a start index in x
+// (included), and an end index in x (excluded). The argument x must be suitably
+// cast to something that can decay (see remark above about how pointer
+// arithmetic works in C), meaning either pointer or array type.
+#define EURYDICE_SLICE(x, start, end) \
+ (CLITERAL(Eurydice_slice){ .ptr = (void *)(x + start), .len = end - start })
+#define EURYDICE_SLICE_LEN(s, _) s.len
+// This macro is a pain because in case the dereferenced element type is an
+// array, you cannot simply write `t x` as it would yield `int[4] x` instead,
+// which is NOT correct C syntax, so we add a dedicated phase in Eurydice that
+// adds an extra argument to this macro at the last minute so that we have the
+// correct type of *pointers* to elements.
+#define Eurydice_slice_index(s, i, t, t_ptr_t) (((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_array_repeat(dst, len, init, t) \
+ ERROR "should've been desugared"
+#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 core_array_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__u32_8__to_be_bytes(uint32_t src, uint8_t dst[4])
+{
+ // TODO: why not store32_be?
+ uint32_t x = htobe32(src);
+ memcpy(dst, &x, 4);
+}
+
+static inline uint32_t
+core_num__u32_8__from_le_bytes(uint8_t buf[4])
+{
+ return load32_le(buf);
+}
+
+static inline void
+core_num__u64_9__to_le_bytes(uint64_t v, uint8_t buf[8])
+{
+ store64_le(buf, v);
+}
+static inline uint64_t
+core_num__u64_9__from_le_bytes(uint8_t buf[8])
+{
+ return load64_le(buf);
+}
+
+static inline int64_t
+core_convert_num___core__convert__From_i32__for_i64__59__from(int32_t x)
+{
+ return x;
+}
+
+static inline uint64_t
+core_convert_num___core__convert__From_u8__for_u64__66__from(uint8_t x)
+{
+ return x;
+}
+
+static inline uint64_t
+core_convert_num___core__convert__From_u16__for_u64__70__from(uint16_t x)
+{
+ return x;
+}
+
+static inline size_t
+core_convert_num___core__convert__From_u16__for_usize__96__from(uint16_t x)
+{
+ return x;
+}
+
+static inline uint32_t
+core_num__u8_6__count_ones(uint8_t x0)
+{
+#ifdef _MSC_VER
+ return __popcnt(x0);
+#else
+ return __builtin_popcount(x0);
+#endif
+}
+
+// unsigned overflow wraparound semantics in C
+static inline uint16_t
+core_num__u16_7__wrapping_add(uint16_t x, uint16_t y)
+{
+ return x + y;
+}
+static inline uint8_t
+core_num__u8_6__wrapping_sub(uint8_t x, uint8_t y)
+{
+ return x - y;
+}
+
+static inline void
+core_ops_arith__i32_319__add_assign(int32_t *x0,
+ int32_t *x1)
+{
+ *x0 = *x0 + *x1;
+}
+
+static inline uint8_t
+Eurydice_bitand_pv_u8(uint8_t *p, uint8_t v)
+{
+ return (*p) & v;
+}
+static inline uint8_t
+Eurydice_shr_pv_u8(uint8_t *p, int32_t v)
+{
+ return (*p) >> v;
+}
+
+#define core_num_nonzero_private_NonZeroUsizeInner size_t
+static inline core_num_nonzero_private_NonZeroUsizeInner
+core_num_nonzero_private___core__clone__Clone_for_core__num__nonzero__private__NonZeroUsizeInner__26__clone(
+ core_num_nonzero_private_NonZeroUsizeInner *x0)
+{
+ return *x0;
+}
+
+// ITERATORS
+#define Eurydice_range_iter_next(iter_ptr, t, ret_t) \
+ (((iter_ptr)->start == (iter_ptr)->end) \
+ ? (CLITERAL(ret_t){ .tag = core_option_None }) \
+ : (CLITERAL(ret_t){ .tag = core_option_Some, \
+ .f0 = (iter_ptr)->start++ }))
+
+// Old name (TODO: remove once everyone has upgraded to the latest Charon)
+#define core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___3__next \
+ Eurydice_range_iter_next
+
+#define core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next \
+ Eurydice_range_iter_next
+
+// See note in karamel/lib/Inlining.ml if you change this
+#define Eurydice_into_iter(x, t, _ret_t) (x)
+#define core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I___into_iter \
+ Eurydice_into_iter
+// This name changed on 20240627
+#define core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter \
+ Eurydice_into_iter
+
+typedef struct {
+ Eurydice_slice slice;
+ size_t chunk_size;
+} Eurydice_chunks;
+
+// Can't use macros Eurydice_slice_subslice_{to,from} because they require a
+// type, and this static inline function cannot receive a type as an argument.
+// Instead, we receive the element size and use it to peform manual offset
+// computations rather than going through the macros.
+static inline Eurydice_slice
+chunk_next(Eurydice_chunks *chunks,
+ size_t element_size)
+{
+ size_t chunk_size = chunks->slice.len >= chunks->chunk_size
+ ? chunks->chunk_size
+ : chunks->slice.len;
+ Eurydice_slice curr_chunk;
+ curr_chunk.ptr = chunks->slice.ptr;
+ curr_chunk.len = chunk_size;
+ chunks->slice.ptr = (char *)(chunks->slice.ptr) + chunk_size * element_size;
+ chunks->slice.len = chunks->slice.len - chunk_size;
+ return curr_chunk;
+}
+
+#define core_slice___Slice_T___chunks(slice_, sz_, t, _ret_t) \
+ ((Eurydice_chunks){ .slice = slice_, .chunk_size = sz_ })
+#define core_slice___Slice_T___chunks_exact(slice_, sz_, t, _ret_t) \
+ ((Eurydice_chunks){ \
+ .slice = { .ptr = slice_.ptr, .len = slice_.len - (slice_.len % sz_) }, \
+ .chunk_size = sz_ })
+#define core_slice_iter_Chunks Eurydice_chunks
+#define core_slice_iter_ChunksExact Eurydice_chunks
+#define Eurydice_chunks_next(iter, t, ret_t) \
+ (((iter)->slice.len == 0) ? ((ret_t){ .tag = core_option_None }) \
+ : ((ret_t){ .tag = core_option_Some, \
+ .f0 = chunk_next(iter, sizeof(t)) }))
+#define core_slice_iter___core__iter__traits__iterator__Iterator_for_core__slice__iter__Chunks__a__T___70__next \
+ Eurydice_chunks_next
+// This name changed on 20240627
+#define core_slice_iter___core__iter__traits__iterator__Iterator_for_core__slice__iter__Chunks__a__T___71__next \
+ Eurydice_chunks_next
+#define core_slice_iter__core__slice__iter__ChunksExact__a__T__89__next( \
+ iter, t, _ret_t) \
+ core_slice_iter__core__slice__iter__Chunks__a__T__70__next(iter, t)
+
+typedef struct {
+ Eurydice_slice s;
+ size_t index;
+} Eurydice_slice_iterator;
+
+#define core_slice___Slice_T___iter(x, t, _ret_t) \
+ ((Eurydice_slice_iterator){ .s = x, .index = 0 })
+#define core_slice_iter_Iter Eurydice_slice_iterator
+#define core_slice_iter__core__slice__iter__Iter__a__T__181__next(iter, t, \
+ ret_t) \
+ (((iter)->index == (iter)->s.len) \
+ ? (CLITERAL(ret_t){ .tag = core_option_None }) \
+ : (CLITERAL(ret_t){ \
+ .tag = core_option_Some, \
+ .f0 = ((iter)->index++, \
+ &((t *)((iter)->s.ptr))[(iter)->index - 1]) }))
+
+// STRINGS
+
+typedef const char *Prims_string;
+
+// MISC (UNTESTED)
+
+typedef void *core_fmt_Formatter;
+typedef void *core_fmt_Arguments;
+typedef void *core_fmt_rt_Argument;
+#define core_fmt_rt__core__fmt__rt__Argument__a__1__new_display(x1, x2, x3, \
+ x4) \
+ NULL
+
+// VECTORS (ANCIENT, POSSIBLY UNTESTED)
+
+/* For now these are passed by value -- three words. We could conceivably change
+ * the representation to heap-allocate this struct and only pass around the
+ * pointer (one word). */
+typedef struct {
+ void *ptr;
+ size_t len; /* the number of elements */
+ size_t alloc_size; /* the size of the allocation, in number of BYTES */
+} Eurydice_vec_s, *Eurydice_vec;
+
+/* Here, we set everything to zero rather than use a non-standard GCC
+ * statement-expression -- this suitably initializes ptr to NULL and len and
+ * size to 0. */
+#define EURYDICE_VEC_NEW(_) calloc(1, sizeof(Eurydice_vec_s))
+#define EURYDICE_VEC_PUSH(v, x, t) \
+ do { \
+ /* Grow the vector if capacity has been reached. */ \
+ if (v->len == v->alloc_size / sizeof(t)) { \
+ /* Assuming that this does not exceed SIZE_MAX, because code proven \
+ * correct by Aeneas. Would this even happen in practice? */ \
+ size_t new_size; \
+ if (v->alloc_size == 0) \
+ new_size = 8 * sizeof(t); \
+ else if (v->alloc_size <= SIZE_MAX / 2) \
+ /* TODO: discuss growth policy */ \
+ new_size = 2 * v->alloc_size; \
+ else \
+ new_size = (SIZE_MAX / sizeof(t)) * sizeof(t); \
+ v->ptr = realloc(v->ptr, new_size); \
+ v->alloc_size = new_size; \
+ } \
+ ((t *)v->ptr)[v->len] = x; \
+ v->len++; \
+ } while (0)
+
+#define EURYDICE_VEC_DROP(v, t) \
+ do { \
+ free(v->ptr); \
+ free(v); \
+ } while (0)
+
+#define EURYDICE_VEC_INDEX(v, i, t) &((t *)v->ptr)[i]
+#define EURYDICE_VEC_LEN(v, t) (v)->len
+
+/* TODO: remove GCC-isms */
+#define EURYDICE_BOX_NEW(x, t) \
+ ({ \
+ t *p = malloc(sizeof(t)); \
+ *p = x; \
+ p; \
+ })
+
+#define EURYDICE_REPLACE(ptr, new_v, t) \
+ ({ \
+ t old_v = *ptr; \
+ *ptr = new_v; \
+ old_v; \
+ })
+
+#if defined(__cplusplus)
+}
+#endif
diff -up ./lib/freebl/verified/internal/libcrux_core.h.mlkem ./lib/freebl/verified/internal/libcrux_core.h
--- ./lib/freebl/verified/internal/libcrux_core.h.mlkem 2024-10-31 14:54:15.462515926 -0700
+++ ./lib/freebl/verified/internal/libcrux_core.h 2024-10-31 14:54:15.462515926 -0700
@@ -0,0 +1,491 @@
+/*
+ * 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: b351338f6a84c7a1afc27433eb0ffdc668b3581d
+ * Eurydice: 7efec1624422fd5e94388ef06b9c76dfe7a48d46
+ * Karamel: c96fb69d15693284644d6aecaa90afa37e4de8f0
+ * F*: 58c915a86a2c07c8eca8d9deafd76cb7a91f0eb7
+ * Libcrux: 6ff01fb3c57ff29ecb59bc62d9dc7fd231060cfb
+ */
+
+#ifndef __internal_libcrux_core_H
+#define __internal_libcrux_core_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include "../libcrux_core.h"
+#include "eurydice_glue.h"
+
+#define CORE_NUM__U32_8__BITS (32U)
+
+static inline uint32_t core_num__u8_6__count_ones(uint8_t x0);
+
+#define LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE ((size_t)32U)
+
+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]);
+
+#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_Keypair1024_s {
+ uint8_t fst[1536U];
+ uint8_t snd[1568U];
+} libcrux_ml_kem_utils_extraction_helper_Keypair1024;
+
+typedef struct libcrux_ml_kem_utils_extraction_helper_Keypair512_s {
+ uint8_t fst[768U];
+ uint8_t snd[800U];
+} libcrux_ml_kem_utils_extraction_helper_Keypair512;
+
+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;
+
+/**
+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= 1568
+*/
+libcrux_ml_kem_types_MlKemPublicKey_1f libcrux_ml_kem_types_from_b6_961(
+ uint8_t value[1568U]);
+
+/**
+ 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= 3168
+- PUBLIC_KEY_SIZE= 1568
+*/
+libcrux_ml_kem_mlkem1024_MlKem1024KeyPair libcrux_ml_kem_types_from_17_821(
+ libcrux_ml_kem_types_MlKemPrivateKey_95 sk,
+ libcrux_ml_kem_types_MlKemPublicKey_1f 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= 3168
+*/
+libcrux_ml_kem_types_MlKemPrivateKey_95 libcrux_ml_kem_types_from_05_891(
+ uint8_t value[3168U]);
+
+/**
+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= 1568
+*/
+libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext libcrux_ml_kem_types_from_01_331(
+ uint8_t value[1568U]);
+
+/**
+ 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= 1568
+*/
+uint8_t *libcrux_ml_kem_types_as_slice_cb_3d1(
+ libcrux_ml_kem_types_MlKemPublicKey_1f *self);
+
+/**
+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= 1568
+*/
+Eurydice_slice libcrux_ml_kem_types_as_ref_00_d81(
+ libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *self);
+
+/**
+ Pad the `slice` with `0`s at the end.
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.utils.into_padded_array
+with const generics
+- LEN= 1600
+*/
+void libcrux_ml_kem_utils_into_padded_array_6d4(Eurydice_slice slice,
+ uint8_t ret[1600U]);
+
+/**
+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
+*/
+libcrux_ml_kem_types_MlKemPublicKey_15 libcrux_ml_kem_types_from_b6_960(
+ uint8_t value[1184U]);
+
+/**
+ 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
+*/
+libcrux_ml_kem_mlkem768_MlKem768KeyPair libcrux_ml_kem_types_from_17_820(
+ libcrux_ml_kem_types_MlKemPrivateKey_55 sk,
+ libcrux_ml_kem_types_MlKemPublicKey_15 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
+*/
+libcrux_ml_kem_types_MlKemPrivateKey_55 libcrux_ml_kem_types_from_05_890(
+ uint8_t value[2400U]);
+
+/**
+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
+*/
+libcrux_ml_kem_mlkem768_MlKem768Ciphertext libcrux_ml_kem_types_from_01_330(
+ uint8_t value[1088U]);
+
+/**
+ 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
+*/
+uint8_t *libcrux_ml_kem_types_as_slice_cb_3d0(
+ libcrux_ml_kem_types_MlKemPublicKey_15 *self);
+
+/**
+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
+*/
+Eurydice_slice libcrux_ml_kem_types_as_ref_00_d80(
+ libcrux_ml_kem_mlkem768_MlKem768Ciphertext *self);
+
+/**
+ 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
+*/
+void libcrux_ml_kem_utils_into_padded_array_6d3(Eurydice_slice slice,
+ uint8_t ret[1120U]);
+
+/**
+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= 800
+*/
+libcrux_ml_kem_types_MlKemPublicKey_be libcrux_ml_kem_types_from_b6_96(
+ uint8_t value[800U]);
+
+/**
+ 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= 1632
+- PUBLIC_KEY_SIZE= 800
+*/
+libcrux_ml_kem_types_MlKemKeyPair_cb libcrux_ml_kem_types_from_17_82(
+ libcrux_ml_kem_types_MlKemPrivateKey_5e sk,
+ libcrux_ml_kem_types_MlKemPublicKey_be 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= 1632
+*/
+libcrux_ml_kem_types_MlKemPrivateKey_5e libcrux_ml_kem_types_from_05_89(
+ uint8_t value[1632U]);
+
+/**
+A monomorphic instance of core.result.Result
+with types uint8_t[32size_t], core_array_TryFromSliceError
+
+*/
+typedef struct core_result_Result_00_s {
+ core_result_Result_86_tags tag;
+ union {
+ uint8_t case_Ok[32U];
+ core_array_TryFromSliceError case_Err;
+ } val;
+} core_result_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
+
+*/
+void core_result_unwrap_41_33(core_result_Result_00 self, uint8_t ret[32U]);
+
+/**
+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= 768
+*/
+libcrux_ml_kem_types_MlKemCiphertext_e8 libcrux_ml_kem_types_from_01_33(
+ uint8_t value[768U]);
+
+/**
+ 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= 800
+*/
+uint8_t *libcrux_ml_kem_types_as_slice_cb_3d(
+ libcrux_ml_kem_types_MlKemPublicKey_be *self);
+
+/**
+ 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
+*/
+void libcrux_ml_kem_utils_into_padded_array_6d2(Eurydice_slice slice,
+ uint8_t ret[33U]);
+
+/**
+ 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
+*/
+void libcrux_ml_kem_utils_into_padded_array_6d1(Eurydice_slice slice,
+ uint8_t ret[34U]);
+
+/**
+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= 768
+*/
+Eurydice_slice libcrux_ml_kem_types_as_ref_00_d8(
+ libcrux_ml_kem_types_MlKemCiphertext_e8 *self);
+
+/**
+ Pad the `slice` with `0`s at the end.
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.utils.into_padded_array
+with const generics
+- LEN= 800
+*/
+void libcrux_ml_kem_utils_into_padded_array_6d0(Eurydice_slice slice,
+ uint8_t ret[800U]);
+
+/**
+ 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
+*/
+void libcrux_ml_kem_utils_into_padded_array_6d(Eurydice_slice slice,
+ uint8_t ret[64U]);
+
+/**
+A monomorphic instance of core.result.Result
+with types uint8_t[24size_t], core_array_TryFromSliceError
+
+*/
+typedef struct core_result_Result_6f_s {
+ core_result_Result_86_tags tag;
+ union {
+ uint8_t case_Ok[24U];
+ core_array_TryFromSliceError case_Err;
+ } val;
+} core_result_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
+
+*/
+void core_result_unwrap_41_76(core_result_Result_6f self, uint8_t ret[24U]);
+
+/**
+A monomorphic instance of core.result.Result
+with types uint8_t[20size_t], core_array_TryFromSliceError
+
+*/
+typedef struct core_result_Result_7a_s {
+ core_result_Result_86_tags tag;
+ union {
+ uint8_t case_Ok[20U];
+ core_array_TryFromSliceError case_Err;
+ } val;
+} core_result_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
+
+*/
+void core_result_unwrap_41_ea(core_result_Result_7a self, uint8_t ret[20U]);
+
+/**
+A monomorphic instance of core.result.Result
+with types uint8_t[10size_t], core_array_TryFromSliceError
+
+*/
+typedef struct core_result_Result_cd_s {
+ core_result_Result_86_tags tag;
+ union {
+ uint8_t case_Ok[10U];
+ core_array_TryFromSliceError case_Err;
+ } val;
+} core_result_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
+
+*/
+void core_result_unwrap_41_07(core_result_Result_cd self, uint8_t ret[10U]);
+
+/**
+A monomorphic instance of core.result.Result
+with types int16_t[16size_t], core_array_TryFromSliceError
+
+*/
+typedef struct core_result_Result_c0_s {
+ core_result_Result_86_tags tag;
+ union {
+ int16_t case_Ok[16U];
+ core_array_TryFromSliceError case_Err;
+ } val;
+} core_result_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
+
+*/
+void core_result_unwrap_41_30(core_result_Result_c0 self, int16_t ret[16U]);
+
+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;
+
+#if defined(__cplusplus)
+}
+#endif
+
+#define __internal_libcrux_core_H_DEFINED
+#endif
diff -up ./lib/freebl/verified/internal/libcrux_mlkem_portable.h.mlkem ./lib/freebl/verified/internal/libcrux_mlkem_portable.h
--- ./lib/freebl/verified/internal/libcrux_mlkem_portable.h.mlkem 2024-10-31 14:54:15.462515926 -0700
+++ ./lib/freebl/verified/internal/libcrux_mlkem_portable.h 2024-10-31 14:54:15.462515926 -0700
@@ -0,0 +1,373 @@
+/*
+ * 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: b351338f6a84c7a1afc27433eb0ffdc668b3581d
+ * Eurydice: 7efec1624422fd5e94388ef06b9c76dfe7a48d46
+ * Karamel: c96fb69d15693284644d6aecaa90afa37e4de8f0
+ * F*: 58c915a86a2c07c8eca8d9deafd76cb7a91f0eb7
+ * Libcrux: 6ff01fb3c57ff29ecb59bc62d9dc7fd231060cfb
+ */
+
+#ifndef __internal_libcrux_mlkem_portable_H
+#define __internal_libcrux_mlkem_portable_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include "../libcrux_mlkem_portable.h"
+#include "eurydice_glue.h"
+#include "internal/libcrux_core.h"
+#include "internal/libcrux_sha3_internal.h"
+
+extern const int16_t libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[128U];
+
+#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)
+
+/**
+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;
+
+/**
+ 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= 4
+- RANKED_BYTES_PER_RING_ELEMENT= 1536
+- PUBLIC_KEY_SIZE= 1568
+*/
+bool libcrux_ml_kem_ind_cca_validate_public_key_b71(uint8_t *public_key);
+
+/**
+ 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[[$4size_t]]
+with const generics
+- K= 4
+- SECRET_KEY_SIZE= 3168
+- CIPHERTEXT_SIZE= 1568
+*/
+bool libcrux_ml_kem_ind_cca_validate_private_key_dc(
+ libcrux_ml_kem_types_MlKemPrivateKey_95 *private_key,
+ libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *_ciphertext);
+
+/**
+ 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[[$4size_t]],
+libcrux_ml_kem_variant_MlKem with const generics
+- K= 4
+- CPA_PRIVATE_KEY_SIZE= 1536
+- PRIVATE_KEY_SIZE= 3168
+- PUBLIC_KEY_SIZE= 1568
+- BYTES_PER_RING_ELEMENT= 1536
+- ETA1= 2
+- ETA1_RANDOMNESS_SIZE= 128
+*/
+libcrux_ml_kem_mlkem1024_MlKem1024KeyPair
+libcrux_ml_kem_ind_cca_generate_keypair_f61(uint8_t randomness[64U]);
+
+/**
+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[[$4size_t]],
+libcrux_ml_kem_variant_MlKem with const generics
+- K= 4
+- CIPHERTEXT_SIZE= 1568
+- PUBLIC_KEY_SIZE= 1568
+- T_AS_NTT_ENCODED_SIZE= 1536
+- C1_SIZE= 1408
+- C2_SIZE= 160
+- VECTOR_U_COMPRESSION_FACTOR= 11
+- VECTOR_V_COMPRESSION_FACTOR= 5
+- VECTOR_U_BLOCK_LEN= 352
+- ETA1= 2
+- ETA1_RANDOMNESS_SIZE= 128
+- ETA2= 2
+- ETA2_RANDOMNESS_SIZE= 128
+*/
+tuple_21 libcrux_ml_kem_ind_cca_encapsulate_eb1(
+ libcrux_ml_kem_types_MlKemPublicKey_1f *public_key,
+ uint8_t randomness[32U]);
+
+/**
+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[[$4size_t]],
+libcrux_ml_kem_variant_MlKem with const generics
+- K= 4
+- SECRET_KEY_SIZE= 3168
+- CPA_SECRET_KEY_SIZE= 1536
+- PUBLIC_KEY_SIZE= 1568
+- CIPHERTEXT_SIZE= 1568
+- T_AS_NTT_ENCODED_SIZE= 1536
+- C1_SIZE= 1408
+- C2_SIZE= 160
+- VECTOR_U_COMPRESSION_FACTOR= 11
+- VECTOR_V_COMPRESSION_FACTOR= 5
+- C1_BLOCK_SIZE= 352
+- ETA1= 2
+- ETA1_RANDOMNESS_SIZE= 128
+- ETA2= 2
+- ETA2_RANDOMNESS_SIZE= 128
+- IMPLICIT_REJECTION_HASH_INPUT_SIZE= 1600
+*/
+void libcrux_ml_kem_ind_cca_decapsulate_1f1(
+ libcrux_ml_kem_types_MlKemPrivateKey_95 *private_key,
+ libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext, uint8_t ret[32U]);
+
+/**
+ 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= 2
+- RANKED_BYTES_PER_RING_ELEMENT= 768
+- PUBLIC_KEY_SIZE= 800
+*/
+bool libcrux_ml_kem_ind_cca_validate_public_key_b70(uint8_t *public_key);
+
+/**
+ 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[[$2size_t]]
+with const generics
+- K= 2
+- SECRET_KEY_SIZE= 1632
+- CIPHERTEXT_SIZE= 768
+*/
+bool libcrux_ml_kem_ind_cca_validate_private_key_03(
+ libcrux_ml_kem_types_MlKemPrivateKey_5e *private_key,
+ libcrux_ml_kem_types_MlKemCiphertext_e8 *_ciphertext);
+
+/**
+ 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[[$2size_t]],
+libcrux_ml_kem_variant_MlKem with const generics
+- K= 2
+- CPA_PRIVATE_KEY_SIZE= 768
+- PRIVATE_KEY_SIZE= 1632
+- PUBLIC_KEY_SIZE= 800
+- BYTES_PER_RING_ELEMENT= 768
+- ETA1= 3
+- ETA1_RANDOMNESS_SIZE= 192
+*/
+libcrux_ml_kem_types_MlKemKeyPair_cb
+libcrux_ml_kem_ind_cca_generate_keypair_f60(uint8_t randomness[64U]);
+
+/**
+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[[$2size_t]],
+libcrux_ml_kem_variant_MlKem with const generics
+- K= 2
+- CIPHERTEXT_SIZE= 768
+- PUBLIC_KEY_SIZE= 800
+- T_AS_NTT_ENCODED_SIZE= 768
+- C1_SIZE= 640
+- C2_SIZE= 128
+- VECTOR_U_COMPRESSION_FACTOR= 10
+- VECTOR_V_COMPRESSION_FACTOR= 4
+- VECTOR_U_BLOCK_LEN= 320
+- ETA1= 3
+- ETA1_RANDOMNESS_SIZE= 192
+- ETA2= 2
+- ETA2_RANDOMNESS_SIZE= 128
+*/
+tuple_ec libcrux_ml_kem_ind_cca_encapsulate_eb0(
+ libcrux_ml_kem_types_MlKemPublicKey_be *public_key,
+ uint8_t randomness[32U]);
+
+/**
+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[[$2size_t]],
+libcrux_ml_kem_variant_MlKem with const generics
+- K= 2
+- SECRET_KEY_SIZE= 1632
+- CPA_SECRET_KEY_SIZE= 768
+- PUBLIC_KEY_SIZE= 800
+- CIPHERTEXT_SIZE= 768
+- T_AS_NTT_ENCODED_SIZE= 768
+- C1_SIZE= 640
+- C2_SIZE= 128
+- VECTOR_U_COMPRESSION_FACTOR= 10
+- VECTOR_V_COMPRESSION_FACTOR= 4
+- C1_BLOCK_SIZE= 320
+- ETA1= 3
+- ETA1_RANDOMNESS_SIZE= 192
+- ETA2= 2
+- ETA2_RANDOMNESS_SIZE= 128
+- IMPLICIT_REJECTION_HASH_INPUT_SIZE= 800
+*/
+void libcrux_ml_kem_ind_cca_decapsulate_1f0(
+ libcrux_ml_kem_types_MlKemPrivateKey_5e *private_key,
+ libcrux_ml_kem_types_MlKemCiphertext_e8 *ciphertext, uint8_t ret[32U]);
+
+/**
+ 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
+*/
+bool libcrux_ml_kem_ind_cca_validate_public_key_b7(uint8_t *public_key);
+
+/**
+ 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
+*/
+bool libcrux_ml_kem_ind_cca_validate_private_key_05(
+ libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key,
+ libcrux_ml_kem_mlkem768_MlKem768Ciphertext *_ciphertext);
+
+/**
+ 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
+*/
+libcrux_ml_kem_mlkem768_MlKem768KeyPair
+libcrux_ml_kem_ind_cca_generate_keypair_f6(uint8_t randomness[64U]);
+
+/**
+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
+*/
+tuple_3c libcrux_ml_kem_ind_cca_encapsulate_eb(
+ libcrux_ml_kem_types_MlKemPublicKey_15 *public_key,
+ uint8_t randomness[32U]);
+
+/**
+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
+*/
+void libcrux_ml_kem_ind_cca_decapsulate_1f(
+ libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key,
+ libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#define __internal_libcrux_mlkem_portable_H_DEFINED
+#endif
diff -up ./lib/freebl/verified/internal/libcrux_sha3_internal.h.mlkem ./lib/freebl/verified/internal/libcrux_sha3_internal.h
--- ./lib/freebl/verified/internal/libcrux_sha3_internal.h.mlkem 2024-10-31 14:54:15.463515937 -0700
+++ ./lib/freebl/verified/internal/libcrux_sha3_internal.h 2024-10-31 14:54:15.463515937 -0700
@@ -0,0 +1,1551 @@
+/*
+ * 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: b351338f6a84c7a1afc27433eb0ffdc668b3581d
+ * Eurydice: 7efec1624422fd5e94388ef06b9c76dfe7a48d46
+ * Karamel: c96fb69d15693284644d6aecaa90afa37e4de8f0
+ * F*: 58c915a86a2c07c8eca8d9deafd76cb7a91f0eb7
+ * Libcrux: 6ff01fb3c57ff29ecb59bc62d9dc7fd231060cfb
+ */
+
+#ifndef __internal_libcrux_sha3_internal_H
+#define __internal_libcrux_sha3_internal_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include "../libcrux_sha3_internal.h"
+#include "eurydice_glue.h"
+
+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_cf();
+}
+
+/**
+ 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_40(s, buf);
+}
+
+/**
+ 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_c2(s, buf);
+}
+
+/**
+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_5c(
+ 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_7b(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_c2(s, o1);
+ libcrux_sha3_generic_keccak_squeeze_next_block_c2(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_5c(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;
+}
+
+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 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_3e(
+ 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_7b(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_c2(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_c2(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_c2(s, o3);
+ libcrux_sha3_generic_keccak_squeeze_next_block_c2(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_3e(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_400(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_cf();
+}
+
+/**
+ 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_7b0(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_c20(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_15(
+ 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;
+ {
+ size_t i = (size_t)0U;
+ Eurydice_slice uu____0 = Eurydice_array_to_subslice_from(
+ (size_t)136U, self->buf[i], self->buf_len, uint8_t, size_t);
+ Eurydice_slice_copy(
+ uu____0,
+ Eurydice_slice_subslice_to(inputs[i], 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_7a(
+ 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_15(uu____0, copy_of_inputs0);
+ if (input_consumed > (size_t)0U) {
+ Eurydice_slice borrowed[1U];
+ {
+ uint8_t buf[136U] = { 0U };
+ borrowed[0U] = core_array___Array_T__N__23__as_slice(
+ (size_t)136U, buf, uint8_t, Eurydice_slice);
+ }
+ {
+ size_t i = (size_t)0U;
+ borrowed[i] =
+ Eurydice_array_to_slice((size_t)136U, self->buf[i], 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_35(uu____2, uu____3);
+ libcrux_sha3_generic_keccak_keccakf1600_b8(&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_35(uu____4, ret);
+ libcrux_sha3_generic_keccak_keccakf1600_b8(&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_45(
+ 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_7a(uu____0, copy_of_inputs);
+ if (input_remainder_len > (size_t)0U) {
+ size_t input_len = Eurydice_slice_len(inputs[0U], uint8_t);
+ {
+ size_t i = (size_t)0U;
+ Eurydice_slice uu____2 = Eurydice_array_to_subslice2(
+ self->buf[i], self->buf_len, self->buf_len + input_remainder_len,
+ uint8_t);
+ Eurydice_slice_copy(
+ uu____2,
+ Eurydice_slice_subslice_from(
+ inputs[i], 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_45(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_b6(
+ 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_7a(uu____0, copy_of_inputs);
+ size_t input_len = Eurydice_slice_len(inputs[0U], uint8_t);
+ uint8_t blocks[1U][200U] = { { 0U } };
+ {
+ size_t i = (size_t)0U;
+ if (self->buf_len > (size_t)0U) {
+ Eurydice_slice uu____2 = Eurydice_array_to_subslice2(
+ blocks[i], (size_t)0U, self->buf_len, uint8_t);
+ Eurydice_slice_copy(uu____2,
+ Eurydice_array_to_subslice2(self->buf[i], (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[i], self->buf_len, self->buf_len + input_remainder_len,
+ uint8_t);
+ Eurydice_slice_copy(
+ uu____3,
+ Eurydice_slice_subslice_from(
+ inputs[i], input_len - input_remainder_len, uint8_t, size_t),
+ uint8_t);
+ }
+ blocks[i][self->buf_len + input_remainder_len] = 31U;
+ size_t uu____4 = i;
+ 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_050(uu____6, uu____7);
+ libcrux_sha3_generic_keccak_keccakf1600_b8(&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_b6(&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_5e(
+ 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_47(void)
+{
+ libcrux_sha3_generic_keccak_KeccakXofState_4f lit;
+ lit.inner = libcrux_sha3_generic_keccak_new_1e_cf();
+ uint8_t ret[136U];
+ libcrux_sha3_generic_keccak_zero_block_9d_5e(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_47();
+}
+
+/**
+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_150(
+ 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;
+ {
+ size_t i = (size_t)0U;
+ Eurydice_slice uu____0 = Eurydice_array_to_subslice_from(
+ (size_t)168U, self->buf[i], self->buf_len, uint8_t, size_t);
+ Eurydice_slice_copy(
+ uu____0,
+ Eurydice_slice_subslice_to(inputs[i], 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_7a0(
+ 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_150(uu____0, copy_of_inputs0);
+ if (input_consumed > (size_t)0U) {
+ Eurydice_slice borrowed[1U];
+ {
+ uint8_t buf[168U] = { 0U };
+ borrowed[0U] = core_array___Array_T__N__23__as_slice(
+ (size_t)168U, buf, uint8_t, Eurydice_slice);
+ }
+ {
+ size_t i = (size_t)0U;
+ borrowed[i] =
+ Eurydice_array_to_slice((size_t)168U, self->buf[i], 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_350(uu____2, uu____3);
+ libcrux_sha3_generic_keccak_keccakf1600_b8(&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_350(uu____4, ret);
+ libcrux_sha3_generic_keccak_keccakf1600_b8(&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_450(
+ 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_7a0(uu____0, copy_of_inputs);
+ if (input_remainder_len > (size_t)0U) {
+ size_t input_len = Eurydice_slice_len(inputs[0U], uint8_t);
+ {
+ size_t i = (size_t)0U;
+ Eurydice_slice uu____2 = Eurydice_array_to_subslice2(
+ self->buf[i], self->buf_len, self->buf_len + input_remainder_len,
+ uint8_t);
+ Eurydice_slice_copy(
+ uu____2,
+ Eurydice_slice_subslice_from(
+ inputs[i], 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_450(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_b60(
+ 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_7a0(uu____0, copy_of_inputs);
+ size_t input_len = Eurydice_slice_len(inputs[0U], uint8_t);
+ uint8_t blocks[1U][200U] = { { 0U } };
+ {
+ size_t i = (size_t)0U;
+ if (self->buf_len > (size_t)0U) {
+ Eurydice_slice uu____2 = Eurydice_array_to_subslice2(
+ blocks[i], (size_t)0U, self->buf_len, uint8_t);
+ Eurydice_slice_copy(uu____2,
+ Eurydice_array_to_subslice2(self->buf[i], (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[i], self->buf_len, self->buf_len + input_remainder_len,
+ uint8_t);
+ Eurydice_slice_copy(
+ uu____3,
+ Eurydice_slice_subslice_from(
+ inputs[i], input_len - input_remainder_len, uint8_t, size_t),
+ uint8_t);
+ }
+ blocks[i][self->buf_len + input_remainder_len] = 31U;
+ size_t uu____4 = i;
+ 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_05(uu____6, uu____7);
+ libcrux_sha3_generic_keccak_keccakf1600_b8(&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_b60(&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_5e0(
+ 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_470(void)
+{
+ libcrux_sha3_generic_keccak_KeccakXofState_78 lit;
+ lit.inner = libcrux_sha3_generic_keccak_new_1e_cf();
+ uint8_t ret[168U];
+ libcrux_sha3_generic_keccak_zero_block_9d_5e0(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_470();
+}
+
+/**
+ `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_81(
+ 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_ba(
+ libcrux_sha3_generic_keccak_KeccakXofState_4f *self,
+ Eurydice_slice out[1U])
+{
+ if (self->sponge) {
+ libcrux_sha3_generic_keccak_keccakf1600_b8(&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_81(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, core_option_Option_b3)
+ .tag == core_option_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_b8(&self->inner);
+ libcrux_sha3_portable_keccak_store_5a_81(self->inner.st, out0);
+ memcpy(out_rest, tmp, (size_t)1U * sizeof(Eurydice_slice));
+ }
+ }
+ if (last < out_len) {
+ libcrux_sha3_generic_keccak_keccakf1600_b8(&self->inner);
+ libcrux_sha3_portable_keccak_store_5a_81(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_ba(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_810(
+ 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_ba0(
+ libcrux_sha3_generic_keccak_KeccakXofState_78 *self,
+ Eurydice_slice out[1U])
+{
+ if (self->sponge) {
+ libcrux_sha3_generic_keccak_keccakf1600_b8(&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_810(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, core_option_Option_b3)
+ .tag == core_option_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_b8(&self->inner);
+ libcrux_sha3_portable_keccak_store_5a_810(self->inner.st, out0);
+ memcpy(out_rest, tmp, (size_t)1U * sizeof(Eurydice_slice));
+ }
+ }
+ if (last < out_len) {
+ libcrux_sha3_generic_keccak_keccakf1600_b8(&self->inner);
+ libcrux_sha3_portable_keccak_store_5a_810(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_ba0(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 __internal_libcrux_sha3_internal_H_DEFINED
+#endif
diff -up ./lib/freebl/verified/libcrux_core.c.mlkem ./lib/freebl/verified/libcrux_core.c
--- ./lib/freebl/verified/libcrux_core.c.mlkem 2024-10-31 14:54:15.463515937 -0700
+++ ./lib/freebl/verified/libcrux_core.c 2024-10-31 14:54:15.463515937 -0700
@@ -0,0 +1,712 @@
+/*
+ * 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: b351338f6a84c7a1afc27433eb0ffdc668b3581d
+ * Eurydice: 7efec1624422fd5e94388ef06b9c76dfe7a48d46
+ * Karamel: c96fb69d15693284644d6aecaa90afa37e4de8f0
+ * F*: 58c915a86a2c07c8eca8d9deafd76cb7a91f0eb7
+ * Libcrux: 6ff01fb3c57ff29ecb59bc62d9dc7fd231060cfb
+ */
+
+#include "internal/libcrux_core.h"
+
+/**
+ Return 1 if `value` is not zero and 0 otherwise.
+*/
+static uint8_t
+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
+is_non_zero(uint8_t value)
+{
+ return inz(value);
+}
+
+/**
+ Return 1 if the bytes of `lhs` and `rhs` do not exactly
+ match and 0 otherwise.
+*/
+static uint8_t
+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 is_non_zero(r);
+}
+
+static KRML_NOINLINE uint8_t
+compare_ciphertexts_in_constant_time(Eurydice_slice lhs, Eurydice_slice rhs)
+{
+ return compare(lhs, rhs);
+}
+
+/**
+ If `selector` is not zero, return the bytes in `rhs`; return the bytes in
+ `lhs` otherwise.
+*/
+static void
+select_ct(Eurydice_slice lhs, Eurydice_slice rhs, uint8_t selector,
+ uint8_t ret[32U])
+{
+ uint8_t mask = core_num__u8_6__wrapping_sub(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
+select_shared_secret_in_constant_time(
+ Eurydice_slice lhs, Eurydice_slice rhs, uint8_t selector,
+ uint8_t ret[32U])
+{
+ select_ct(lhs, rhs, selector, ret);
+}
+
+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 = compare_ciphertexts_in_constant_time(lhs_c, rhs_c);
+ uint8_t ret0[32U];
+ select_shared_secret_in_constant_time(lhs_s, rhs_s, selector, ret0);
+ memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t));
+}
+
+/**
+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= 1568
+*/
+libcrux_ml_kem_types_MlKemPublicKey_1f
+libcrux_ml_kem_types_from_b6_961(
+ uint8_t value[1568U])
+{
+ /* Passing arrays by value in Rust generates a copy in C */
+ uint8_t copy_of_value[1568U];
+ memcpy(copy_of_value, value, (size_t)1568U * sizeof(uint8_t));
+ libcrux_ml_kem_types_MlKemPublicKey_1f lit;
+ memcpy(lit.value, copy_of_value, (size_t)1568U * sizeof(uint8_t));
+ return lit;
+}
+
+/**
+ 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= 3168
+- PUBLIC_KEY_SIZE= 1568
+*/
+libcrux_ml_kem_mlkem1024_MlKem1024KeyPair
+libcrux_ml_kem_types_from_17_821(
+ libcrux_ml_kem_types_MlKemPrivateKey_95 sk,
+ libcrux_ml_kem_types_MlKemPublicKey_1f pk)
+{
+ return (
+ CLITERAL(libcrux_ml_kem_mlkem1024_MlKem1024KeyPair){ .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= 3168
+*/
+libcrux_ml_kem_types_MlKemPrivateKey_95
+libcrux_ml_kem_types_from_05_891(
+ uint8_t value[3168U])
+{
+ /* Passing arrays by value in Rust generates a copy in C */
+ uint8_t copy_of_value[3168U];
+ memcpy(copy_of_value, value, (size_t)3168U * sizeof(uint8_t));
+ libcrux_ml_kem_types_MlKemPrivateKey_95 lit;
+ memcpy(lit.value, copy_of_value, (size_t)3168U * sizeof(uint8_t));
+ return lit;
+}
+
+/**
+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= 1568
+*/
+libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext
+libcrux_ml_kem_types_from_01_331(
+ uint8_t value[1568U])
+{
+ /* Passing arrays by value in Rust generates a copy in C */
+ uint8_t copy_of_value[1568U];
+ memcpy(copy_of_value, value, (size_t)1568U * sizeof(uint8_t));
+ libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext lit;
+ memcpy(lit.value, copy_of_value, (size_t)1568U * 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= 1568
+*/
+uint8_t *
+libcrux_ml_kem_types_as_slice_cb_3d1(
+ libcrux_ml_kem_types_MlKemPublicKey_1f *self)
+{
+ return self->value;
+}
+
+/**
+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= 1568
+*/
+Eurydice_slice
+libcrux_ml_kem_types_as_ref_00_d81(
+ libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *self)
+{
+ return Eurydice_array_to_slice((size_t)1568U, 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= 1600
+*/
+void
+libcrux_ml_kem_utils_into_padded_array_6d4(Eurydice_slice slice,
+ uint8_t ret[1600U])
+{
+ uint8_t out[1600U] = { 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)1600U * sizeof(uint8_t));
+}
+
+/**
+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
+*/
+libcrux_ml_kem_types_MlKemPublicKey_15
+libcrux_ml_kem_types_from_b6_960(
+ 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;
+}
+
+/**
+ 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
+*/
+libcrux_ml_kem_mlkem768_MlKem768KeyPair
+libcrux_ml_kem_types_from_17_820(
+ 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
+*/
+libcrux_ml_kem_types_MlKemPrivateKey_55
+libcrux_ml_kem_types_from_05_890(
+ 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;
+}
+
+/**
+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
+*/
+libcrux_ml_kem_mlkem768_MlKem768Ciphertext
+libcrux_ml_kem_types_from_01_330(
+ 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
+*/
+uint8_t *
+libcrux_ml_kem_types_as_slice_cb_3d0(
+ libcrux_ml_kem_types_MlKemPublicKey_15 *self)
+{
+ return self->value;
+}
+
+/**
+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
+*/
+Eurydice_slice
+libcrux_ml_kem_types_as_ref_00_d80(
+ 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
+*/
+void
+libcrux_ml_kem_utils_into_padded_array_6d3(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));
+}
+
+/**
+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= 800
+*/
+libcrux_ml_kem_types_MlKemPublicKey_be
+libcrux_ml_kem_types_from_b6_96(
+ uint8_t value[800U])
+{
+ /* Passing arrays by value in Rust generates a copy in C */
+ uint8_t copy_of_value[800U];
+ memcpy(copy_of_value, value, (size_t)800U * sizeof(uint8_t));
+ libcrux_ml_kem_types_MlKemPublicKey_be lit;
+ memcpy(lit.value, copy_of_value, (size_t)800U * sizeof(uint8_t));
+ return lit;
+}
+
+/**
+ 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= 1632
+- PUBLIC_KEY_SIZE= 800
+*/
+libcrux_ml_kem_types_MlKemKeyPair_cb
+libcrux_ml_kem_types_from_17_82(
+ libcrux_ml_kem_types_MlKemPrivateKey_5e sk,
+ libcrux_ml_kem_types_MlKemPublicKey_be pk)
+{
+ return (CLITERAL(libcrux_ml_kem_types_MlKemKeyPair_cb){ .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= 1632
+*/
+libcrux_ml_kem_types_MlKemPrivateKey_5e
+libcrux_ml_kem_types_from_05_89(
+ uint8_t value[1632U])
+{
+ /* Passing arrays by value in Rust generates a copy in C */
+ uint8_t copy_of_value[1632U];
+ memcpy(copy_of_value, value, (size_t)1632U * sizeof(uint8_t));
+ libcrux_ml_kem_types_MlKemPrivateKey_5e lit;
+ memcpy(lit.value, copy_of_value, (size_t)1632U * sizeof(uint8_t));
+ return lit;
+}
+
+/**
+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
+
+*/
+void
+core_result_unwrap_41_33(core_result_Result_00 self, uint8_t ret[32U])
+{
+ if (self.tag == core_result_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);
+ }
+}
+
+/**
+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= 768
+*/
+libcrux_ml_kem_types_MlKemCiphertext_e8
+libcrux_ml_kem_types_from_01_33(
+ uint8_t value[768U])
+{
+ /* Passing arrays by value in Rust generates a copy in C */
+ uint8_t copy_of_value[768U];
+ memcpy(copy_of_value, value, (size_t)768U * sizeof(uint8_t));
+ libcrux_ml_kem_types_MlKemCiphertext_e8 lit;
+ memcpy(lit.value, copy_of_value, (size_t)768U * 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= 800
+*/
+uint8_t *
+libcrux_ml_kem_types_as_slice_cb_3d(
+ libcrux_ml_kem_types_MlKemPublicKey_be *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
+*/
+void
+libcrux_ml_kem_utils_into_padded_array_6d2(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
+*/
+void
+libcrux_ml_kem_utils_into_padded_array_6d1(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= 768
+*/
+Eurydice_slice
+libcrux_ml_kem_types_as_ref_00_d8(
+ libcrux_ml_kem_types_MlKemCiphertext_e8 *self)
+{
+ return Eurydice_array_to_slice((size_t)768U, 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= 800
+*/
+void
+libcrux_ml_kem_utils_into_padded_array_6d0(Eurydice_slice slice,
+ uint8_t ret[800U])
+{
+ uint8_t out[800U] = { 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)800U * 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
+*/
+void
+libcrux_ml_kem_utils_into_padded_array_6d(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));
+}
+
+/**
+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
+
+*/
+void
+core_result_unwrap_41_76(core_result_Result_6f self, uint8_t ret[24U])
+{
+ if (self.tag == core_result_Ok) {
+ uint8_t f0[24U];
+ memcpy(f0, self.val.case_Ok, (size_t)24U * sizeof(uint8_t));
+ memcpy(ret, f0, (size_t)24U * sizeof(uint8_t));
+ } else {
+ KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__,
+ "unwrap not Ok");
+ KRML_HOST_EXIT(255U);
+ }
+}
+
+/**
+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
+
+*/
+void
+core_result_unwrap_41_ea(core_result_Result_7a self, uint8_t ret[20U])
+{
+ if (self.tag == core_result_Ok) {
+ uint8_t f0[20U];
+ memcpy(f0, self.val.case_Ok, (size_t)20U * sizeof(uint8_t));
+ memcpy(ret, f0, (size_t)20U * sizeof(uint8_t));
+ } else {
+ KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__,
+ "unwrap not Ok");
+ KRML_HOST_EXIT(255U);
+ }
+}
+
+/**
+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
+
+*/
+void
+core_result_unwrap_41_07(core_result_Result_cd self, uint8_t ret[10U])
+{
+ if (self.tag == core_result_Ok) {
+ uint8_t f0[10U];
+ memcpy(f0, self.val.case_Ok, (size_t)10U * sizeof(uint8_t));
+ memcpy(ret, f0, (size_t)10U * sizeof(uint8_t));
+ } else {
+ KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__,
+ "unwrap not Ok");
+ KRML_HOST_EXIT(255U);
+ }
+}
+
+/**
+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
+
+*/
+void
+core_result_unwrap_41_30(core_result_Result_c0 self, int16_t ret[16U])
+{
+ if (self.tag == core_result_Ok) {
+ int16_t f0[16U];
+ memcpy(f0, self.val.case_Ok, (size_t)16U * sizeof(int16_t));
+ memcpy(ret, f0, (size_t)16U * sizeof(int16_t));
+ } else {
+ KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__,
+ "unwrap not Ok");
+ KRML_HOST_EXIT(255U);
+ }
+}
+
+/**
+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
+
+*/
+void
+core_result_unwrap_41_0e(core_result_Result_56 self, uint8_t ret[8U])
+{
+ if (self.tag == core_result_Ok) {
+ uint8_t f0[8U];
+ memcpy(f0, self.val.case_Ok, (size_t)8U * sizeof(uint8_t));
+ memcpy(ret, f0, (size_t)8U * sizeof(uint8_t));
+ } else {
+ KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__,
+ "unwrap not Ok");
+ KRML_HOST_EXIT(255U);
+ }
+}
diff -up ./lib/freebl/verified/libcrux_core.h.mlkem ./lib/freebl/verified/libcrux_core.h
--- ./lib/freebl/verified/libcrux_core.h.mlkem 2024-10-31 14:54:15.463515937 -0700
+++ ./lib/freebl/verified/libcrux_core.h 2024-10-31 14:54:15.463515937 -0700
@@ -0,0 +1,219 @@
+/*
+ * 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: b351338f6a84c7a1afc27433eb0ffdc668b3581d
+ * Eurydice: 7efec1624422fd5e94388ef06b9c76dfe7a48d46
+ * Karamel: c96fb69d15693284644d6aecaa90afa37e4de8f0
+ * F*: 58c915a86a2c07c8eca8d9deafd76cb7a91f0eb7
+ * Libcrux: 6ff01fb3c57ff29ecb59bc62d9dc7fd231060cfb
+ */
+
+#ifndef __libcrux_core_H
+#define __libcrux_core_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include "eurydice_glue.h"
+
+/**
+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 core_result_Ok 0
+#define core_result_Err 1
+
+typedef uint8_t core_result_Result_86_tags;
+
+#define core_option_None 0
+#define core_option_Some 1
+
+typedef uint8_t core_option_Option_ef_tags;
+
+/**
+A monomorphic instance of core.option.Option
+with types size_t
+
+*/
+typedef struct core_option_Option_b3_s {
+ core_option_Option_ef_tags tag;
+ size_t f0;
+} core_option_Option_b3;
+
+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]);
+
+/**
+A monomorphic instance of libcrux_ml_kem.types.MlKemPublicKey
+with const generics
+- $1568size_t
+*/
+typedef struct libcrux_ml_kem_types_MlKemPublicKey_1f_s {
+ uint8_t value[1568U];
+} libcrux_ml_kem_types_MlKemPublicKey_1f;
+
+/**
+A monomorphic instance of libcrux_ml_kem.types.MlKemPrivateKey
+with const generics
+- $3168size_t
+*/
+typedef struct libcrux_ml_kem_types_MlKemPrivateKey_95_s {
+ uint8_t value[3168U];
+} libcrux_ml_kem_types_MlKemPrivateKey_95;
+
+typedef struct libcrux_ml_kem_mlkem1024_MlKem1024KeyPair_s {
+ libcrux_ml_kem_types_MlKemPrivateKey_95 sk;
+ libcrux_ml_kem_types_MlKemPublicKey_1f pk;
+} libcrux_ml_kem_mlkem1024_MlKem1024KeyPair;
+
+typedef struct libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext_s {
+ uint8_t value[1568U];
+} libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext;
+
+/**
+A monomorphic instance of K.
+with types libcrux_ml_kem_types_MlKemCiphertext[[$1568size_t]],
+uint8_t[32size_t]
+
+*/
+typedef struct tuple_21_s {
+ libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext fst;
+ uint8_t snd[32U];
+} tuple_21;
+
+/**
+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;
+
+/**
+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;
+
+typedef struct libcrux_ml_kem_mlkem768_MlKem768Ciphertext_s {
+ uint8_t value[1088U];
+} libcrux_ml_kem_mlkem768_MlKem768Ciphertext;
+
+/**
+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;
+
+/**
+A monomorphic instance of libcrux_ml_kem.types.MlKemPublicKey
+with const generics
+- $800size_t
+*/
+typedef struct libcrux_ml_kem_types_MlKemPublicKey_be_s {
+ uint8_t value[800U];
+} libcrux_ml_kem_types_MlKemPublicKey_be;
+
+/**
+A monomorphic instance of libcrux_ml_kem.types.MlKemPrivateKey
+with const generics
+- $1632size_t
+*/
+typedef struct libcrux_ml_kem_types_MlKemPrivateKey_5e_s {
+ uint8_t value[1632U];
+} libcrux_ml_kem_types_MlKemPrivateKey_5e;
+
+/**
+A monomorphic instance of libcrux_ml_kem.types.MlKemKeyPair
+with const generics
+- $1632size_t
+- $800size_t
+*/
+typedef struct libcrux_ml_kem_types_MlKemKeyPair_cb_s {
+ libcrux_ml_kem_types_MlKemPrivateKey_5e sk;
+ libcrux_ml_kem_types_MlKemPublicKey_be pk;
+} libcrux_ml_kem_types_MlKemKeyPair_cb;
+
+/**
+A monomorphic instance of libcrux_ml_kem.types.MlKemCiphertext
+with const generics
+- $768size_t
+*/
+typedef struct libcrux_ml_kem_types_MlKemCiphertext_e8_s {
+ uint8_t value[768U];
+} libcrux_ml_kem_types_MlKemCiphertext_e8;
+
+/**
+A monomorphic instance of K.
+with types libcrux_ml_kem_types_MlKemCiphertext[[$768size_t]], uint8_t[32size_t]
+
+*/
+typedef struct tuple_ec_s {
+ libcrux_ml_kem_types_MlKemCiphertext_e8 fst;
+ uint8_t snd[32U];
+} tuple_ec;
+
+/**
+A monomorphic instance of core.result.Result
+with types uint8_t[8size_t], core_array_TryFromSliceError
+
+*/
+typedef struct core_result_Result_56_s {
+ core_result_Result_86_tags tag;
+ union {
+ uint8_t case_Ok[8U];
+ core_array_TryFromSliceError case_Err;
+ } val;
+} core_result_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
+
+*/
+void core_result_unwrap_41_0e(core_result_Result_56 self, uint8_t ret[8U]);
+
+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
diff -up ./lib/freebl/verified/libcrux_mlkem768.h.mlkem ./lib/freebl/verified/libcrux_mlkem768.h
--- ./lib/freebl/verified/libcrux_mlkem768.h.mlkem 2024-10-31 14:54:15.463515937 -0700
+++ ./lib/freebl/verified/libcrux_mlkem768.h 2024-10-31 14:54:15.463515937 -0700
@@ -0,0 +1,92 @@
+/*
+ * 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: b351338f6a84c7a1afc27433eb0ffdc668b3581d
+ * Eurydice: 7efec1624422fd5e94388ef06b9c76dfe7a48d46
+ * Karamel: c96fb69d15693284644d6aecaa90afa37e4de8f0
+ * F*: 58c915a86a2c07c8eca8d9deafd76cb7a91f0eb7
+ * Libcrux: 6ff01fb3c57ff29ecb59bc62d9dc7fd231060cfb
+ */
+
+#ifndef __libcrux_mlkem768_H
+#define __libcrux_mlkem768_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include "eurydice_glue.h"
+#include "libcrux_core.h"
+
+#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)
+
+#if defined(__cplusplus)
+}
+#endif
+
+#define __libcrux_mlkem768_H_DEFINED
+#endif
diff -up ./lib/freebl/verified/libcrux_mlkem768_portable.c.mlkem ./lib/freebl/verified/libcrux_mlkem768_portable.c
--- ./lib/freebl/verified/libcrux_mlkem768_portable.c.mlkem 2024-10-31 14:54:15.463515937 -0700
+++ ./lib/freebl/verified/libcrux_mlkem768_portable.c 2024-10-31 14:54:15.463515937 -0700
@@ -0,0 +1,209 @@
+/*
+ * 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: b351338f6a84c7a1afc27433eb0ffdc668b3581d
+ * Eurydice: 7efec1624422fd5e94388ef06b9c76dfe7a48d46
+ * Karamel: c96fb69d15693284644d6aecaa90afa37e4de8f0
+ * F*: 58c915a86a2c07c8eca8d9deafd76cb7a91f0eb7
+ * Libcrux: 6ff01fb3c57ff29ecb59bc62d9dc7fd231060cfb
+ */
+
+#include "libcrux_mlkem768_portable.h"
+
+#include "internal/libcrux_mlkem_portable.h"
+
+/**
+ 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 void
+decapsulate_67(
+ libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key,
+ libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U])
+{
+ libcrux_ml_kem_ind_cca_decapsulate_1f(private_key, ciphertext, ret);
+}
+
+/**
+ Decapsulate ML-KEM 768
+
+ Generates an [`MlKemSharedSecret`].
+ The input is a reference to an [`MlKem768PrivateKey`] and an
+ [`MlKem768Ciphertext`].
+*/
+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])
+{
+ decapsulate_67(private_key, ciphertext, ret);
+}
+
+/**
+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 tuple_3c
+encapsulate_02(
+ 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_eb(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`.
+*/
+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 encapsulate_02(uu____0, copy_of_randomness);
+}
+
+/**
+ 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 libcrux_ml_kem_mlkem768_MlKem768KeyPair
+generate_keypair_87(
+ 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_f6(copy_of_randomness);
+}
+
+/**
+ Generate ML-KEM 768 Key Pair
+*/
+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 generate_keypair_87(copy_of_randomness);
+}
+
+/**
+ 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
+validate_private_key_e8(
+ libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key,
+ libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext)
+{
+ return libcrux_ml_kem_ind_cca_validate_private_key_05(private_key,
+ ciphertext);
+}
+
+/**
+ Validate a private key.
+
+ Returns `true` if valid, and `false` otherwise.
+*/
+bool
+libcrux_ml_kem_mlkem768_portable_validate_private_key(
+ libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key,
+ libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext)
+{
+ return validate_private_key_e8(private_key, ciphertext);
+}
+
+/**
+ 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
+validate_public_key_7d(uint8_t *public_key)
+{
+ return libcrux_ml_kem_ind_cca_validate_public_key_b7(public_key);
+}
+
+/**
+ Validate a public key.
+
+ Returns `true` if valid, and `false` otherwise.
+*/
+bool
+libcrux_ml_kem_mlkem768_portable_validate_public_key(
+ libcrux_ml_kem_types_MlKemPublicKey_15 *public_key)
+{
+ return validate_public_key_7d(public_key->value);
+}
diff -up ./lib/freebl/verified/libcrux_mlkem768_portable.h.mlkem ./lib/freebl/verified/libcrux_mlkem768_portable.h
--- ./lib/freebl/verified/libcrux_mlkem768_portable.h.mlkem 2024-10-31 14:54:15.463515937 -0700
+++ ./lib/freebl/verified/libcrux_mlkem768_portable.h 2024-10-31 14:54:15.463515937 -0700
@@ -0,0 +1,74 @@
+/*
+ * 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: b351338f6a84c7a1afc27433eb0ffdc668b3581d
+ * Eurydice: 7efec1624422fd5e94388ef06b9c76dfe7a48d46
+ * Karamel: c96fb69d15693284644d6aecaa90afa37e4de8f0
+ * F*: 58c915a86a2c07c8eca8d9deafd76cb7a91f0eb7
+ * Libcrux: 6ff01fb3c57ff29ecb59bc62d9dc7fd231060cfb
+ */
+
+#ifndef __libcrux_mlkem768_portable_H
+#define __libcrux_mlkem768_portable_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include "eurydice_glue.h"
+#include "libcrux_core.h"
+
+/**
+ Decapsulate ML-KEM 768
+
+ Generates an [`MlKemSharedSecret`].
+ The input is a reference to an [`MlKem768PrivateKey`] and an
+ [`MlKem768Ciphertext`].
+*/
+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]);
+
+/**
+ Encapsulate ML-KEM 768
+
+ Generates an ([`MlKem768Ciphertext`], [`MlKemSharedSecret`]) tuple.
+ The input is a reference to an [`MlKem768PublicKey`] and [`SHARED_SECRET_SIZE`]
+ bytes of `randomness`.
+*/
+tuple_3c libcrux_ml_kem_mlkem768_portable_encapsulate(
+ libcrux_ml_kem_types_MlKemPublicKey_15 *public_key,
+ uint8_t randomness[32U]);
+
+/**
+ Generate ML-KEM 768 Key Pair
+*/
+libcrux_ml_kem_mlkem768_MlKem768KeyPair
+libcrux_ml_kem_mlkem768_portable_generate_key_pair(uint8_t randomness[64U]);
+
+/**
+ Validate a private key.
+
+ Returns `true` if valid, and `false` otherwise.
+*/
+bool libcrux_ml_kem_mlkem768_portable_validate_private_key(
+ libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key,
+ libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext);
+
+/**
+ Validate a public key.
+
+ Returns `true` if valid, and `false` otherwise.
+*/
+bool libcrux_ml_kem_mlkem768_portable_validate_public_key(
+ libcrux_ml_kem_types_MlKemPublicKey_15 *public_key);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#define __libcrux_mlkem768_portable_H_DEFINED
+#endif
diff -up ./lib/freebl/verified/libcrux_mlkem_portable.c.mlkem ./lib/freebl/verified/libcrux_mlkem_portable.c
--- ./lib/freebl/verified/libcrux_mlkem_portable.c.mlkem 2024-10-31 14:54:15.465515959 -0700
+++ ./lib/freebl/verified/libcrux_mlkem_portable.c 2024-10-31 14:54:15.465515959 -0700
@@ -0,0 +1,9295 @@
+/*
+ * 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: b351338f6a84c7a1afc27433eb0ffdc668b3581d
+ * Eurydice: 7efec1624422fd5e94388ef06b9c76dfe7a48d46
+ * Karamel: c96fb69d15693284644d6aecaa90afa37e4de8f0
+ * F*: 58c915a86a2c07c8eca8d9deafd76cb7a91f0eb7
+ * Libcrux: 6ff01fb3c57ff29ecb59bc62d9dc7fd231060cfb
+ */
+
+#include "internal/libcrux_mlkem_portable.h"
+
+#include "internal/libcrux_core.h"
+#include "internal/libcrux_sha3_internal.h"
+
+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));
+}
+
+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));
+}
+
+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
+};
+
+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];
+ core_result_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]);
+ core_result_unwrap_41_30(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)}
+*/
+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);
+}
+
+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 });
+}
+
+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)}
+*/
+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);
+}
+
+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 });
+}
+
+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;
+}
+
+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)}
+*/
+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);
+}
+
+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)}
+*/
+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);
+}
+
+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)}
+*/
+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();
+}
+
+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)}
+*/
+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);
+}
+
+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)}
+*/
+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);
+}
+
+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)}
+*/
+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);
+}
+
+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)}
+*/
+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);
+}
+
+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) {
+ core_option_Option_b3 uu____0 =
+ core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next(
+ &iter, size_t, core_option_Option_b3);
+ if (!(uu____0.tag == core_option_None)) {
+ size_t i = uu____0.f0;
+ if (v.elements[i] >= (int16_t)3329) {
+ size_t uu____1 = i;
+ v.elements[uu____1] = v.elements[uu____1] - (int16_t)3329;
+ }
+ continue;
+ }
+ return v;
+ }
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+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);
+}
+
+/**
+ 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`.
+*/
+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;
+}
+
+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)}
+*/
+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);
+}
+
+/**
+ 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`.
+*/
+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)`.
+*/
+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);
+}
+
+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)}
+*/
+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>.
+*/
+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);
+}
+
+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)}
+*/
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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;
+}
+
+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)}
+*/
+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);
+}
+
+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)}
+*/
+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);
+}
+
+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)}
+*/
+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);
+}
+
+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);
+}
+
+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)}
+*/
+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);
+}
+
+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)}
+*/
+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);
+}
+
+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)}
+*/
+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>.
+*/
+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;
+}
+
+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)}
+*/
+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);
+}
+
+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 };
+ KRML_MAYBE_FOR8(
+ i, (size_t)0U, (size_t)8U, (size_t)1U, size_t i0 = i;
+ size_t uu____0 = (size_t)0U;
+ result[uu____0] = (uint32_t)result[uu____0] |
+ (uint32_t)(uint8_t)v.elements[i0] << (uint32_t)i0;);
+ KRML_MAYBE_FOR8(i, (size_t)8U, (size_t)16U, (size_t)1U, size_t i0 = i;
+ size_t uu____1 = (size_t)1U;
+ result[uu____1] = (uint32_t)result[uu____1] |
+ (uint32_t)(uint8_t)v.elements[i0]
+ << (uint32_t)(i0 - (size_t)8U););
+ memcpy(ret, result, (size_t)2U * sizeof(uint8_t));
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+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);
+}
+
+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();
+ KRML_MAYBE_FOR8(
+ i, (size_t)0U, (size_t)8U, (size_t)1U, 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)}
+*/
+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);
+}
+
+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 });
+}
+
+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)}
+*/
+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);
+}
+
+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 });
+}
+
+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)}
+*/
+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);
+}
+
+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 });
+}
+
+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)}
+*/
+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);
+}
+
+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 });
+}
+
+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)}
+*/
+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);
+}
+
+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 });
+}
+
+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)}
+*/
+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);
+}
+
+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 });
+}
+
+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)}
+*/
+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);
+}
+
+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 });
+}
+
+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)}
+*/
+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);
+}
+
+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 });
+}
+
+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)}
+*/
+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);
+}
+
+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)}
+*/
+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);
+}
+
+/**
+This function found in impl {(core::clone::Clone for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+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];
+}
+
+/**
+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 libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+ZERO_89_c3(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;
+}
+
+/**
+ 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
+deserialize_to_reduced_ring_element_45(Eurydice_slice serialized)
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re = ZERO_89_c3();
+ 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= 1568
+- K= 4
+*/
+static KRML_MUSTINLINE void
+deserialize_ring_elements_reduced_4f4(
+ Eurydice_slice public_key,
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[4U])
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 deserialized_pk[4U];
+ KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U,
+ deserialized_pk[i] = ZERO_89_c3(););
+ 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 =
+ deserialize_to_reduced_ring_element_45(ring_element);
+ deserialized_pk[i0] = uu____0;
+ }
+ memcpy(
+ ret, deserialized_pk,
+ (size_t)4U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+}
+
+/**
+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
+shift_right_b0(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 libcrux_ml_kem_vector_portable_vector_type_PortableVector
+shift_right_0d_01(libcrux_ml_kem_vector_portable_vector_type_PortableVector v)
+{
+ return shift_right_b0(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 libcrux_ml_kem_vector_portable_vector_type_PortableVector
+to_unsigned_representative_84(
+ libcrux_ml_kem_vector_portable_vector_type_PortableVector a)
+{
+ libcrux_ml_kem_vector_portable_vector_type_PortableVector t =
+ shift_right_0d_01(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.serialize_uncompressed_ring_element with types
+libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics
+
+*/
+static KRML_MUSTINLINE void
+serialize_uncompressed_ring_element_3c(
+ 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 =
+ to_unsigned_representative_84(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= 4
+- OUT_LEN= 1536
+*/
+static KRML_MUSTINLINE void
+serialize_secret_key_a31(
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *key,
+ uint8_t ret[1536U])
+{
+ uint8_t out[1536U] = { 0U };
+ for (size_t i = (size_t)0U;
+ i < Eurydice_slice_len(
+ Eurydice_array_to_slice(
+ (size_t)4U, 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];
+ serialize_uncompressed_ring_element_3c(&re, ret0);
+ Eurydice_slice_copy(
+ uu____0, Eurydice_array_to_slice((size_t)384U, ret0, uint8_t), uint8_t);
+ }
+ memcpy(ret, out, (size_t)1536U * 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= 4
+- RANKED_BYTES_PER_RING_ELEMENT= 1536
+- PUBLIC_KEY_SIZE= 1568
+*/
+static KRML_MUSTINLINE void
+serialize_public_key_671(
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *t_as_ntt,
+ Eurydice_slice seed_for_a, uint8_t ret[1568U])
+{
+ uint8_t public_key_serialized[1568U] = { 0U };
+ Eurydice_slice uu____0 = Eurydice_array_to_subslice2(
+ public_key_serialized, (size_t)0U, (size_t)1536U, uint8_t);
+ uint8_t ret0[1536U];
+ serialize_secret_key_a31(t_as_ntt, ret0);
+ Eurydice_slice_copy(
+ uu____0, Eurydice_array_to_slice((size_t)1536U, ret0, uint8_t), uint8_t);
+ Eurydice_slice_copy(
+ Eurydice_array_to_subslice_from((size_t)1568U, public_key_serialized,
+ (size_t)1536U, uint8_t, size_t),
+ seed_for_a, uint8_t);
+ memcpy(ret, public_key_serialized, (size_t)1568U * sizeof(uint8_t));
+}
+
+/**
+ 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= 4
+- RANKED_BYTES_PER_RING_ELEMENT= 1536
+- PUBLIC_KEY_SIZE= 1568
+*/
+bool
+libcrux_ml_kem_ind_cca_validate_public_key_b71(uint8_t *public_key)
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 deserialized_pk[4U];
+ deserialize_ring_elements_reduced_4f4(
+ Eurydice_array_to_subslice_to((size_t)1568U, public_key, (size_t)1536U,
+ uint8_t, size_t),
+ deserialized_pk);
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *uu____0 = deserialized_pk;
+ uint8_t public_key_serialized[1568U];
+ serialize_public_key_671(
+ uu____0,
+ Eurydice_array_to_subslice_from((size_t)1568U, public_key, (size_t)1536U,
+ uint8_t, size_t),
+ public_key_serialized);
+ return core_array_equality___core__cmp__PartialEq__Array_U__N___for__Array_T__N____eq(
+ (size_t)1568U, public_key, public_key_serialized, uint8_t, uint8_t, bool);
+}
+
+/**
+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= 4
+*/
+static KRML_MUSTINLINE void
+H_f1_191(Eurydice_slice input, uint8_t ret[32U])
+{
+ libcrux_ml_kem_hash_functions_portable_H(input, ret);
+}
+
+/**
+ 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[[$4size_t]]
+with const generics
+- K= 4
+- SECRET_KEY_SIZE= 3168
+- CIPHERTEXT_SIZE= 1568
+*/
+bool
+libcrux_ml_kem_ind_cca_validate_private_key_dc(
+ libcrux_ml_kem_types_MlKemPrivateKey_95 *private_key,
+ libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *_ciphertext)
+{
+ uint8_t t[32U];
+ H_f1_191(Eurydice_array_to_subslice2(
+ private_key->value, (size_t)384U * (size_t)4U,
+ (size_t)768U * (size_t)4U + (size_t)32U, uint8_t),
+ t);
+ Eurydice_slice expected = Eurydice_array_to_subslice2(
+ private_key->value, (size_t)768U * (size_t)4U + (size_t)32U,
+ (size_t)768U * (size_t)4U + (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);
+}
+
+/**
+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= 4
+*/
+static KRML_MUSTINLINE void
+G_f1_381(Eurydice_slice input, uint8_t ret[64U])
+{
+ libcrux_ml_kem_hash_functions_portable_G(input, ret);
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::variant::Variant for
+libcrux_ml_kem::variant::MlKem)}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.variant.cpa_keygen_seed_d8
+with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]]
+with const generics
+- K= 4
+*/
+static KRML_MUSTINLINE void
+cpa_keygen_seed_d8_72(
+ 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)4U;
+ uint8_t ret0[64U];
+ G_f1_381(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.sample_matrix_A.closure
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector,
+libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] with const
+generics
+- K= 4
+*/
+static void
+closure_fc1(
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[4U])
+{
+ KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U,
+ ret[i] = ZERO_89_c3(););
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PortableHash
+with const generics
+- $4size_t
+*/
+typedef struct PortableHash_d1_s {
+ libcrux_sha3_generic_keccak_KeccakState_48 shake128_state[4U];
+} PortableHash_d1;
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.hash_functions.portable.shake128_init_absorb with const generics
+- K= 4
+*/
+static KRML_MUSTINLINE PortableHash_d1
+shake128_init_absorb_791(uint8_t input[4U][34U])
+{
+ libcrux_sha3_generic_keccak_KeccakState_48 shake128_state[4U];
+ KRML_MAYBE_FOR4(
+ i, (size_t)0U, (size_t)4U, (size_t)1U,
+ shake128_state[i] = libcrux_sha3_portable_incremental_shake128_init(););
+ KRML_MAYBE_FOR4(
+ i, (size_t)0U, (size_t)4U, (size_t)1U, 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[4U];
+ memcpy(copy_of_shake128_state, shake128_state,
+ (size_t)4U * sizeof(libcrux_sha3_generic_keccak_KeccakState_48));
+ PortableHash_d1 lit;
+ memcpy(lit.shake128_state, copy_of_shake128_state,
+ (size_t)4U * 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= 4
+*/
+static KRML_MUSTINLINE PortableHash_d1
+shake128_init_absorb_f1_771(uint8_t input[4U][34U])
+{
+ /* Passing arrays by value in Rust generates a copy in C */
+ uint8_t copy_of_input[4U][34U];
+ memcpy(copy_of_input, input, (size_t)4U * sizeof(uint8_t[34U]));
+ return shake128_init_absorb_791(copy_of_input);
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.hash_functions.portable.shake128_squeeze_three_blocks with const
+generics
+- K= 4
+*/
+static KRML_MUSTINLINE void
+shake128_squeeze_three_blocks_eb1(
+ PortableHash_d1 *st, uint8_t ret[4U][504U])
+{
+ uint8_t out[4U][504U] = { { 0U } };
+ KRML_MAYBE_FOR4(
+ i, (size_t)0U, (size_t)4U, (size_t)1U, 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)4U * 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= 4
+*/
+static KRML_MUSTINLINE void
+shake128_squeeze_three_blocks_f1_841(
+ PortableHash_d1 *self, uint8_t ret[4U][504U])
+{
+ shake128_squeeze_three_blocks_eb1(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= 4
+- N= 504
+*/
+static KRML_MUSTINLINE bool
+sample_from_uniform_distribution_next_173(
+ uint8_t randomness[4U][504U], size_t *sampled_coefficients,
+ int16_t (*out)[272U])
+{
+ KRML_MAYBE_FOR4(
+ i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0;
+ for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) {
+ size_t r = i;
+ if (sampled_coefficients[i1] <
+ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) {
+ Eurydice_slice uu____0 = Eurydice_array_to_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;
+ KRML_MAYBE_FOR4(
+ i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i;
+ if (sampled_coefficients[i0] >=
+ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) {
+ sampled_coefficients[i0] =
+ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT;
+ } else { done = false; });
+ return done;
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.hash_functions.portable.shake128_squeeze_block with const
+generics
+- K= 4
+*/
+static KRML_MUSTINLINE void
+shake128_squeeze_block_3b1(PortableHash_d1 *st,
+ uint8_t ret[4U][168U])
+{
+ uint8_t out[4U][168U] = { { 0U } };
+ KRML_MAYBE_FOR4(
+ i, (size_t)0U, (size_t)4U, (size_t)1U, 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)4U * 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= 4
+*/
+static KRML_MUSTINLINE void
+shake128_squeeze_block_f1_8e1(
+ PortableHash_d1 *self, uint8_t ret[4U][168U])
+{
+ shake128_squeeze_block_3b1(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= 4
+- N= 168
+*/
+static KRML_MUSTINLINE bool
+sample_from_uniform_distribution_next_174(
+ uint8_t randomness[4U][168U], size_t *sampled_coefficients,
+ int16_t (*out)[272U])
+{
+ KRML_MAYBE_FOR4(
+ i0, (size_t)0U, (size_t)4U, (size_t)1U, size_t i1 = i0;
+ for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) {
+ size_t r = i;
+ if (sampled_coefficients[i1] <
+ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) {
+ Eurydice_slice uu____0 = Eurydice_array_to_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;
+ KRML_MAYBE_FOR4(
+ i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i;
+ if (sampled_coefficients[i0] >=
+ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) {
+ sampled_coefficients[i0] =
+ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT;
+ } else { done = false; });
+ return done;
+}
+
+/**
+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
+from_i16_array_89_33(Eurydice_slice a)
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 result = ZERO_89_c3();
+ 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[[$4size_t]] with const
+generics
+- K= 4
+*/
+static libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+closure_e41(
+ int16_t s[272U])
+{
+ return from_i16_array_89_33(
+ 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[[$4size_t]] with const
+generics
+- K= 4
+*/
+static KRML_MUSTINLINE void
+sample_from_xof_461(
+ uint8_t seeds[4U][34U],
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[4U])
+{
+ size_t sampled_coefficients[4U] = { 0U };
+ int16_t out[4U][272U] = { { 0U } };
+ /* Passing arrays by value in Rust generates a copy in C */
+ uint8_t copy_of_seeds[4U][34U];
+ memcpy(copy_of_seeds, seeds, (size_t)4U * sizeof(uint8_t[34U]));
+ PortableHash_d1 xof_state = shake128_init_absorb_f1_771(copy_of_seeds);
+ uint8_t randomness0[4U][504U];
+ shake128_squeeze_three_blocks_f1_841(&xof_state, randomness0);
+ /* Passing arrays by value in Rust generates a copy in C */
+ uint8_t copy_of_randomness0[4U][504U];
+ memcpy(copy_of_randomness0, randomness0, (size_t)4U * sizeof(uint8_t[504U]));
+ bool done = sample_from_uniform_distribution_next_173(
+ copy_of_randomness0, sampled_coefficients, out);
+ while (true) {
+ if (done) {
+ break;
+ } else {
+ uint8_t randomness[4U][168U];
+ shake128_squeeze_block_f1_8e1(&xof_state, randomness);
+ /* Passing arrays by value in Rust generates a copy in C */
+ uint8_t copy_of_randomness[4U][168U];
+ memcpy(copy_of_randomness, randomness,
+ (size_t)4U * sizeof(uint8_t[168U]));
+ done = sample_from_uniform_distribution_next_174(
+ copy_of_randomness, sampled_coefficients, out);
+ }
+ }
+ /* Passing arrays by value in Rust generates a copy in C */
+ int16_t copy_of_out[4U][272U];
+ memcpy(copy_of_out, out, (size_t)4U * sizeof(int16_t[272U]));
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret0[4U];
+ KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U,
+ ret0[i] = closure_e41(copy_of_out[i]););
+ memcpy(
+ ret, ret0,
+ (size_t)4U * 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[[$4size_t]] with const
+generics
+- K= 4
+*/
+static KRML_MUSTINLINE void
+sample_matrix_A_e71(
+ uint8_t seed[34U], bool transpose,
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[4U][4U])
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 A_transpose[4U][4U];
+ KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U,
+ closure_fc1(A_transpose[i]););
+ KRML_MAYBE_FOR4(
+ i0, (size_t)0U, (size_t)4U, (size_t)1U, 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[4U][34U]; KRML_MAYBE_FOR4(
+ i, (size_t)0U, (size_t)4U, (size_t)1U,
+ memcpy(seeds[i], copy_of_seed, (size_t)34U * sizeof(uint8_t)););
+ KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, 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[4U][34U];
+ memcpy(copy_of_seeds, seeds, (size_t)4U * sizeof(uint8_t[34U]));
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 sampled[4U];
+ sample_from_xof_461(copy_of_seeds, sampled);
+ for (size_t i = (size_t)0U;
+ i < Eurydice_slice_len(
+ Eurydice_array_to_slice(
+ (size_t)4U, 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)4U *
+ sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0[4U]));
+}
+
+/**
+A monomorphic instance of K.
+with types libcrux_ml_kem_polynomial_PolynomialRingElement
+libcrux_ml_kem_vector_portable_vector_type_PortableVector[4size_t], uint8_t
+
+*/
+typedef struct tuple_710_s {
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 fst[4U];
+ uint8_t snd;
+} tuple_710;
+
+/**
+A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRFxN
+with const generics
+- K= 4
+- LEN= 128
+*/
+static KRML_MUSTINLINE void
+PRFxN_1c2(uint8_t (*input)[33U],
+ uint8_t ret[4U][128U])
+{
+ uint8_t out[4U][128U] = { { 0U } };
+ KRML_MAYBE_FOR4(
+ i, (size_t)0U, (size_t)4U, (size_t)1U, 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)4U * 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= 4
+- LEN= 128
+*/
+static KRML_MUSTINLINE void
+PRFxN_f1_d52(uint8_t (*input)[33U],
+ uint8_t ret[4U][128U])
+{
+ PRFxN_1c2(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] ← xy 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
+sample_from_binomial_distribution_2_7b(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 from_i16_array_89_33(
+ 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
+sample_from_binomial_distribution_3_14(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 from_i16_array_89_33(
+ 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
+sample_from_binomial_distribution_ca(Eurydice_slice randomness)
+{
+ return sample_from_binomial_distribution_2_7b(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
+ntt_at_layer_7_60(
+ 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;
+ }
+}
+
+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 libcrux_ml_kem_vector_portable_vector_type_PortableVector
+montgomery_multiply_fe_05(
+ 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
+ ntt_layer_int_vec_step_88(
+ 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 =
+ montgomery_multiply_fe_05(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
+ntt_at_layer_4_plus_8c(
+ 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 / (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 =
+ ntt_layer_int_vec_step_88(
+ 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
+ntt_at_layer_3_34(
+ size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re)
+{
+ KRML_MAYBE_FOR16(
+ i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i;
+ zeta_i[0U] = zeta_i[0U] + (size_t)1U;
+ libcrux_ml_kem_vector_portable_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
+ntt_at_layer_2_26(
+ size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re)
+{
+ KRML_MAYBE_FOR16(
+ i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i;
+ zeta_i[0U] = zeta_i[0U] + (size_t)1U;
+ 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
+ntt_at_layer_1_3c(
+ size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re)
+{
+ KRML_MAYBE_FOR16(
+ i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i;
+ zeta_i[0U] = zeta_i[0U] + (size_t)1U;
+ 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
+poly_barrett_reduce_89_d8(
+ 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_binomially_sampled_ring_element
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static KRML_MUSTINLINE void
+ntt_binomially_sampled_ring_element_63(
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re)
+{
+ ntt_at_layer_7_60(re);
+ size_t zeta_i = (size_t)1U;
+ ntt_at_layer_4_plus_8c(&zeta_i, re, (size_t)6U);
+ ntt_at_layer_4_plus_8c(&zeta_i, re, (size_t)5U);
+ ntt_at_layer_4_plus_8c(&zeta_i, re, (size_t)4U);
+ ntt_at_layer_3_34(&zeta_i, re);
+ ntt_at_layer_2_26(&zeta_i, re);
+ ntt_at_layer_1_3c(&zeta_i, re);
+ poly_barrett_reduce_89_d8(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[[$4size_t]] with const
+generics
+- K= 4
+- ETA= 2
+- ETA_RANDOMNESS_SIZE= 128
+*/
+static KRML_MUSTINLINE tuple_710
+sample_vector_cbd_then_ntt_781(
+ uint8_t prf_input[33U], uint8_t domain_separator)
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re_as_ntt[4U];
+ KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U,
+ re_as_ntt[i] = ZERO_89_c3(););
+ /* 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[4U][33U];
+ KRML_MAYBE_FOR4(
+ i, (size_t)0U, (size_t)4U, (size_t)1U,
+ memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t)););
+ KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i;
+ prf_inputs[i0][32U] = domain_separator;
+ domain_separator = (uint32_t)domain_separator + 1U;);
+ uint8_t prf_outputs[4U][128U];
+ PRFxN_f1_d52(prf_inputs, prf_outputs);
+ KRML_MAYBE_FOR4(
+ i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i;
+ re_as_ntt[i0] = sample_from_binomial_distribution_ca(
+ Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], uint8_t));
+ ntt_binomially_sampled_ring_element_63(&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[4U];
+ memcpy(
+ copy_of_re_as_ntt, re_as_ntt,
+ (size_t)4U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+ tuple_710 lit;
+ memcpy(
+ lit.fst, copy_of_re_as_ntt,
+ (size_t)4U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+ lit.snd = domain_separator;
+ return lit;
+}
+
+/**
+ 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
+ntt_multiply_89_3b(libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *self,
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *rhs)
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 out = ZERO_89_c3();
+ 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= 4
+*/
+static KRML_MUSTINLINE void
+add_to_ring_element_89_1e1(
+ 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.vector.traits.to_standard_domain
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector
+with const generics
+
+*/
+static libcrux_ml_kem_vector_portable_vector_type_PortableVector
+to_standard_domain_21(
+ 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
+add_standard_error_reduce_89_64(
+ 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 = to_standard_domain_21(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= 4
+*/
+static KRML_MUSTINLINE void
+compute_As_plus_e_c71(
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 (*matrix_A)[4U],
+ 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[4U])
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 result[4U];
+ KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U,
+ result[i] = ZERO_89_c3(););
+ for (size_t i0 = (size_t)0U;
+ i0 < Eurydice_slice_len(
+ Eurydice_array_to_slice(
+ (size_t)4U, matrix_A,
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0[4U]),
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0[4U]);
+ 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)4U, 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 =
+ ntt_multiply_89_3b(matrix_element, &s_as_ntt[j]);
+ add_to_ring_element_89_1e1(&result[i1], &product);
+ }
+ add_standard_error_reduce_89_64(&result[i1], &error_as_ntt[i1]);
+ }
+ memcpy(
+ ret, result,
+ (size_t)4U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+}
+
+/**
+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[[$4size_t]],
+libcrux_ml_kem_variant_MlKem with const generics
+- K= 4
+- PRIVATE_KEY_SIZE= 1536
+- PUBLIC_KEY_SIZE= 1568
+- RANKED_BYTES_PER_RING_ELEMENT= 1536
+- ETA1= 2
+- ETA1_RANDOMNESS_SIZE= 128
+*/
+static libcrux_ml_kem_utils_extraction_helper_Keypair1024
+generate_keypair_a21(
+ Eurydice_slice key_generation_seed)
+{
+ uint8_t hashed[64U];
+ cpa_keygen_seed_d8_72(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[4U][4U];
+ uint8_t ret[34U];
+ libcrux_ml_kem_utils_into_padded_array_6d1(seed_for_A0, ret);
+ sample_matrix_A_e71(ret, true, A_transpose);
+ uint8_t prf_input[33U];
+ libcrux_ml_kem_utils_into_padded_array_6d2(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_710 uu____2 = sample_vector_cbd_then_ntt_781(copy_of_prf_input0, 0U);
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 secret_as_ntt[4U];
+ memcpy(
+ secret_as_ntt, uu____2.fst,
+ (size_t)4U * 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[4U];
+ memcpy(
+ error_as_ntt,
+ sample_vector_cbd_then_ntt_781(copy_of_prf_input, domain_separator).fst,
+ (size_t)4U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 t_as_ntt[4U];
+ compute_As_plus_e_c71(A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt);
+ uint8_t seed_for_A[32U];
+ core_result_Result_00 dst;
+ Eurydice_slice_to_array2(&dst, seed_for_A0, Eurydice_slice, uint8_t[32U]);
+ core_result_unwrap_41_33(dst, seed_for_A);
+ uint8_t public_key_serialized[1568U];
+ serialize_public_key_671(
+ t_as_ntt, Eurydice_array_to_slice((size_t)32U, seed_for_A, uint8_t),
+ public_key_serialized);
+ uint8_t secret_key_serialized[1536U];
+ serialize_secret_key_a31(secret_as_ntt, secret_key_serialized);
+ /* Passing arrays by value in Rust generates a copy in C */
+ uint8_t copy_of_secret_key_serialized[1536U];
+ memcpy(copy_of_secret_key_serialized, secret_key_serialized,
+ (size_t)1536U * sizeof(uint8_t));
+ /* Passing arrays by value in Rust generates a copy in C */
+ uint8_t copy_of_public_key_serialized[1568U];
+ memcpy(copy_of_public_key_serialized, public_key_serialized,
+ (size_t)1568U * sizeof(uint8_t));
+ libcrux_ml_kem_utils_extraction_helper_Keypair1024 lit;
+ memcpy(lit.fst, copy_of_secret_key_serialized,
+ (size_t)1536U * sizeof(uint8_t));
+ memcpy(lit.snd, copy_of_public_key_serialized,
+ (size_t)1568U * 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[[$4size_t]]
+with const generics
+- K= 4
+- SERIALIZED_KEY_LEN= 3168
+*/
+static KRML_MUSTINLINE void
+serialize_kem_secret_key_7d(
+ Eurydice_slice private_key, Eurydice_slice public_key,
+ Eurydice_slice implicit_rejection_value, uint8_t ret[3168U])
+{
+ uint8_t out[3168U] = { 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];
+ H_f1_191(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)3168U * 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[[$4size_t]],
+libcrux_ml_kem_variant_MlKem with const generics
+- K= 4
+- CPA_PRIVATE_KEY_SIZE= 1536
+- PRIVATE_KEY_SIZE= 3168
+- PUBLIC_KEY_SIZE= 1568
+- BYTES_PER_RING_ELEMENT= 1536
+- ETA1= 2
+- ETA1_RANDOMNESS_SIZE= 128
+*/
+libcrux_ml_kem_mlkem1024_MlKem1024KeyPair
+libcrux_ml_kem_ind_cca_generate_keypair_f61(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_Keypair1024 uu____0 =
+ generate_keypair_a21(ind_cpa_keypair_randomness);
+ uint8_t ind_cpa_private_key[1536U];
+ memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1536U * sizeof(uint8_t));
+ uint8_t public_key[1568U];
+ memcpy(public_key, uu____0.snd, (size_t)1568U * sizeof(uint8_t));
+ uint8_t secret_key_serialized[3168U];
+ serialize_kem_secret_key_7d(
+ Eurydice_array_to_slice((size_t)1536U, ind_cpa_private_key, uint8_t),
+ Eurydice_array_to_slice((size_t)1568U, 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[3168U];
+ memcpy(copy_of_secret_key_serialized, secret_key_serialized,
+ (size_t)3168U * sizeof(uint8_t));
+ libcrux_ml_kem_types_MlKemPrivateKey_95 private_key =
+ libcrux_ml_kem_types_from_05_891(copy_of_secret_key_serialized);
+ libcrux_ml_kem_types_MlKemPrivateKey_95 uu____2 = private_key;
+ /* Passing arrays by value in Rust generates a copy in C */
+ uint8_t copy_of_public_key[1568U];
+ memcpy(copy_of_public_key, public_key, (size_t)1568U * sizeof(uint8_t));
+ return libcrux_ml_kem_types_from_17_821(
+ uu____2, libcrux_ml_kem_types_from_b6_961(copy_of_public_key));
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::variant::Variant for
+libcrux_ml_kem::variant::MlKem)}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.variant.entropy_preprocess_d8
+with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]]
+with const generics
+- K= 4
+*/
+static KRML_MUSTINLINE void
+entropy_preprocess_d8_d1(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 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= 1536
+- K= 4
+*/
+static KRML_MUSTINLINE void
+deserialize_ring_elements_reduced_4f3(
+ Eurydice_slice public_key,
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[4U])
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 deserialized_pk[4U];
+ KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U,
+ deserialized_pk[i] = ZERO_89_c3(););
+ 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 =
+ deserialize_to_reduced_ring_element_45(ring_element);
+ deserialized_pk[i0] = uu____0;
+ }
+ memcpy(
+ ret, deserialized_pk,
+ (size_t)4U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+}
+
+/**
+ 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[[$4size_t]] with const
+generics
+- K= 4
+- ETA2_RANDOMNESS_SIZE= 128
+- ETA2= 2
+*/
+static KRML_MUSTINLINE tuple_710
+sample_ring_element_cbd_a81(uint8_t prf_input[33U], uint8_t domain_separator)
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 error_1[4U];
+ KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U,
+ error_1[i] = ZERO_89_c3(););
+ /* 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[4U][33U];
+ KRML_MAYBE_FOR4(
+ i, (size_t)0U, (size_t)4U, (size_t)1U,
+ memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t)););
+ KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i;
+ prf_inputs[i0][32U] = domain_separator;
+ domain_separator = (uint32_t)domain_separator + 1U;);
+ uint8_t prf_outputs[4U][128U];
+ PRFxN_f1_d52(prf_inputs, prf_outputs);
+ KRML_MAYBE_FOR4(
+ i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i;
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 uu____1 =
+ sample_from_binomial_distribution_ca(
+ 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[4U];
+ memcpy(
+ copy_of_error_1, error_1,
+ (size_t)4U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+ tuple_710 lit;
+ memcpy(
+ lit.fst, copy_of_error_1,
+ (size_t)4U * 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
+PRF_7c0(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= 4
+- LEN= 128
+*/
+static KRML_MUSTINLINE void
+PRF_f1_2e4(Eurydice_slice input,
+ uint8_t ret[128U])
+{
+ PRF_7c0(input, ret);
+}
+
+/**
+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
+invert_ntt_at_layer_1_4b(
+ size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re)
+{
+ KRML_MAYBE_FOR16(
+ i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i;
+ zeta_i[0U] = zeta_i[0U] - (size_t)1U;
+ 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
+invert_ntt_at_layer_2_2b(
+ size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re)
+{
+ KRML_MAYBE_FOR16(
+ i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i;
+ zeta_i[0U] = zeta_i[0U] - (size_t)1U;
+ 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
+invert_ntt_at_layer_3_97(
+ size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re)
+{
+ KRML_MAYBE_FOR16(
+ i, (size_t)0U, (size_t)16U, (size_t)1U, size_t round = i;
+ zeta_i[0U] = zeta_i[0U] - (size_t)1U;
+ libcrux_ml_kem_vector_portable_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
+ inv_ntt_layer_int_vec_step_reduce_aa(
+ 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 = montgomery_multiply_fe_05(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
+invert_ntt_at_layer_4_plus_04(
+ 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 =
+ inv_ntt_layer_int_vec_step_reduce_aa(
+ 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= 4
+*/
+static KRML_MUSTINLINE void
+invert_ntt_montgomery_c91(
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re)
+{
+ size_t zeta_i =
+ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U;
+ invert_ntt_at_layer_1_4b(&zeta_i, re);
+ invert_ntt_at_layer_2_2b(&zeta_i, re);
+ invert_ntt_at_layer_3_97(&zeta_i, re);
+ invert_ntt_at_layer_4_plus_04(&zeta_i, re, (size_t)4U);
+ invert_ntt_at_layer_4_plus_04(&zeta_i, re, (size_t)5U);
+ invert_ntt_at_layer_4_plus_04(&zeta_i, re, (size_t)6U);
+ invert_ntt_at_layer_4_plus_04(&zeta_i, re, (size_t)7U);
+ poly_barrett_reduce_89_d8(re);
+}
+
+/**
+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
+add_error_reduce_89_5d(
+ 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= 4
+*/
+static KRML_MUSTINLINE void
+compute_vector_u_931(
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 (*a_as_ntt)[4U],
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *r_as_ntt,
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *error_1,
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[4U])
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 result[4U];
+ KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U,
+ result[i] = ZERO_89_c3(););
+ for (size_t i0 = (size_t)0U;
+ i0 < Eurydice_slice_len(
+ Eurydice_array_to_slice(
+ (size_t)4U, a_as_ntt,
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0[4U]),
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0[4U]);
+ 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)4U, 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 =
+ ntt_multiply_89_3b(a_element, &r_as_ntt[j]);
+ add_to_ring_element_89_1e1(&result[i1], &product);
+ }
+ invert_ntt_montgomery_c91(&result[i1]);
+ add_error_reduce_89_5d(&result[i1], &error_1[i1]);
+ }
+ memcpy(
+ ret, result,
+ (size_t)4U * 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 libcrux_ml_kem_vector_portable_vector_type_PortableVector
+decompress_1_3e(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
+deserialize_then_decompress_message_f7(uint8_t serialized[32U])
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re = ZERO_89_c3();
+ KRML_MAYBE_FOR16(
+ i, (size_t)0U, (size_t)16U, (size_t)1U, 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 =
+ decompress_1_3e(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
+add_message_error_reduce_89_c4(
+ 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= 4
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+compute_ring_element_v_541(
+ 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 = ZERO_89_c3();
+ KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i;
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 product =
+ ntt_multiply_89_3b(&t_as_ntt[i0], &r_as_ntt[i0]);
+ add_to_ring_element_89_1e1(&result, &product););
+ invert_ntt_montgomery_c91(&result);
+ result = add_message_error_reduce_89_c4(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
+compress_dc(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 libcrux_ml_kem_vector_portable_vector_type_PortableVector
+compress_0d_96(
+ libcrux_ml_kem_vector_portable_vector_type_PortableVector v)
+{
+ return compress_dc(v);
+}
+
+/**
+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
+compress_dc0(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 libcrux_ml_kem_vector_portable_vector_type_PortableVector
+compress_0d_960(libcrux_ml_kem_vector_portable_vector_type_PortableVector v)
+{
+ return compress_dc0(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= 352
+*/
+static KRML_MUSTINLINE void
+compress_then_serialize_11_ef0(
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, uint8_t ret[352U])
+{
+ uint8_t serialized[352U] = { 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 =
+ compress_0d_960(to_unsigned_representative_84(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)352U * 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= 11
+- OUT_LEN= 352
+*/
+static KRML_MUSTINLINE void
+compress_then_serialize_ring_element_u_2e0(
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, uint8_t ret[352U])
+{
+ uint8_t uu____0[352U];
+ compress_then_serialize_11_ef0(re, uu____0);
+ memcpy(ret, uu____0, (size_t)352U * 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= 4
+- OUT_LEN= 1408
+- COMPRESSION_FACTOR= 11
+- BLOCK_LEN= 352
+*/
+static void
+compress_then_serialize_u_281(
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 input[4U],
+ Eurydice_slice out)
+{
+ for (size_t i = (size_t)0U;
+ i < Eurydice_slice_len(
+ Eurydice_array_to_slice(
+ (size_t)4U, 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)1408U / (size_t)4U),
+ (i0 + (size_t)1U) * ((size_t)1408U / (size_t)4U), uint8_t);
+ uint8_t ret[352U];
+ compress_then_serialize_ring_element_u_2e0(&re, ret);
+ Eurydice_slice_copy(
+ uu____0, Eurydice_array_to_slice((size_t)352U, 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
+compress_dc1(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 libcrux_ml_kem_vector_portable_vector_type_PortableVector
+compress_0d_961(libcrux_ml_kem_vector_portable_vector_type_PortableVector v)
+{
+ return compress_dc1(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
+compress_then_serialize_4_80(
+ 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 =
+ compress_0d_961(to_unsigned_representative_84(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
+compress_dc2(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 libcrux_ml_kem_vector_portable_vector_type_PortableVector
+compress_0d_962(libcrux_ml_kem_vector_portable_vector_type_PortableVector v)
+{
+ return compress_dc2(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
+compress_then_serialize_5_3c(
+ 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 =
+ compress_0d_962(to_unsigned_representative_84(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= 5
+- OUT_LEN= 160
+*/
+static KRML_MUSTINLINE void
+compress_then_serialize_ring_element_v_650(
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re, Eurydice_slice out)
+{
+ compress_then_serialize_5_3c(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[[$4size_t]] with const
+generics
+- K= 4
+- CIPHERTEXT_SIZE= 1568
+- T_AS_NTT_ENCODED_SIZE= 1536
+- C1_LEN= 1408
+- C2_LEN= 160
+- U_COMPRESSION_FACTOR= 11
+- V_COMPRESSION_FACTOR= 5
+- BLOCK_LEN= 352
+- ETA1= 2
+- ETA1_RANDOMNESS_SIZE= 128
+- ETA2= 2
+- ETA2_RANDOMNESS_SIZE= 128
+*/
+static void
+encrypt_7b1(Eurydice_slice public_key, uint8_t message[32U],
+ Eurydice_slice randomness, uint8_t ret[1568U])
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 t_as_ntt[4U];
+ deserialize_ring_elements_reduced_4f3(
+ Eurydice_slice_subslice_to(public_key, (size_t)1536U, uint8_t, size_t),
+ t_as_ntt);
+ Eurydice_slice seed =
+ Eurydice_slice_subslice_from(public_key, (size_t)1536U, uint8_t, size_t);
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 A[4U][4U];
+ uint8_t ret0[34U];
+ libcrux_ml_kem_utils_into_padded_array_6d1(seed, ret0);
+ sample_matrix_A_e71(ret0, false, A);
+ uint8_t prf_input[33U];
+ libcrux_ml_kem_utils_into_padded_array_6d2(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_710 uu____1 = sample_vector_cbd_then_ntt_781(copy_of_prf_input0, 0U);
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 r_as_ntt[4U];
+ memcpy(
+ r_as_ntt, uu____1.fst,
+ (size_t)4U * 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_710 uu____3 =
+ sample_ring_element_cbd_a81(copy_of_prf_input, domain_separator0);
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 error_1[4U];
+ memcpy(
+ error_1, uu____3.fst,
+ (size_t)4U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+ uint8_t domain_separator = uu____3.snd;
+ prf_input[32U] = domain_separator;
+ uint8_t prf_output[128U];
+ PRF_f1_2e4(Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t),
+ prf_output);
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 error_2 =
+ sample_from_binomial_distribution_ca(
+ Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t));
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 u[4U];
+ compute_vector_u_931(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 =
+ deserialize_then_decompress_message_f7(copy_of_message);
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 v =
+ compute_ring_element_v_541(t_as_ntt, r_as_ntt, &error_2,
+ &message_as_ring_element);
+ uint8_t ciphertext[1568U] = { 0U };
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 uu____5[4U];
+ memcpy(
+ uu____5, u,
+ (size_t)4U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+ compress_then_serialize_u_281(
+ uu____5, Eurydice_array_to_subslice2(ciphertext, (size_t)0U,
+ (size_t)1408U, uint8_t));
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 uu____6 = v;
+ compress_then_serialize_ring_element_v_650(
+ uu____6, Eurydice_array_to_subslice_from((size_t)1568U, ciphertext,
+ (size_t)1408U, uint8_t, size_t));
+ memcpy(ret, ciphertext, (size_t)1568U * sizeof(uint8_t));
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::variant::Variant for
+libcrux_ml_kem::variant::MlKem)}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.variant.kdf_d8
+with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]]
+with const generics
+- K= 4
+- CIPHERTEXT_SIZE= 1568
+*/
+static KRML_MUSTINLINE void
+kdf_d8_93(Eurydice_slice shared_secret,
+ 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.encapsulate
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector,
+libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]],
+libcrux_ml_kem_variant_MlKem with const generics
+- K= 4
+- CIPHERTEXT_SIZE= 1568
+- PUBLIC_KEY_SIZE= 1568
+- T_AS_NTT_ENCODED_SIZE= 1536
+- C1_SIZE= 1408
+- C2_SIZE= 160
+- VECTOR_U_COMPRESSION_FACTOR= 11
+- VECTOR_V_COMPRESSION_FACTOR= 5
+- VECTOR_U_BLOCK_LEN= 352
+- ETA1= 2
+- ETA1_RANDOMNESS_SIZE= 128
+- ETA2= 2
+- ETA2_RANDOMNESS_SIZE= 128
+*/
+tuple_21
+libcrux_ml_kem_ind_cca_encapsulate_eb1(
+ libcrux_ml_kem_types_MlKemPublicKey_1f *public_key,
+ uint8_t randomness[32U])
+{
+ uint8_t randomness0[32U];
+ entropy_preprocess_d8_d1(
+ Eurydice_array_to_slice((size_t)32U, randomness, uint8_t), randomness0);
+ uint8_t to_hash[64U];
+ libcrux_ml_kem_utils_into_padded_array_6d(
+ 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];
+ H_f1_191(Eurydice_array_to_slice(
+ (size_t)1568U, libcrux_ml_kem_types_as_slice_cb_3d1(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];
+ G_f1_381(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)1568U, libcrux_ml_kem_types_as_slice_cb_3d1(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[1568U];
+ encrypt_7b1(uu____2, copy_of_randomness, pseudorandomness, ciphertext);
+ /* Passing arrays by value in Rust generates a copy in C */
+ uint8_t copy_of_ciphertext[1568U];
+ memcpy(copy_of_ciphertext, ciphertext, (size_t)1568U * sizeof(uint8_t));
+ libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext ciphertext0 =
+ libcrux_ml_kem_types_from_01_331(copy_of_ciphertext);
+ uint8_t shared_secret_array[32U];
+ kdf_d8_93(shared_secret, shared_secret_array);
+ libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext 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_21 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.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
+deserialize_to_uncompressed_ring_element_27(Eurydice_slice serialized)
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re = ZERO_89_c3();
+ 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= 4
+*/
+static KRML_MUSTINLINE void
+deserialize_secret_key_7b1(
+ Eurydice_slice secret_key,
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[4U])
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 secret_as_ntt[4U];
+ KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U,
+ secret_as_ntt[i] = ZERO_89_c3(););
+ 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 =
+ deserialize_to_uncompressed_ring_element_27(secret_bytes);
+ secret_as_ntt[i0] = uu____0;
+ }
+ memcpy(
+ ret, secret_as_ntt,
+ (size_t)4U * 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
+- $4size_t
+*/
+typedef struct IndCpaPrivateKeyUnpacked_42_s {
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 secret_as_ntt[4U];
+} IndCpaPrivateKeyUnpacked_42;
+
+/**
+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
+decompress_ciphertext_coefficient_84(
+ 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 libcrux_ml_kem_vector_portable_vector_type_PortableVector
+decompress_ciphertext_coefficient_0d_b3(
+ libcrux_ml_kem_vector_portable_vector_type_PortableVector v)
+{
+ return decompress_ciphertext_coefficient_84(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
+deserialize_then_decompress_10_50(Eurydice_slice serialized)
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re = ZERO_89_c3();
+ 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 =
+ decompress_ciphertext_coefficient_0d_b3(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
+decompress_ciphertext_coefficient_840(
+ 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 libcrux_ml_kem_vector_portable_vector_type_PortableVector
+decompress_ciphertext_coefficient_0d_b30(
+ libcrux_ml_kem_vector_portable_vector_type_PortableVector v)
+{
+ return decompress_ciphertext_coefficient_840(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
+deserialize_then_decompress_11_1f(Eurydice_slice serialized)
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re = ZERO_89_c3();
+ 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 =
+ decompress_ciphertext_coefficient_0d_b30(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= 11
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+deserialize_then_decompress_ring_element_u_c20(Eurydice_slice serialized)
+{
+ return deserialize_then_decompress_11_1f(serialized);
+}
+
+/**
+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= 11
+*/
+static KRML_MUSTINLINE void
+ntt_vector_u_6f0(
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re)
+{
+ size_t zeta_i = (size_t)0U;
+ ntt_at_layer_4_plus_8c(&zeta_i, re, (size_t)7U);
+ ntt_at_layer_4_plus_8c(&zeta_i, re, (size_t)6U);
+ ntt_at_layer_4_plus_8c(&zeta_i, re, (size_t)5U);
+ ntt_at_layer_4_plus_8c(&zeta_i, re, (size_t)4U);
+ ntt_at_layer_3_34(&zeta_i, re);
+ ntt_at_layer_2_26(&zeta_i, re);
+ ntt_at_layer_1_3c(&zeta_i, re);
+ poly_barrett_reduce_89_d8(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= 4
+- CIPHERTEXT_SIZE= 1568
+- U_COMPRESSION_FACTOR= 11
+*/
+static KRML_MUSTINLINE void
+deserialize_then_decompress_u_1a1(
+ uint8_t *ciphertext,
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[4U])
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 u_as_ntt[4U];
+ KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U,
+ u_as_ntt[i] = ZERO_89_c3(););
+ for (size_t i = (size_t)0U;
+ i < Eurydice_slice_len(
+ Eurydice_array_to_slice((size_t)1568U, ciphertext, uint8_t),
+ uint8_t) /
+ (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT *
+ (size_t)11U / (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)11U / (size_t)8U),
+ i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT *
+ (size_t)11U / (size_t)8U) +
+ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT *
+ (size_t)11U / (size_t)8U,
+ uint8_t);
+ u_as_ntt[i0] = deserialize_then_decompress_ring_element_u_c20(u_bytes);
+ ntt_vector_u_6f0(&u_as_ntt[i0]);
+ }
+ memcpy(
+ ret, u_as_ntt,
+ (size_t)4U * 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
+decompress_ciphertext_coefficient_841(
+ 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 libcrux_ml_kem_vector_portable_vector_type_PortableVector
+decompress_ciphertext_coefficient_0d_b31(
+ libcrux_ml_kem_vector_portable_vector_type_PortableVector v)
+{
+ return decompress_ciphertext_coefficient_841(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
+deserialize_then_decompress_4_94(Eurydice_slice serialized)
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re = ZERO_89_c3();
+ 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 =
+ decompress_ciphertext_coefficient_0d_b31(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
+decompress_ciphertext_coefficient_842(
+ 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 libcrux_ml_kem_vector_portable_vector_type_PortableVector
+decompress_ciphertext_coefficient_0d_b32(
+ libcrux_ml_kem_vector_portable_vector_type_PortableVector v)
+{
+ return decompress_ciphertext_coefficient_842(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
+deserialize_then_decompress_5_100(Eurydice_slice serialized)
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re = ZERO_89_c3();
+ 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 =
+ decompress_ciphertext_coefficient_0d_b32(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= 5
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+deserialize_then_decompress_ring_element_v_930(Eurydice_slice serialized)
+{
+ return deserialize_then_decompress_5_100(serialized);
+}
+
+/**
+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
+subtract_reduce_89_61(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= 4
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+compute_message_c91(
+ 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 = ZERO_89_c3();
+ KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i;
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 product =
+ ntt_multiply_89_3b(&secret_as_ntt[i0], &u_as_ntt[i0]);
+ add_to_ring_element_89_1e1(&result, &product););
+ invert_ntt_montgomery_c91(&result);
+ result = subtract_reduce_89_61(v, result);
+ return result;
+}
+
+/**
+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
+compress_then_serialize_message_d4(
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re, uint8_t ret[32U])
+{
+ uint8_t serialized[32U] = { 0U };
+ KRML_MAYBE_FOR16(
+ i, (size_t)0U, (size_t)16U, (size_t)1U, size_t i0 = i;
+ libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient =
+ to_unsigned_representative_84(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= 4
+- CIPHERTEXT_SIZE= 1568
+- VECTOR_U_ENCODED_SIZE= 1408
+- U_COMPRESSION_FACTOR= 11
+- V_COMPRESSION_FACTOR= 5
+*/
+static void
+decrypt_unpacked_6b1(IndCpaPrivateKeyUnpacked_42 *secret_key,
+ uint8_t *ciphertext, uint8_t ret[32U])
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 u_as_ntt[4U];
+ deserialize_then_decompress_u_1a1(ciphertext, u_as_ntt);
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 v =
+ deserialize_then_decompress_ring_element_v_930(
+ Eurydice_array_to_subslice_from((size_t)1568U, ciphertext,
+ (size_t)1408U, uint8_t, size_t));
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 message =
+ compute_message_c91(&v, secret_key->secret_as_ntt, u_as_ntt);
+ uint8_t ret0[32U];
+ compress_then_serialize_message_d4(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= 4
+- CIPHERTEXT_SIZE= 1568
+- VECTOR_U_ENCODED_SIZE= 1408
+- U_COMPRESSION_FACTOR= 11
+- V_COMPRESSION_FACTOR= 5
+*/
+static void
+decrypt_121(Eurydice_slice secret_key, uint8_t *ciphertext,
+ uint8_t ret[32U])
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 secret_as_ntt[4U];
+ deserialize_secret_key_7b1(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[4U];
+ memcpy(
+ copy_of_secret_as_ntt, secret_as_ntt,
+ (size_t)4U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+ IndCpaPrivateKeyUnpacked_42 secret_key_unpacked;
+ memcpy(
+ secret_key_unpacked.secret_as_ntt, copy_of_secret_as_ntt,
+ (size_t)4U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+ uint8_t ret0[32U];
+ decrypt_unpacked_6b1(&secret_key_unpacked, ciphertext, ret0);
+ memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t));
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRF
+with const generics
+- LEN= 32
+*/
+static KRML_MUSTINLINE void
+PRF_7c(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= 4
+- LEN= 32
+*/
+static KRML_MUSTINLINE void
+PRF_f1_2e3(Eurydice_slice input, uint8_t ret[32U])
+{
+ PRF_7c(input, ret);
+}
+
+/**
+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[[$4size_t]],
+libcrux_ml_kem_variant_MlKem with const generics
+- K= 4
+- SECRET_KEY_SIZE= 3168
+- CPA_SECRET_KEY_SIZE= 1536
+- PUBLIC_KEY_SIZE= 1568
+- CIPHERTEXT_SIZE= 1568
+- T_AS_NTT_ENCODED_SIZE= 1536
+- C1_SIZE= 1408
+- C2_SIZE= 160
+- VECTOR_U_COMPRESSION_FACTOR= 11
+- VECTOR_V_COMPRESSION_FACTOR= 5
+- C1_BLOCK_SIZE= 352
+- ETA1= 2
+- ETA1_RANDOMNESS_SIZE= 128
+- ETA2= 2
+- ETA2_RANDOMNESS_SIZE= 128
+- IMPLICIT_REJECTION_HASH_INPUT_SIZE= 1600
+*/
+void
+libcrux_ml_kem_ind_cca_decapsulate_1f1(
+ libcrux_ml_kem_types_MlKemPrivateKey_95 *private_key,
+ libcrux_ml_kem_mlkem1024_MlKem1024Ciphertext *ciphertext,
+ uint8_t ret[32U])
+{
+ Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at(
+ Eurydice_array_to_slice((size_t)3168U, private_key->value, uint8_t),
+ (size_t)1536U, 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)1568U, 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];
+ decrypt_121(ind_cpa_secret_key, ciphertext->value, decrypted);
+ uint8_t to_hash0[64U];
+ libcrux_ml_kem_utils_into_padded_array_6d(
+ 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];
+ G_f1_381(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[1600U];
+ libcrux_ml_kem_utils_into_padded_array_6d4(implicit_rejection_value, to_hash);
+ Eurydice_slice uu____4 = Eurydice_array_to_subslice_from(
+ (size_t)1600U, 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_d81(ciphertext),
+ uint8_t);
+ uint8_t implicit_rejection_shared_secret0[32U];
+ PRF_f1_2e3(Eurydice_array_to_slice((size_t)1600U, 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[1568U];
+ encrypt_7b1(uu____5, copy_of_decrypted, pseudorandomness,
+ expected_ciphertext);
+ uint8_t implicit_rejection_shared_secret[32U];
+ kdf_d8_93(Eurydice_array_to_slice((size_t)32U,
+ implicit_rejection_shared_secret0, uint8_t),
+ implicit_rejection_shared_secret);
+ uint8_t shared_secret[32U];
+ kdf_d8_93(shared_secret0, 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_d81(ciphertext),
+ Eurydice_array_to_slice((size_t)1568U, 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));
+}
+
+/**
+ 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= 800
+- K= 2
+*/
+static KRML_MUSTINLINE void
+deserialize_ring_elements_reduced_4f2(
+ Eurydice_slice public_key,
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[2U])
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 deserialized_pk[2U];
+ KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U,
+ deserialized_pk[i] = ZERO_89_c3(););
+ 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 =
+ deserialize_to_reduced_ring_element_45(ring_element);
+ deserialized_pk[i0] = uu____0;
+ }
+ memcpy(
+ ret, deserialized_pk,
+ (size_t)2U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+}
+
+/**
+ 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= 2
+- OUT_LEN= 768
+*/
+static KRML_MUSTINLINE void
+serialize_secret_key_a30(
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *key,
+ uint8_t ret[768U])
+{
+ uint8_t out[768U] = { 0U };
+ for (size_t i = (size_t)0U;
+ i < Eurydice_slice_len(
+ Eurydice_array_to_slice(
+ (size_t)2U, 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];
+ serialize_uncompressed_ring_element_3c(&re, ret0);
+ Eurydice_slice_copy(
+ uu____0, Eurydice_array_to_slice((size_t)384U, ret0, uint8_t), uint8_t);
+ }
+ memcpy(ret, out, (size_t)768U * 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= 2
+- RANKED_BYTES_PER_RING_ELEMENT= 768
+- PUBLIC_KEY_SIZE= 800
+*/
+static KRML_MUSTINLINE void
+serialize_public_key_670(
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *t_as_ntt,
+ Eurydice_slice seed_for_a, uint8_t ret[800U])
+{
+ uint8_t public_key_serialized[800U] = { 0U };
+ Eurydice_slice uu____0 = Eurydice_array_to_subslice2(
+ public_key_serialized, (size_t)0U, (size_t)768U, uint8_t);
+ uint8_t ret0[768U];
+ serialize_secret_key_a30(t_as_ntt, ret0);
+ Eurydice_slice_copy(
+ uu____0, Eurydice_array_to_slice((size_t)768U, ret0, uint8_t), uint8_t);
+ Eurydice_slice_copy(
+ Eurydice_array_to_subslice_from((size_t)800U, public_key_serialized,
+ (size_t)768U, uint8_t, size_t),
+ seed_for_a, uint8_t);
+ memcpy(ret, public_key_serialized, (size_t)800U * sizeof(uint8_t));
+}
+
+/**
+ 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= 2
+- RANKED_BYTES_PER_RING_ELEMENT= 768
+- PUBLIC_KEY_SIZE= 800
+*/
+bool
+libcrux_ml_kem_ind_cca_validate_public_key_b70(uint8_t *public_key)
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 deserialized_pk[2U];
+ deserialize_ring_elements_reduced_4f2(
+ Eurydice_array_to_subslice_to((size_t)800U, public_key, (size_t)768U,
+ uint8_t, size_t),
+ deserialized_pk);
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *uu____0 = deserialized_pk;
+ uint8_t public_key_serialized[800U];
+ serialize_public_key_670(
+ uu____0,
+ Eurydice_array_to_subslice_from((size_t)800U, public_key, (size_t)768U,
+ uint8_t, size_t),
+ public_key_serialized);
+ return core_array_equality___core__cmp__PartialEq__Array_U__N___for__Array_T__N____eq(
+ (size_t)800U, public_key, public_key_serialized, uint8_t, uint8_t, bool);
+}
+
+/**
+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= 2
+*/
+static KRML_MUSTINLINE void
+H_f1_190(Eurydice_slice input, uint8_t ret[32U])
+{
+ libcrux_ml_kem_hash_functions_portable_H(input, ret);
+}
+
+/**
+ 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[[$2size_t]]
+with const generics
+- K= 2
+- SECRET_KEY_SIZE= 1632
+- CIPHERTEXT_SIZE= 768
+*/
+bool
+libcrux_ml_kem_ind_cca_validate_private_key_03(
+ libcrux_ml_kem_types_MlKemPrivateKey_5e *private_key,
+ libcrux_ml_kem_types_MlKemCiphertext_e8 *_ciphertext)
+{
+ uint8_t t[32U];
+ H_f1_190(Eurydice_array_to_subslice2(
+ private_key->value, (size_t)384U * (size_t)2U,
+ (size_t)768U * (size_t)2U + (size_t)32U, uint8_t),
+ t);
+ Eurydice_slice expected = Eurydice_array_to_subslice2(
+ private_key->value, (size_t)768U * (size_t)2U + (size_t)32U,
+ (size_t)768U * (size_t)2U + (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);
+}
+
+/**
+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= 2
+*/
+static KRML_MUSTINLINE void
+G_f1_380(Eurydice_slice input, uint8_t ret[64U])
+{
+ libcrux_ml_kem_hash_functions_portable_G(input, ret);
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::variant::Variant for
+libcrux_ml_kem::variant::MlKem)}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.variant.cpa_keygen_seed_d8
+with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$2size_t]]
+with const generics
+- K= 2
+*/
+static KRML_MUSTINLINE void
+cpa_keygen_seed_d8_4d(
+ 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)2U;
+ uint8_t ret0[64U];
+ G_f1_380(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.sample_matrix_A.closure
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector,
+libcrux_ml_kem_hash_functions_portable_PortableHash[[$2size_t]] with const
+generics
+- K= 2
+*/
+static void
+closure_fc0(
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[2U])
+{
+ KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U,
+ ret[i] = ZERO_89_c3(););
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PortableHash
+with const generics
+- $2size_t
+*/
+typedef struct PortableHash_8b_s {
+ libcrux_sha3_generic_keccak_KeccakState_48 shake128_state[2U];
+} PortableHash_8b;
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.hash_functions.portable.shake128_init_absorb with const generics
+- K= 2
+*/
+static KRML_MUSTINLINE PortableHash_8b
+shake128_init_absorb_790(uint8_t input[2U][34U])
+{
+ libcrux_sha3_generic_keccak_KeccakState_48 shake128_state[2U];
+ KRML_MAYBE_FOR2(
+ i, (size_t)0U, (size_t)2U, (size_t)1U,
+ shake128_state[i] = libcrux_sha3_portable_incremental_shake128_init(););
+ KRML_MAYBE_FOR2(
+ i, (size_t)0U, (size_t)2U, (size_t)1U, 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[2U];
+ memcpy(copy_of_shake128_state, shake128_state,
+ (size_t)2U * sizeof(libcrux_sha3_generic_keccak_KeccakState_48));
+ PortableHash_8b lit;
+ memcpy(lit.shake128_state, copy_of_shake128_state,
+ (size_t)2U * 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= 2
+*/
+static KRML_MUSTINLINE PortableHash_8b
+shake128_init_absorb_f1_770(uint8_t input[2U][34U])
+{
+ /* Passing arrays by value in Rust generates a copy in C */
+ uint8_t copy_of_input[2U][34U];
+ memcpy(copy_of_input, input, (size_t)2U * sizeof(uint8_t[34U]));
+ return shake128_init_absorb_790(copy_of_input);
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.hash_functions.portable.shake128_squeeze_three_blocks with const
+generics
+- K= 2
+*/
+static KRML_MUSTINLINE void
+shake128_squeeze_three_blocks_eb0(
+ PortableHash_8b *st, uint8_t ret[2U][504U])
+{
+ uint8_t out[2U][504U] = { { 0U } };
+ KRML_MAYBE_FOR2(
+ i, (size_t)0U, (size_t)2U, (size_t)1U, 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)2U * 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= 2
+*/
+static KRML_MUSTINLINE void
+shake128_squeeze_three_blocks_f1_840(
+ PortableHash_8b *self, uint8_t ret[2U][504U])
+{
+ shake128_squeeze_three_blocks_eb0(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= 2
+- N= 504
+*/
+static KRML_MUSTINLINE bool
+sample_from_uniform_distribution_next_171(
+ uint8_t randomness[2U][504U], size_t *sampled_coefficients,
+ int16_t (*out)[272U])
+{
+ KRML_MAYBE_FOR2(
+ i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0;
+ for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) {
+ size_t r = i;
+ if (sampled_coefficients[i1] <
+ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) {
+ Eurydice_slice uu____0 = Eurydice_array_to_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;
+ KRML_MAYBE_FOR2(
+ i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i;
+ if (sampled_coefficients[i0] >=
+ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) {
+ sampled_coefficients[i0] =
+ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT;
+ } else { done = false; });
+ return done;
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.hash_functions.portable.shake128_squeeze_block with const
+generics
+- K= 2
+*/
+static KRML_MUSTINLINE void
+shake128_squeeze_block_3b0(PortableHash_8b *st,
+ uint8_t ret[2U][168U])
+{
+ uint8_t out[2U][168U] = { { 0U } };
+ KRML_MAYBE_FOR2(
+ i, (size_t)0U, (size_t)2U, (size_t)1U, 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)2U * 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= 2
+*/
+static KRML_MUSTINLINE void
+shake128_squeeze_block_f1_8e0(
+ PortableHash_8b *self, uint8_t ret[2U][168U])
+{
+ shake128_squeeze_block_3b0(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= 2
+- N= 168
+*/
+static KRML_MUSTINLINE bool
+sample_from_uniform_distribution_next_172(
+ uint8_t randomness[2U][168U], size_t *sampled_coefficients,
+ int16_t (*out)[272U])
+{
+ KRML_MAYBE_FOR2(
+ i0, (size_t)0U, (size_t)2U, (size_t)1U, size_t i1 = i0;
+ for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) {
+ size_t r = i;
+ if (sampled_coefficients[i1] <
+ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) {
+ Eurydice_slice uu____0 = Eurydice_array_to_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;
+ KRML_MAYBE_FOR2(
+ i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i;
+ if (sampled_coefficients[i0] >=
+ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) {
+ sampled_coefficients[i0] =
+ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT;
+ } else { done = false; });
+ return done;
+}
+
+/**
+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[[$2size_t]] with const
+generics
+- K= 2
+*/
+static libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+closure_e40(
+ int16_t s[272U])
+{
+ return from_i16_array_89_33(
+ 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[[$2size_t]] with const
+generics
+- K= 2
+*/
+static KRML_MUSTINLINE void
+sample_from_xof_460(
+ uint8_t seeds[2U][34U],
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[2U])
+{
+ size_t sampled_coefficients[2U] = { 0U };
+ int16_t out[2U][272U] = { { 0U } };
+ /* Passing arrays by value in Rust generates a copy in C */
+ uint8_t copy_of_seeds[2U][34U];
+ memcpy(copy_of_seeds, seeds, (size_t)2U * sizeof(uint8_t[34U]));
+ PortableHash_8b xof_state = shake128_init_absorb_f1_770(copy_of_seeds);
+ uint8_t randomness0[2U][504U];
+ shake128_squeeze_three_blocks_f1_840(&xof_state, randomness0);
+ /* Passing arrays by value in Rust generates a copy in C */
+ uint8_t copy_of_randomness0[2U][504U];
+ memcpy(copy_of_randomness0, randomness0, (size_t)2U * sizeof(uint8_t[504U]));
+ bool done = sample_from_uniform_distribution_next_171(
+ copy_of_randomness0, sampled_coefficients, out);
+ while (true) {
+ if (done) {
+ break;
+ } else {
+ uint8_t randomness[2U][168U];
+ shake128_squeeze_block_f1_8e0(&xof_state, randomness);
+ /* Passing arrays by value in Rust generates a copy in C */
+ uint8_t copy_of_randomness[2U][168U];
+ memcpy(copy_of_randomness, randomness,
+ (size_t)2U * sizeof(uint8_t[168U]));
+ done = sample_from_uniform_distribution_next_172(
+ copy_of_randomness, sampled_coefficients, out);
+ }
+ }
+ /* Passing arrays by value in Rust generates a copy in C */
+ int16_t copy_of_out[2U][272U];
+ memcpy(copy_of_out, out, (size_t)2U * sizeof(int16_t[272U]));
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret0[2U];
+ KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U,
+ ret0[i] = closure_e40(copy_of_out[i]););
+ memcpy(
+ ret, ret0,
+ (size_t)2U * 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[[$2size_t]] with const
+generics
+- K= 2
+*/
+static KRML_MUSTINLINE void
+sample_matrix_A_e70(
+ uint8_t seed[34U], bool transpose,
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[2U][2U])
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 A_transpose[2U][2U];
+ KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U,
+ closure_fc0(A_transpose[i]););
+ KRML_MAYBE_FOR2(
+ i0, (size_t)0U, (size_t)2U, (size_t)1U, 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[2U][34U]; KRML_MAYBE_FOR2(
+ i, (size_t)0U, (size_t)2U, (size_t)1U,
+ memcpy(seeds[i], copy_of_seed, (size_t)34U * sizeof(uint8_t)););
+ KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, 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[2U][34U];
+ memcpy(copy_of_seeds, seeds, (size_t)2U * sizeof(uint8_t[34U]));
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 sampled[2U];
+ sample_from_xof_460(copy_of_seeds, sampled);
+ for (size_t i = (size_t)0U;
+ i < Eurydice_slice_len(
+ Eurydice_array_to_slice(
+ (size_t)2U, 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)2U *
+ sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0[2U]));
+}
+
+/**
+A monomorphic instance of K.
+with types libcrux_ml_kem_polynomial_PolynomialRingElement
+libcrux_ml_kem_vector_portable_vector_type_PortableVector[2size_t], uint8_t
+
+*/
+typedef struct tuple_740_s {
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 fst[2U];
+ uint8_t snd;
+} tuple_740;
+
+/**
+A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRFxN
+with const generics
+- K= 2
+- LEN= 192
+*/
+static KRML_MUSTINLINE void
+PRFxN_1c0(uint8_t (*input)[33U],
+ uint8_t ret[2U][192U])
+{
+ uint8_t out[2U][192U] = { { 0U } };
+ KRML_MAYBE_FOR2(
+ i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i;
+ libcrux_sha3_portable_shake256(
+ Eurydice_array_to_slice((size_t)192U, out[i0], uint8_t),
+ Eurydice_array_to_slice((size_t)33U, input[i0], uint8_t)););
+ memcpy(ret, out, (size_t)2U * sizeof(uint8_t[192U]));
+}
+
+/**
+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= 2
+- LEN= 192
+*/
+static KRML_MUSTINLINE void
+PRFxN_f1_d50(uint8_t (*input)[33U],
+ uint8_t ret[2U][192U])
+{
+ PRFxN_1c0(input, ret);
+}
+
+/**
+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= 3
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+sample_from_binomial_distribution_ca0(Eurydice_slice randomness)
+{
+ return sample_from_binomial_distribution_3_14(randomness);
+}
+
+/**
+ 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[[$2size_t]] with const
+generics
+- K= 2
+- ETA= 3
+- ETA_RANDOMNESS_SIZE= 192
+*/
+static KRML_MUSTINLINE tuple_740
+sample_vector_cbd_then_ntt_780(
+ uint8_t prf_input[33U], uint8_t domain_separator)
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re_as_ntt[2U];
+ KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U,
+ re_as_ntt[i] = ZERO_89_c3(););
+ /* 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[2U][33U];
+ KRML_MAYBE_FOR2(
+ i, (size_t)0U, (size_t)2U, (size_t)1U,
+ memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t)););
+ KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i;
+ prf_inputs[i0][32U] = domain_separator;
+ domain_separator = (uint32_t)domain_separator + 1U;);
+ uint8_t prf_outputs[2U][192U];
+ PRFxN_f1_d50(prf_inputs, prf_outputs);
+ KRML_MAYBE_FOR2(
+ i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i;
+ re_as_ntt[i0] = sample_from_binomial_distribution_ca0(
+ Eurydice_array_to_slice((size_t)192U, prf_outputs[i0], uint8_t));
+ ntt_binomially_sampled_ring_element_63(&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[2U];
+ memcpy(
+ copy_of_re_as_ntt, re_as_ntt,
+ (size_t)2U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+ tuple_740 lit;
+ memcpy(
+ lit.fst, copy_of_re_as_ntt,
+ (size_t)2U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+ lit.snd = domain_separator;
+ return lit;
+}
+
+/**
+ 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= 2
+*/
+static KRML_MUSTINLINE void
+add_to_ring_element_89_1e0(
+ 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;
+ }
+}
+
+/**
+ 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= 2
+*/
+static KRML_MUSTINLINE void
+compute_As_plus_e_c70(
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 (*matrix_A)[2U],
+ 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[2U])
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 result[2U];
+ KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U,
+ result[i] = ZERO_89_c3(););
+ for (size_t i0 = (size_t)0U;
+ i0 < Eurydice_slice_len(
+ Eurydice_array_to_slice(
+ (size_t)2U, matrix_A,
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0[2U]),
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0[2U]);
+ 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)2U, 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 =
+ ntt_multiply_89_3b(matrix_element, &s_as_ntt[j]);
+ add_to_ring_element_89_1e0(&result[i1], &product);
+ }
+ add_standard_error_reduce_89_64(&result[i1], &error_as_ntt[i1]);
+ }
+ memcpy(
+ ret, result,
+ (size_t)2U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+}
+
+/**
+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[[$2size_t]],
+libcrux_ml_kem_variant_MlKem with const generics
+- K= 2
+- PRIVATE_KEY_SIZE= 768
+- PUBLIC_KEY_SIZE= 800
+- RANKED_BYTES_PER_RING_ELEMENT= 768
+- ETA1= 3
+- ETA1_RANDOMNESS_SIZE= 192
+*/
+static libcrux_ml_kem_utils_extraction_helper_Keypair512
+generate_keypair_a20(
+ Eurydice_slice key_generation_seed)
+{
+ uint8_t hashed[64U];
+ cpa_keygen_seed_d8_4d(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[2U][2U];
+ uint8_t ret[34U];
+ libcrux_ml_kem_utils_into_padded_array_6d1(seed_for_A0, ret);
+ sample_matrix_A_e70(ret, true, A_transpose);
+ uint8_t prf_input[33U];
+ libcrux_ml_kem_utils_into_padded_array_6d2(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_740 uu____2 = sample_vector_cbd_then_ntt_780(copy_of_prf_input0, 0U);
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 secret_as_ntt[2U];
+ memcpy(
+ secret_as_ntt, uu____2.fst,
+ (size_t)2U * 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[2U];
+ memcpy(
+ error_as_ntt,
+ sample_vector_cbd_then_ntt_780(copy_of_prf_input, domain_separator).fst,
+ (size_t)2U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 t_as_ntt[2U];
+ compute_As_plus_e_c70(A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt);
+ uint8_t seed_for_A[32U];
+ core_result_Result_00 dst;
+ Eurydice_slice_to_array2(&dst, seed_for_A0, Eurydice_slice, uint8_t[32U]);
+ core_result_unwrap_41_33(dst, seed_for_A);
+ uint8_t public_key_serialized[800U];
+ serialize_public_key_670(
+ t_as_ntt, Eurydice_array_to_slice((size_t)32U, seed_for_A, uint8_t),
+ public_key_serialized);
+ uint8_t secret_key_serialized[768U];
+ serialize_secret_key_a30(secret_as_ntt, secret_key_serialized);
+ /* Passing arrays by value in Rust generates a copy in C */
+ uint8_t copy_of_secret_key_serialized[768U];
+ memcpy(copy_of_secret_key_serialized, secret_key_serialized,
+ (size_t)768U * sizeof(uint8_t));
+ /* Passing arrays by value in Rust generates a copy in C */
+ uint8_t copy_of_public_key_serialized[800U];
+ memcpy(copy_of_public_key_serialized, public_key_serialized,
+ (size_t)800U * sizeof(uint8_t));
+ libcrux_ml_kem_utils_extraction_helper_Keypair512 lit;
+ memcpy(lit.fst, copy_of_secret_key_serialized,
+ (size_t)768U * sizeof(uint8_t));
+ memcpy(lit.snd, copy_of_public_key_serialized,
+ (size_t)800U * 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[[$2size_t]]
+with const generics
+- K= 2
+- SERIALIZED_KEY_LEN= 1632
+*/
+static KRML_MUSTINLINE void
+serialize_kem_secret_key_19(
+ Eurydice_slice private_key, Eurydice_slice public_key,
+ Eurydice_slice implicit_rejection_value, uint8_t ret[1632U])
+{
+ uint8_t out[1632U] = { 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];
+ H_f1_190(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)1632U * 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[[$2size_t]],
+libcrux_ml_kem_variant_MlKem with const generics
+- K= 2
+- CPA_PRIVATE_KEY_SIZE= 768
+- PRIVATE_KEY_SIZE= 1632
+- PUBLIC_KEY_SIZE= 800
+- BYTES_PER_RING_ELEMENT= 768
+- ETA1= 3
+- ETA1_RANDOMNESS_SIZE= 192
+*/
+libcrux_ml_kem_types_MlKemKeyPair_cb
+libcrux_ml_kem_ind_cca_generate_keypair_f60(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_Keypair512 uu____0 =
+ generate_keypair_a20(ind_cpa_keypair_randomness);
+ uint8_t ind_cpa_private_key[768U];
+ memcpy(ind_cpa_private_key, uu____0.fst, (size_t)768U * sizeof(uint8_t));
+ uint8_t public_key[800U];
+ memcpy(public_key, uu____0.snd, (size_t)800U * sizeof(uint8_t));
+ uint8_t secret_key_serialized[1632U];
+ serialize_kem_secret_key_19(
+ Eurydice_array_to_slice((size_t)768U, ind_cpa_private_key, uint8_t),
+ Eurydice_array_to_slice((size_t)800U, 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[1632U];
+ memcpy(copy_of_secret_key_serialized, secret_key_serialized,
+ (size_t)1632U * sizeof(uint8_t));
+ libcrux_ml_kem_types_MlKemPrivateKey_5e private_key =
+ libcrux_ml_kem_types_from_05_89(copy_of_secret_key_serialized);
+ libcrux_ml_kem_types_MlKemPrivateKey_5e uu____2 = private_key;
+ /* Passing arrays by value in Rust generates a copy in C */
+ uint8_t copy_of_public_key[800U];
+ memcpy(copy_of_public_key, public_key, (size_t)800U * sizeof(uint8_t));
+ return libcrux_ml_kem_types_from_17_82(
+ uu____2, libcrux_ml_kem_types_from_b6_96(copy_of_public_key));
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::variant::Variant for
+libcrux_ml_kem::variant::MlKem)}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.variant.entropy_preprocess_d8
+with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$2size_t]]
+with const generics
+- K= 2
+*/
+static KRML_MUSTINLINE void
+entropy_preprocess_d8_6c(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 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= 768
+- K= 2
+*/
+static KRML_MUSTINLINE void
+deserialize_ring_elements_reduced_4f1(
+ Eurydice_slice public_key,
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[2U])
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 deserialized_pk[2U];
+ KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U,
+ deserialized_pk[i] = ZERO_89_c3(););
+ 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 =
+ deserialize_to_reduced_ring_element_45(ring_element);
+ deserialized_pk[i0] = uu____0;
+ }
+ memcpy(
+ ret, deserialized_pk,
+ (size_t)2U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRFxN
+with const generics
+- K= 2
+- LEN= 128
+*/
+static KRML_MUSTINLINE void
+PRFxN_1c1(uint8_t (*input)[33U],
+ uint8_t ret[2U][128U])
+{
+ uint8_t out[2U][128U] = { { 0U } };
+ KRML_MAYBE_FOR2(
+ i, (size_t)0U, (size_t)2U, (size_t)1U, 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)2U * 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= 2
+- LEN= 128
+*/
+static KRML_MUSTINLINE void
+PRFxN_f1_d51(uint8_t (*input)[33U],
+ uint8_t ret[2U][128U])
+{
+ PRFxN_1c1(input, ret);
+}
+
+/**
+ 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[[$2size_t]] with const
+generics
+- K= 2
+- ETA2_RANDOMNESS_SIZE= 128
+- ETA2= 2
+*/
+static KRML_MUSTINLINE tuple_740
+sample_ring_element_cbd_a80(uint8_t prf_input[33U], uint8_t domain_separator)
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 error_1[2U];
+ KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U,
+ error_1[i] = ZERO_89_c3(););
+ /* 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[2U][33U];
+ KRML_MAYBE_FOR2(
+ i, (size_t)0U, (size_t)2U, (size_t)1U,
+ memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t)););
+ KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i;
+ prf_inputs[i0][32U] = domain_separator;
+ domain_separator = (uint32_t)domain_separator + 1U;);
+ uint8_t prf_outputs[2U][128U];
+ PRFxN_f1_d51(prf_inputs, prf_outputs);
+ KRML_MAYBE_FOR2(
+ i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i;
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 uu____1 =
+ sample_from_binomial_distribution_ca(
+ 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[2U];
+ memcpy(
+ copy_of_error_1, error_1,
+ (size_t)2U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+ tuple_740 lit;
+ memcpy(
+ lit.fst, copy_of_error_1,
+ (size_t)2U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+ lit.snd = domain_separator;
+ 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.PRF_f1
+with const generics
+- K= 2
+- LEN= 128
+*/
+static KRML_MUSTINLINE void
+PRF_f1_2e2(Eurydice_slice input,
+ uint8_t ret[128U])
+{
+ PRF_7c0(input, ret);
+}
+
+/**
+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= 2
+*/
+static KRML_MUSTINLINE void
+invert_ntt_montgomery_c90(
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re)
+{
+ size_t zeta_i =
+ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U;
+ invert_ntt_at_layer_1_4b(&zeta_i, re);
+ invert_ntt_at_layer_2_2b(&zeta_i, re);
+ invert_ntt_at_layer_3_97(&zeta_i, re);
+ invert_ntt_at_layer_4_plus_04(&zeta_i, re, (size_t)4U);
+ invert_ntt_at_layer_4_plus_04(&zeta_i, re, (size_t)5U);
+ invert_ntt_at_layer_4_plus_04(&zeta_i, re, (size_t)6U);
+ invert_ntt_at_layer_4_plus_04(&zeta_i, re, (size_t)7U);
+ poly_barrett_reduce_89_d8(re);
+}
+
+/**
+ 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= 2
+*/
+static KRML_MUSTINLINE void
+compute_vector_u_930(
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 (*a_as_ntt)[2U],
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *r_as_ntt,
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *error_1,
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[2U])
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 result[2U];
+ KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U,
+ result[i] = ZERO_89_c3(););
+ for (size_t i0 = (size_t)0U;
+ i0 < Eurydice_slice_len(
+ Eurydice_array_to_slice(
+ (size_t)2U, a_as_ntt,
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0[2U]),
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0[2U]);
+ 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)2U, 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 =
+ ntt_multiply_89_3b(a_element, &r_as_ntt[j]);
+ add_to_ring_element_89_1e0(&result[i1], &product);
+ }
+ invert_ntt_montgomery_c90(&result[i1]);
+ add_error_reduce_89_5d(&result[i1], &error_1[i1]);
+ }
+ memcpy(
+ ret, result,
+ (size_t)2U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+}
+
+/**
+ 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= 2
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+compute_ring_element_v_540(
+ 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 = ZERO_89_c3();
+ KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i;
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 product =
+ ntt_multiply_89_3b(&t_as_ntt[i0], &r_as_ntt[i0]);
+ add_to_ring_element_89_1e0(&result, &product););
+ invert_ntt_montgomery_c90(&result);
+ result = add_message_error_reduce_89_c4(error_2, message, result);
+ return result;
+}
+
+/**
+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
+compress_then_serialize_10_88(
+ 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 =
+ compress_0d_96(to_unsigned_representative_84(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.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
+compress_then_serialize_ring_element_u_2e(
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, uint8_t ret[320U])
+{
+ uint8_t uu____0[320U];
+ compress_then_serialize_10_88(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= 2
+- OUT_LEN= 640
+- COMPRESSION_FACTOR= 10
+- BLOCK_LEN= 320
+*/
+static void
+compress_then_serialize_u_280(
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 input[2U],
+ Eurydice_slice out)
+{
+ for (size_t i = (size_t)0U;
+ i < Eurydice_slice_len(
+ Eurydice_array_to_slice(
+ (size_t)2U, 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)640U / (size_t)2U),
+ (i0 + (size_t)1U) * ((size_t)640U / (size_t)2U), uint8_t);
+ uint8_t ret[320U];
+ compress_then_serialize_ring_element_u_2e(&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.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
+compress_then_serialize_ring_element_v_65(
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re, Eurydice_slice out)
+{
+ compress_then_serialize_4_80(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[[$2size_t]] with const
+generics
+- K= 2
+- CIPHERTEXT_SIZE= 768
+- T_AS_NTT_ENCODED_SIZE= 768
+- C1_LEN= 640
+- C2_LEN= 128
+- U_COMPRESSION_FACTOR= 10
+- V_COMPRESSION_FACTOR= 4
+- BLOCK_LEN= 320
+- ETA1= 3
+- ETA1_RANDOMNESS_SIZE= 192
+- ETA2= 2
+- ETA2_RANDOMNESS_SIZE= 128
+*/
+static void
+encrypt_7b0(Eurydice_slice public_key, uint8_t message[32U],
+ Eurydice_slice randomness, uint8_t ret[768U])
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 t_as_ntt[2U];
+ deserialize_ring_elements_reduced_4f1(
+ Eurydice_slice_subslice_to(public_key, (size_t)768U, uint8_t, size_t),
+ t_as_ntt);
+ Eurydice_slice seed =
+ Eurydice_slice_subslice_from(public_key, (size_t)768U, uint8_t, size_t);
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 A[2U][2U];
+ uint8_t ret0[34U];
+ libcrux_ml_kem_utils_into_padded_array_6d1(seed, ret0);
+ sample_matrix_A_e70(ret0, false, A);
+ uint8_t prf_input[33U];
+ libcrux_ml_kem_utils_into_padded_array_6d2(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_740 uu____1 = sample_vector_cbd_then_ntt_780(copy_of_prf_input0, 0U);
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 r_as_ntt[2U];
+ memcpy(
+ r_as_ntt, uu____1.fst,
+ (size_t)2U * 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_740 uu____3 =
+ sample_ring_element_cbd_a80(copy_of_prf_input, domain_separator0);
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 error_1[2U];
+ memcpy(
+ error_1, uu____3.fst,
+ (size_t)2U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+ uint8_t domain_separator = uu____3.snd;
+ prf_input[32U] = domain_separator;
+ uint8_t prf_output[128U];
+ PRF_f1_2e2(Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t),
+ prf_output);
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 error_2 =
+ sample_from_binomial_distribution_ca(
+ Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t));
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 u[2U];
+ compute_vector_u_930(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 =
+ deserialize_then_decompress_message_f7(copy_of_message);
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 v =
+ compute_ring_element_v_540(t_as_ntt, r_as_ntt, &error_2,
+ &message_as_ring_element);
+ uint8_t ciphertext[768U] = { 0U };
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 uu____5[2U];
+ memcpy(
+ uu____5, u,
+ (size_t)2U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+ compress_then_serialize_u_280(
+ uu____5, Eurydice_array_to_subslice2(ciphertext, (size_t)0U, (size_t)640U,
+ uint8_t));
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 uu____6 = v;
+ compress_then_serialize_ring_element_v_65(
+ uu____6, Eurydice_array_to_subslice_from((size_t)768U, ciphertext,
+ (size_t)640U, uint8_t, size_t));
+ memcpy(ret, ciphertext, (size_t)768U * sizeof(uint8_t));
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::variant::Variant for
+libcrux_ml_kem::variant::MlKem)}
+*/
+/**
+A monomorphic instance of libcrux_ml_kem.variant.kdf_d8
+with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$2size_t]]
+with const generics
+- K= 2
+- CIPHERTEXT_SIZE= 768
+*/
+static KRML_MUSTINLINE void
+kdf_d8_32(Eurydice_slice shared_secret,
+ 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.encapsulate
+with types libcrux_ml_kem_vector_portable_vector_type_PortableVector,
+libcrux_ml_kem_hash_functions_portable_PortableHash[[$2size_t]],
+libcrux_ml_kem_variant_MlKem with const generics
+- K= 2
+- CIPHERTEXT_SIZE= 768
+- PUBLIC_KEY_SIZE= 800
+- T_AS_NTT_ENCODED_SIZE= 768
+- C1_SIZE= 640
+- C2_SIZE= 128
+- VECTOR_U_COMPRESSION_FACTOR= 10
+- VECTOR_V_COMPRESSION_FACTOR= 4
+- VECTOR_U_BLOCK_LEN= 320
+- ETA1= 3
+- ETA1_RANDOMNESS_SIZE= 192
+- ETA2= 2
+- ETA2_RANDOMNESS_SIZE= 128
+*/
+tuple_ec
+libcrux_ml_kem_ind_cca_encapsulate_eb0(
+ libcrux_ml_kem_types_MlKemPublicKey_be *public_key,
+ uint8_t randomness[32U])
+{
+ uint8_t randomness0[32U];
+ entropy_preprocess_d8_6c(
+ Eurydice_array_to_slice((size_t)32U, randomness, uint8_t), randomness0);
+ uint8_t to_hash[64U];
+ libcrux_ml_kem_utils_into_padded_array_6d(
+ 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];
+ H_f1_190(Eurydice_array_to_slice(
+ (size_t)800U, libcrux_ml_kem_types_as_slice_cb_3d(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];
+ G_f1_380(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)800U, libcrux_ml_kem_types_as_slice_cb_3d(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[768U];
+ encrypt_7b0(uu____2, copy_of_randomness, pseudorandomness, ciphertext);
+ /* Passing arrays by value in Rust generates a copy in C */
+ uint8_t copy_of_ciphertext[768U];
+ memcpy(copy_of_ciphertext, ciphertext, (size_t)768U * sizeof(uint8_t));
+ libcrux_ml_kem_types_MlKemCiphertext_e8 ciphertext0 =
+ libcrux_ml_kem_types_from_01_33(copy_of_ciphertext);
+ uint8_t shared_secret_array[32U];
+ kdf_d8_32(shared_secret, shared_secret_array);
+ libcrux_ml_kem_types_MlKemCiphertext_e8 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_ec lit;
+ lit.fst = uu____5;
+ memcpy(lit.snd, copy_of_shared_secret_array, (size_t)32U * sizeof(uint8_t));
+ return lit;
+}
+
+/**
+ 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= 2
+*/
+static KRML_MUSTINLINE void
+deserialize_secret_key_7b0(
+ Eurydice_slice secret_key,
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[2U])
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 secret_as_ntt[2U];
+ KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U,
+ secret_as_ntt[i] = ZERO_89_c3(););
+ 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 =
+ deserialize_to_uncompressed_ring_element_27(secret_bytes);
+ secret_as_ntt[i0] = uu____0;
+ }
+ memcpy(
+ ret, secret_as_ntt,
+ (size_t)2U * 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
+- $2size_t
+*/
+typedef struct IndCpaPrivateKeyUnpacked_ae_s {
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 secret_as_ntt[2U];
+} IndCpaPrivateKeyUnpacked_ae;
+
+/**
+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
+deserialize_then_decompress_ring_element_u_c2(Eurydice_slice serialized)
+{
+ return deserialize_then_decompress_10_50(serialized);
+}
+
+/**
+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
+ntt_vector_u_6f(
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re)
+{
+ size_t zeta_i = (size_t)0U;
+ ntt_at_layer_4_plus_8c(&zeta_i, re, (size_t)7U);
+ ntt_at_layer_4_plus_8c(&zeta_i, re, (size_t)6U);
+ ntt_at_layer_4_plus_8c(&zeta_i, re, (size_t)5U);
+ ntt_at_layer_4_plus_8c(&zeta_i, re, (size_t)4U);
+ ntt_at_layer_3_34(&zeta_i, re);
+ ntt_at_layer_2_26(&zeta_i, re);
+ ntt_at_layer_1_3c(&zeta_i, re);
+ poly_barrett_reduce_89_d8(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= 2
+- CIPHERTEXT_SIZE= 768
+- U_COMPRESSION_FACTOR= 10
+*/
+static KRML_MUSTINLINE void
+deserialize_then_decompress_u_1a0(
+ uint8_t *ciphertext,
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[2U])
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 u_as_ntt[2U];
+ KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U,
+ u_as_ntt[i] = ZERO_89_c3(););
+ for (size_t i = (size_t)0U;
+ i < Eurydice_slice_len(
+ Eurydice_array_to_slice((size_t)768U, 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] = deserialize_then_decompress_ring_element_u_c2(u_bytes);
+ ntt_vector_u_6f(&u_as_ntt[i0]);
+ }
+ memcpy(
+ ret, u_as_ntt,
+ (size_t)2U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+}
+
+/**
+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
+deserialize_then_decompress_ring_element_v_93(Eurydice_slice serialized)
+{
+ return deserialize_then_decompress_4_94(serialized);
+}
+
+/**
+ 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= 2
+*/
+static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+compute_message_c90(
+ 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 = ZERO_89_c3();
+ KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i;
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 product =
+ ntt_multiply_89_3b(&secret_as_ntt[i0], &u_as_ntt[i0]);
+ add_to_ring_element_89_1e0(&result, &product););
+ invert_ntt_montgomery_c90(&result);
+ result = subtract_reduce_89_61(v, result);
+ return result;
+}
+
+/**
+ 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= 2
+- CIPHERTEXT_SIZE= 768
+- VECTOR_U_ENCODED_SIZE= 640
+- U_COMPRESSION_FACTOR= 10
+- V_COMPRESSION_FACTOR= 4
+*/
+static void
+decrypt_unpacked_6b0(IndCpaPrivateKeyUnpacked_ae *secret_key,
+ uint8_t *ciphertext, uint8_t ret[32U])
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 u_as_ntt[2U];
+ deserialize_then_decompress_u_1a0(ciphertext, u_as_ntt);
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 v =
+ deserialize_then_decompress_ring_element_v_93(
+ Eurydice_array_to_subslice_from((size_t)768U, ciphertext,
+ (size_t)640U, uint8_t, size_t));
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 message =
+ compute_message_c90(&v, secret_key->secret_as_ntt, u_as_ntt);
+ uint8_t ret0[32U];
+ compress_then_serialize_message_d4(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= 2
+- CIPHERTEXT_SIZE= 768
+- VECTOR_U_ENCODED_SIZE= 640
+- U_COMPRESSION_FACTOR= 10
+- V_COMPRESSION_FACTOR= 4
+*/
+static void
+decrypt_120(Eurydice_slice secret_key, uint8_t *ciphertext,
+ uint8_t ret[32U])
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 secret_as_ntt[2U];
+ deserialize_secret_key_7b0(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[2U];
+ memcpy(
+ copy_of_secret_as_ntt, secret_as_ntt,
+ (size_t)2U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+ IndCpaPrivateKeyUnpacked_ae secret_key_unpacked;
+ memcpy(
+ secret_key_unpacked.secret_as_ntt, copy_of_secret_as_ntt,
+ (size_t)2U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+ uint8_t ret0[32U];
+ decrypt_unpacked_6b0(&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.PRF_f1
+with const generics
+- K= 2
+- LEN= 32
+*/
+static KRML_MUSTINLINE void
+PRF_f1_2e1(Eurydice_slice input, uint8_t ret[32U])
+{
+ PRF_7c(input, ret);
+}
+
+/**
+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[[$2size_t]],
+libcrux_ml_kem_variant_MlKem with const generics
+- K= 2
+- SECRET_KEY_SIZE= 1632
+- CPA_SECRET_KEY_SIZE= 768
+- PUBLIC_KEY_SIZE= 800
+- CIPHERTEXT_SIZE= 768
+- T_AS_NTT_ENCODED_SIZE= 768
+- C1_SIZE= 640
+- C2_SIZE= 128
+- VECTOR_U_COMPRESSION_FACTOR= 10
+- VECTOR_V_COMPRESSION_FACTOR= 4
+- C1_BLOCK_SIZE= 320
+- ETA1= 3
+- ETA1_RANDOMNESS_SIZE= 192
+- ETA2= 2
+- ETA2_RANDOMNESS_SIZE= 128
+- IMPLICIT_REJECTION_HASH_INPUT_SIZE= 800
+*/
+void
+libcrux_ml_kem_ind_cca_decapsulate_1f0(
+ libcrux_ml_kem_types_MlKemPrivateKey_5e *private_key,
+ libcrux_ml_kem_types_MlKemCiphertext_e8 *ciphertext, uint8_t ret[32U])
+{
+ Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at(
+ Eurydice_array_to_slice((size_t)1632U, private_key->value, uint8_t),
+ (size_t)768U, 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)800U, 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];
+ decrypt_120(ind_cpa_secret_key, ciphertext->value, decrypted);
+ uint8_t to_hash0[64U];
+ libcrux_ml_kem_utils_into_padded_array_6d(
+ 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];
+ G_f1_380(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[800U];
+ libcrux_ml_kem_utils_into_padded_array_6d0(implicit_rejection_value, to_hash);
+ Eurydice_slice uu____4 = Eurydice_array_to_subslice_from(
+ (size_t)800U, 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_d8(ciphertext),
+ uint8_t);
+ uint8_t implicit_rejection_shared_secret0[32U];
+ PRF_f1_2e1(Eurydice_array_to_slice((size_t)800U, 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[768U];
+ encrypt_7b0(uu____5, copy_of_decrypted, pseudorandomness,
+ expected_ciphertext);
+ uint8_t implicit_rejection_shared_secret[32U];
+ kdf_d8_32(Eurydice_array_to_slice((size_t)32U,
+ implicit_rejection_shared_secret0, uint8_t),
+ implicit_rejection_shared_secret);
+ uint8_t shared_secret[32U];
+ kdf_d8_32(shared_secret0, 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_d8(ciphertext),
+ Eurydice_array_to_slice((size_t)768U, 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));
+}
+
+/**
+ 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
+deserialize_ring_elements_reduced_4f0(
+ Eurydice_slice public_key,
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U])
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 deserialized_pk[3U];
+ KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U,
+ deserialized_pk[i] = ZERO_89_c3(););
+ 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 =
+ deserialize_to_reduced_ring_element_45(ring_element);
+ deserialized_pk[i0] = uu____0;
+ }
+ memcpy(
+ ret, deserialized_pk,
+ (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+}
+
+/**
+ 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
+serialize_secret_key_a3(
+ 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];
+ serialize_uncompressed_ring_element_3c(&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
+serialize_public_key_67(
+ 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];
+ serialize_secret_key_a3(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));
+}
+
+/**
+ 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
+*/
+bool
+libcrux_ml_kem_ind_cca_validate_public_key_b7(uint8_t *public_key)
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 deserialized_pk[3U];
+ deserialize_ring_elements_reduced_4f0(
+ 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];
+ serialize_public_key_67(
+ 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);
+}
+
+/**
+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
+H_f1_19(Eurydice_slice input, uint8_t ret[32U])
+{
+ libcrux_ml_kem_hash_functions_portable_H(input, ret);
+}
+
+/**
+ 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
+*/
+bool
+libcrux_ml_kem_ind_cca_validate_private_key_05(
+ libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key,
+ libcrux_ml_kem_mlkem768_MlKem768Ciphertext *_ciphertext)
+{
+ uint8_t t[32U];
+ H_f1_19(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);
+}
+
+/**
+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
+G_f1_38(Eurydice_slice input, uint8_t ret[64U])
+{
+ libcrux_ml_kem_hash_functions_portable_G(input, ret);
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::variant::Variant for
+libcrux_ml_kem::variant::MlKem)}
+*/
+/**
+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
+cpa_keygen_seed_d8_b0(
+ 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];
+ G_f1_38(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.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 void
+closure_fc(
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U])
+{
+ KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U,
+ ret[i] = ZERO_89_c3(););
+}
+
+/**
+A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PortableHash
+with const generics
+- $3size_t
+*/
+typedef struct PortableHash_58_s {
+ libcrux_sha3_generic_keccak_KeccakState_48 shake128_state[3U];
+} PortableHash_58;
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.hash_functions.portable.shake128_init_absorb with const generics
+- K= 3
+*/
+static KRML_MUSTINLINE PortableHash_58
+shake128_init_absorb_79(uint8_t input[3U][34U])
+{
+ libcrux_sha3_generic_keccak_KeccakState_48 shake128_state[3U];
+ KRML_MAYBE_FOR3(
+ i, (size_t)0U, (size_t)3U, (size_t)1U,
+ shake128_state[i] = libcrux_sha3_portable_incremental_shake128_init(););
+ KRML_MAYBE_FOR3(
+ i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i;
+ libcrux_sha3_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));
+ 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 PortableHash_58
+shake128_init_absorb_f1_77(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 shake128_init_absorb_79(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
+shake128_squeeze_three_blocks_eb(
+ PortableHash_58 *st, uint8_t ret[3U][504U])
+{
+ uint8_t out[3U][504U] = { { 0U } };
+ KRML_MAYBE_FOR3(
+ i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i;
+ libcrux_sha3_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
+shake128_squeeze_three_blocks_f1_84(
+ PortableHash_58 *self, uint8_t ret[3U][504U])
+{
+ shake128_squeeze_three_blocks_eb(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
+sample_from_uniform_distribution_next_17(
+ uint8_t randomness[3U][504U], size_t *sampled_coefficients,
+ int16_t (*out)[272U])
+{
+ KRML_MAYBE_FOR3(
+ i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0;
+ for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) {
+ size_t r = i;
+ if (sampled_coefficients[i1] <
+ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) {
+ Eurydice_slice uu____0 = Eurydice_array_to_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;
+ KRML_MAYBE_FOR3(
+ i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i;
+ if (sampled_coefficients[i0] >=
+ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) {
+ sampled_coefficients[i0] =
+ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT;
+ } else { done = false; });
+ return done;
+}
+
+/**
+A monomorphic instance of
+libcrux_ml_kem.hash_functions.portable.shake128_squeeze_block with const
+generics
+- K= 3
+*/
+static KRML_MUSTINLINE void
+shake128_squeeze_block_3b(PortableHash_58 *st,
+ uint8_t ret[3U][168U])
+{
+ uint8_t out[3U][168U] = { { 0U } };
+ KRML_MAYBE_FOR3(
+ i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i;
+ libcrux_sha3_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
+shake128_squeeze_block_f1_8e(
+ PortableHash_58 *self, uint8_t ret[3U][168U])
+{
+ shake128_squeeze_block_3b(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
+sample_from_uniform_distribution_next_170(
+ uint8_t randomness[3U][168U], size_t *sampled_coefficients,
+ int16_t (*out)[272U])
+{
+ KRML_MAYBE_FOR3(
+ i0, (size_t)0U, (size_t)3U, (size_t)1U, size_t i1 = i0;
+ for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) {
+ size_t r = i;
+ if (sampled_coefficients[i1] <
+ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) {
+ Eurydice_slice uu____0 = Eurydice_array_to_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;
+ KRML_MAYBE_FOR3(
+ i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i;
+ if (sampled_coefficients[i0] >=
+ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) {
+ sampled_coefficients[i0] =
+ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT;
+ } else { done = false; });
+ return done;
+}
+
+/**
+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 libcrux_ml_kem_polynomial_PolynomialRingElement_f0
+closure_e4(
+ int16_t s[272U])
+{
+ return from_i16_array_89_33(
+ 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
+sample_from_xof_46(
+ 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]));
+ PortableHash_58 xof_state = shake128_init_absorb_f1_77(copy_of_seeds);
+ uint8_t randomness0[3U][504U];
+ shake128_squeeze_three_blocks_f1_84(&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 = sample_from_uniform_distribution_next_17(
+ copy_of_randomness0, sampled_coefficients, out);
+ while (true) {
+ if (done) {
+ break;
+ } else {
+ uint8_t randomness[3U][168U];
+ shake128_squeeze_block_f1_8e(&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 = sample_from_uniform_distribution_next_170(
+ 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];
+ KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U,
+ ret0[i] = closure_e4(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
+sample_matrix_A_e7(
+ 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];
+ KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U,
+ closure_fc(A_transpose[i]););
+ KRML_MAYBE_FOR3(
+ i0, (size_t)0U, (size_t)3U, (size_t)1U, 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]; KRML_MAYBE_FOR3(
+ i, (size_t)0U, (size_t)3U, (size_t)1U,
+ memcpy(seeds[i], copy_of_seed, (size_t)34U * sizeof(uint8_t)););
+ KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t j = i;
+ seeds[j][32U] = (uint8_t)i1; seeds[j][33U] = (uint8_t)j;);
+ /* 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];
+ sample_from_xof_46(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.hash_functions.portable.PRFxN
+with const generics
+- K= 3
+- LEN= 128
+*/
+static KRML_MUSTINLINE void
+PRFxN_1c(uint8_t (*input)[33U],
+ uint8_t ret[3U][128U])
+{
+ uint8_t out[3U][128U] = { { 0U } };
+ KRML_MAYBE_FOR3(
+ i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i;
+ 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
+PRFxN_f1_d5(uint8_t (*input)[33U],
+ uint8_t ret[3U][128U])
+{
+ PRFxN_1c(input, ret);
+}
+
+/**
+ 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
+sample_vector_cbd_then_ntt_78(
+ uint8_t prf_input[33U], uint8_t domain_separator)
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re_as_ntt[3U];
+ KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U,
+ re_as_ntt[i] = ZERO_89_c3(););
+ /* 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];
+ KRML_MAYBE_FOR3(
+ i, (size_t)0U, (size_t)3U, (size_t)1U,
+ memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t)););
+ KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i;
+ prf_inputs[i0][32U] = domain_separator;
+ domain_separator = (uint32_t)domain_separator + 1U;);
+ uint8_t prf_outputs[3U][128U];
+ PRFxN_f1_d5(prf_inputs, prf_outputs);
+ KRML_MAYBE_FOR3(
+ i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i;
+ re_as_ntt[i0] = sample_from_binomial_distribution_ca(
+ Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], uint8_t));
+ ntt_binomially_sampled_ring_element_63(&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;
+}
+
+/**
+ 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
+add_to_ring_element_89_1e(
+ 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;
+ }
+}
+
+/**
+ 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
+compute_As_plus_e_c7(
+ 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];
+ KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U,
+ result[i] = ZERO_89_c3(););
+ 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 =
+ ntt_multiply_89_3b(matrix_element, &s_as_ntt[j]);
+ add_to_ring_element_89_1e(&result[i1], &product);
+ }
+ add_standard_error_reduce_89_64(&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.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 libcrux_ml_kem_utils_extraction_helper_Keypair768
+generate_keypair_a2(
+ Eurydice_slice key_generation_seed)
+{
+ uint8_t hashed[64U];
+ cpa_keygen_seed_d8_b0(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_6d1(seed_for_A0, ret);
+ sample_matrix_A_e7(ret, true, A_transpose);
+ uint8_t prf_input[33U];
+ libcrux_ml_kem_utils_into_padded_array_6d2(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 = sample_vector_cbd_then_ntt_78(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,
+ sample_vector_cbd_then_ntt_78(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];
+ compute_As_plus_e_c7(A_transpose, secret_as_ntt, error_as_ntt, t_as_ntt);
+ uint8_t seed_for_A[32U];
+ core_result_Result_00 dst;
+ Eurydice_slice_to_array2(&dst, seed_for_A0, Eurydice_slice, uint8_t[32U]);
+ core_result_unwrap_41_33(dst, seed_for_A);
+ uint8_t public_key_serialized[1184U];
+ serialize_public_key_67(
+ t_as_ntt, Eurydice_array_to_slice((size_t)32U, seed_for_A, uint8_t),
+ public_key_serialized);
+ uint8_t secret_key_serialized[1152U];
+ serialize_secret_key_a3(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
+serialize_kem_secret_key_5d(
+ 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];
+ H_f1_19(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
+*/
+libcrux_ml_kem_mlkem768_MlKem768KeyPair
+libcrux_ml_kem_ind_cca_generate_keypair_f6(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 =
+ generate_keypair_a2(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];
+ serialize_kem_secret_key_5d(
+ 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_890(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_820(
+ uu____2, libcrux_ml_kem_types_from_b6_960(copy_of_public_key));
+}
+
+/**
+This function found in impl {(libcrux_ml_kem::variant::Variant for
+libcrux_ml_kem::variant::MlKem)}
+*/
+/**
+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
+entropy_preprocess_d8_9f(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 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
+deserialize_ring_elements_reduced_4f(
+ Eurydice_slice public_key,
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U])
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 deserialized_pk[3U];
+ KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U,
+ deserialized_pk[i] = ZERO_89_c3(););
+ 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 =
+ deserialize_to_reduced_ring_element_45(ring_element);
+ deserialized_pk[i0] = uu____0;
+ }
+ memcpy(
+ ret, deserialized_pk,
+ (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+}
+
+/**
+ 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
+sample_ring_element_cbd_a8(uint8_t prf_input[33U], uint8_t domain_separator)
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 error_1[3U];
+ KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U,
+ error_1[i] = ZERO_89_c3(););
+ /* 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];
+ KRML_MAYBE_FOR3(
+ i, (size_t)0U, (size_t)3U, (size_t)1U,
+ memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t)););
+ KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i;
+ prf_inputs[i0][32U] = domain_separator;
+ domain_separator = (uint32_t)domain_separator + 1U;);
+ uint8_t prf_outputs[3U][128U];
+ PRFxN_f1_d5(prf_inputs, prf_outputs);
+ KRML_MAYBE_FOR3(
+ i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i;
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 uu____1 =
+ sample_from_binomial_distribution_ca(
+ 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;
+}
+
+/**
+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
+PRF_f1_2e0(Eurydice_slice input,
+ uint8_t ret[128U])
+{
+ PRF_7c0(input, ret);
+}
+
+/**
+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
+invert_ntt_montgomery_c9(
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re)
+{
+ size_t zeta_i =
+ LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U;
+ invert_ntt_at_layer_1_4b(&zeta_i, re);
+ invert_ntt_at_layer_2_2b(&zeta_i, re);
+ invert_ntt_at_layer_3_97(&zeta_i, re);
+ invert_ntt_at_layer_4_plus_04(&zeta_i, re, (size_t)4U);
+ invert_ntt_at_layer_4_plus_04(&zeta_i, re, (size_t)5U);
+ invert_ntt_at_layer_4_plus_04(&zeta_i, re, (size_t)6U);
+ invert_ntt_at_layer_4_plus_04(&zeta_i, re, (size_t)7U);
+ poly_barrett_reduce_89_d8(re);
+}
+
+/**
+ 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
+compute_vector_u_93(
+ 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];
+ KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U,
+ result[i] = ZERO_89_c3(););
+ 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 =
+ ntt_multiply_89_3b(a_element, &r_as_ntt[j]);
+ add_to_ring_element_89_1e(&result[i1], &product);
+ }
+ invert_ntt_montgomery_c9(&result[i1]);
+ add_error_reduce_89_5d(&result[i1], &error_1[i1]);
+ }
+ memcpy(
+ ret, result,
+ (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+}
+
+/**
+ 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
+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 = ZERO_89_c3();
+ KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i;
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 product =
+ ntt_multiply_89_3b(&t_as_ntt[i0], &r_as_ntt[i0]);
+ add_to_ring_element_89_1e(&result, &product););
+ invert_ntt_montgomery_c9(&result);
+ result = add_message_error_reduce_89_c4(error_2, message, result);
+ return result;
+}
+
+/**
+ 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 void
+compress_then_serialize_u_28(
+ 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];
+ compress_then_serialize_ring_element_u_2e(&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.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 void
+encrypt_7b(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];
+ deserialize_ring_elements_reduced_4f(
+ 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_6d1(seed, ret0);
+ sample_matrix_A_e7(ret0, false, A);
+ uint8_t prf_input[33U];
+ libcrux_ml_kem_utils_into_padded_array_6d2(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 = sample_vector_cbd_then_ntt_78(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 =
+ sample_ring_element_cbd_a8(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];
+ PRF_f1_2e0(Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t),
+ prf_output);
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 error_2 =
+ sample_from_binomial_distribution_ca(
+ Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t));
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 u[3U];
+ compute_vector_u_93(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 =
+ deserialize_then_decompress_message_f7(copy_of_message);
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 v =
+ 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));
+ compress_then_serialize_u_28(
+ uu____5, Eurydice_array_to_subslice2(ciphertext, (size_t)0U, (size_t)960U,
+ uint8_t));
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 uu____6 = v;
+ compress_then_serialize_ring_element_v_65(
+ 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)}
+*/
+/**
+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
+kdf_d8_c5(Eurydice_slice shared_secret,
+ 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.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
+*/
+tuple_3c
+libcrux_ml_kem_ind_cca_encapsulate_eb(
+ libcrux_ml_kem_types_MlKemPublicKey_15 *public_key,
+ uint8_t randomness[32U])
+{
+ uint8_t randomness0[32U];
+ entropy_preprocess_d8_9f(
+ Eurydice_array_to_slice((size_t)32U, randomness, uint8_t), randomness0);
+ uint8_t to_hash[64U];
+ libcrux_ml_kem_utils_into_padded_array_6d(
+ 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];
+ H_f1_19(Eurydice_array_to_slice(
+ (size_t)1184U, libcrux_ml_kem_types_as_slice_cb_3d0(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];
+ G_f1_38(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_3d0(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];
+ encrypt_7b(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_330(copy_of_ciphertext);
+ uint8_t shared_secret_array[32U];
+ kdf_d8_c5(shared_secret, 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;
+}
+
+/**
+ 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
+deserialize_secret_key_7b(
+ Eurydice_slice secret_key,
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U])
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 secret_as_ntt[3U];
+ KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U,
+ secret_as_ntt[i] = ZERO_89_c3(););
+ 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 =
+ deserialize_to_uncompressed_ring_element_27(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 IndCpaPrivateKeyUnpacked_f8_s {
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 secret_as_ntt[3U];
+} IndCpaPrivateKeyUnpacked_f8;
+
+/**
+ 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
+deserialize_then_decompress_u_1a(
+ uint8_t *ciphertext,
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U])
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 u_as_ntt[3U];
+ KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U,
+ u_as_ntt[i] = ZERO_89_c3(););
+ 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] = deserialize_then_decompress_ring_element_u_c2(u_bytes);
+ ntt_vector_u_6f(&u_as_ntt[i0]);
+ }
+ memcpy(
+ ret, u_as_ntt,
+ (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0));
+}
+
+/**
+ 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
+compute_message_c9(
+ 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 = ZERO_89_c3();
+ KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i;
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 product =
+ ntt_multiply_89_3b(&secret_as_ntt[i0], &u_as_ntt[i0]);
+ add_to_ring_element_89_1e(&result, &product););
+ invert_ntt_montgomery_c9(&result);
+ result = subtract_reduce_89_61(v, result);
+ return result;
+}
+
+/**
+ 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 void
+decrypt_unpacked_6b(IndCpaPrivateKeyUnpacked_f8 *secret_key,
+ uint8_t *ciphertext, uint8_t ret[32U])
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 u_as_ntt[3U];
+ deserialize_then_decompress_u_1a(ciphertext, u_as_ntt);
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 v =
+ deserialize_then_decompress_ring_element_v_93(
+ Eurydice_array_to_subslice_from((size_t)1088U, ciphertext,
+ (size_t)960U, uint8_t, size_t));
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 message =
+ compute_message_c9(&v, secret_key->secret_as_ntt, u_as_ntt);
+ uint8_t ret0[32U];
+ compress_then_serialize_message_d4(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 void
+decrypt_12(Eurydice_slice secret_key, uint8_t *ciphertext,
+ uint8_t ret[32U])
+{
+ libcrux_ml_kem_polynomial_PolynomialRingElement_f0 secret_as_ntt[3U];
+ deserialize_secret_key_7b(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));
+ 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];
+ decrypt_unpacked_6b(&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.PRF_f1
+with const generics
+- K= 3
+- LEN= 32
+*/
+static KRML_MUSTINLINE void
+PRF_f1_2e(Eurydice_slice input, uint8_t ret[32U])
+{
+ PRF_7c(input, ret);
+}
+
+/**
+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
+*/
+void
+libcrux_ml_kem_ind_cca_decapsulate_1f(
+ 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];
+ decrypt_12(ind_cpa_secret_key, ciphertext->value, decrypted);
+ uint8_t to_hash0[64U];
+ libcrux_ml_kem_utils_into_padded_array_6d(
+ 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];
+ G_f1_38(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_6d3(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_d80(ciphertext),
+ uint8_t);
+ uint8_t implicit_rejection_shared_secret0[32U];
+ PRF_f1_2e(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];
+ encrypt_7b(uu____5, copy_of_decrypted, pseudorandomness, expected_ciphertext);
+ uint8_t implicit_rejection_shared_secret[32U];
+ kdf_d8_c5(Eurydice_array_to_slice((size_t)32U,
+ implicit_rejection_shared_secret0, uint8_t),
+ implicit_rejection_shared_secret);
+ uint8_t shared_secret[32U];
+ kdf_d8_c5(shared_secret0, 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_d80(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));
+}
diff -up ./lib/freebl/verified/libcrux_mlkem_portable.h.mlkem ./lib/freebl/verified/libcrux_mlkem_portable.h
--- ./lib/freebl/verified/libcrux_mlkem_portable.h.mlkem 2024-10-31 14:54:15.465515959 -0700
+++ ./lib/freebl/verified/libcrux_mlkem_portable.h 2024-10-31 14:54:15.465515959 -0700
@@ -0,0 +1,643 @@
+/*
+ * 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: b351338f6a84c7a1afc27433eb0ffdc668b3581d
+ * Eurydice: 7efec1624422fd5e94388ef06b9c76dfe7a48d46
+ * Karamel: c96fb69d15693284644d6aecaa90afa37e4de8f0
+ * F*: 58c915a86a2c07c8eca8d9deafd76cb7a91f0eb7
+ * Libcrux: 6ff01fb3c57ff29ecb59bc62d9dc7fd231060cfb
+ */
+
+#ifndef __libcrux_mlkem_portable_H
+#define __libcrux_mlkem_portable_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include "eurydice_glue.h"
+#include "libcrux_core.h"
+#include "libcrux_sha3.h"
+#include "libcrux_sha3_internal.h"
+
+void libcrux_ml_kem_hash_functions_portable_G(Eurydice_slice input,
+ uint8_t ret[64U]);
+
+void libcrux_ml_kem_hash_functions_portable_H(Eurydice_slice input,
+ uint8_t ret[32U]);
+
+#define LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR ((size_t)16U)
+
+#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;
+
+libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_vector_type_from_i16_array(Eurydice_slice array);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_from_i16_array_0d(Eurydice_slice 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;
+
+uint8_t_x11 libcrux_ml_kem_vector_portable_serialize_serialize_11_int(
+ Eurydice_slice v);
+
+void libcrux_ml_kem_vector_portable_serialize_serialize_11(
+ libcrux_ml_kem_vector_portable_vector_type_PortableVector v,
+ uint8_t ret[22U]);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+void libcrux_ml_kem_vector_portable_serialize_11_0d(
+ libcrux_ml_kem_vector_portable_vector_type_PortableVector a,
+ uint8_t ret[22U]);
+
+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;
+
+int16_t_x8 libcrux_ml_kem_vector_portable_serialize_deserialize_11_int(
+ Eurydice_slice bytes);
+
+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
+libcrux_ml_kem_vector_portable_serialize_deserialize_11(Eurydice_slice bytes);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_deserialize_11_0d(Eurydice_slice a);
+
+void libcrux_ml_kem_vector_portable_vector_type_to_i16_array(
+ libcrux_ml_kem_vector_portable_vector_type_PortableVector x,
+ int16_t ret[16U]);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+void libcrux_ml_kem_vector_portable_to_i16_array_0d(
+ libcrux_ml_kem_vector_portable_vector_type_PortableVector x,
+ int16_t ret[16U]);
+
+extern const uint8_t
+ libcrux_ml_kem_vector_rej_sample_table_REJECTION_SAMPLE_SHUFFLE_TABLE[256U]
+ [16U];
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_ZERO_0d(void);
+
+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);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+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);
+
+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);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+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);
+
+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);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+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);
+
+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);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+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);
+
+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);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+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);
+
+#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`.
+*/
+int16_t libcrux_ml_kem_vector_portable_arithmetic_barrett_reduce_element(
+ int16_t value);
+
+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);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+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);
+
+#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`.
+*/
+int16_t libcrux_ml_kem_vector_portable_arithmetic_montgomery_reduce_element(
+ int32_t value);
+
+/**
+ 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)`.
+*/
+int16_t libcrux_ml_kem_vector_portable_arithmetic_montgomery_multiply_fe_by_fer(
+ int16_t fe, int16_t fer);
+
+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);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+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);
+
+/**
+ 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>.
+*/
+uint8_t libcrux_ml_kem_vector_portable_compress_compress_message_coefficient(
+ uint16_t fe);
+
+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);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+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);
+
+uint32_t libcrux_ml_kem_vector_portable_arithmetic_get_n_least_significant_bits(
+ uint8_t n, uint32_t value);
+
+int16_t libcrux_ml_kem_vector_portable_compress_compress_ciphertext_coefficient(
+ uint8_t coefficient_bits, uint16_t fe);
+
+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);
+
+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);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+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);
+
+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);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+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);
+
+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);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+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);
+
+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);
+
+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);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+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);
+
+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);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+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);
+
+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);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+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);
+
+/**
+ 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>.
+*/
+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);
+
+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);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+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);
+
+void libcrux_ml_kem_vector_portable_serialize_serialize_1(
+ libcrux_ml_kem_vector_portable_vector_type_PortableVector v,
+ uint8_t ret[2U]);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+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_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_serialize_deserialize_1(Eurydice_slice v);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_deserialize_1_0d(Eurydice_slice a);
+
+typedef struct uint8_t_x4_s {
+ uint8_t fst;
+ uint8_t snd;
+ uint8_t thd;
+ uint8_t f3;
+} uint8_t_x4;
+
+uint8_t_x4 libcrux_ml_kem_vector_portable_serialize_serialize_4_int(
+ Eurydice_slice v);
+
+void libcrux_ml_kem_vector_portable_serialize_serialize_4(
+ libcrux_ml_kem_vector_portable_vector_type_PortableVector v,
+ uint8_t ret[8U]);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+void libcrux_ml_kem_vector_portable_serialize_4_0d(
+ libcrux_ml_kem_vector_portable_vector_type_PortableVector a,
+ uint8_t ret[8U]);
+
+int16_t_x8 libcrux_ml_kem_vector_portable_serialize_deserialize_4_int(
+ Eurydice_slice bytes);
+
+libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_serialize_deserialize_4(Eurydice_slice bytes);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_deserialize_4_0d(Eurydice_slice 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;
+
+uint8_t_x5 libcrux_ml_kem_vector_portable_serialize_serialize_5_int(
+ Eurydice_slice v);
+
+void libcrux_ml_kem_vector_portable_serialize_serialize_5(
+ libcrux_ml_kem_vector_portable_vector_type_PortableVector v,
+ uint8_t ret[10U]);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+void libcrux_ml_kem_vector_portable_serialize_5_0d(
+ libcrux_ml_kem_vector_portable_vector_type_PortableVector a,
+ uint8_t ret[10U]);
+
+int16_t_x8 libcrux_ml_kem_vector_portable_serialize_deserialize_5_int(
+ Eurydice_slice bytes);
+
+libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_serialize_deserialize_5(Eurydice_slice bytes);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_deserialize_5_0d(Eurydice_slice a);
+
+uint8_t_x5 libcrux_ml_kem_vector_portable_serialize_serialize_10_int(
+ Eurydice_slice v);
+
+void libcrux_ml_kem_vector_portable_serialize_serialize_10(
+ libcrux_ml_kem_vector_portable_vector_type_PortableVector v,
+ uint8_t ret[20U]);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+void libcrux_ml_kem_vector_portable_serialize_10_0d(
+ libcrux_ml_kem_vector_portable_vector_type_PortableVector a,
+ uint8_t ret[20U]);
+
+int16_t_x8 libcrux_ml_kem_vector_portable_serialize_deserialize_10_int(
+ Eurydice_slice bytes);
+
+libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_serialize_deserialize_10(Eurydice_slice bytes);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_deserialize_10_0d(Eurydice_slice a);
+
+typedef struct uint8_t_x3_s {
+ uint8_t fst;
+ uint8_t snd;
+ uint8_t thd;
+} uint8_t_x3;
+
+uint8_t_x3 libcrux_ml_kem_vector_portable_serialize_serialize_12_int(
+ Eurydice_slice v);
+
+void libcrux_ml_kem_vector_portable_serialize_serialize_12(
+ libcrux_ml_kem_vector_portable_vector_type_PortableVector v,
+ uint8_t ret[24U]);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+void libcrux_ml_kem_vector_portable_serialize_12_0d(
+ libcrux_ml_kem_vector_portable_vector_type_PortableVector a,
+ uint8_t ret[24U]);
+
+typedef struct int16_t_x2_s {
+ int16_t fst;
+ int16_t snd;
+} int16_t_x2;
+
+int16_t_x2 libcrux_ml_kem_vector_portable_serialize_deserialize_12_int(
+ Eurydice_slice bytes);
+
+libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_serialize_deserialize_12(Eurydice_slice bytes);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+libcrux_ml_kem_vector_portable_vector_type_PortableVector
+libcrux_ml_kem_vector_portable_deserialize_12_0d(Eurydice_slice a);
+
+size_t libcrux_ml_kem_vector_portable_sampling_rej_sample(
+ Eurydice_slice a, Eurydice_slice result);
+
+/**
+This function found in impl {(libcrux_ml_kem::vector::traits::Operations for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+size_t libcrux_ml_kem_vector_portable_rej_sample_0d(Eurydice_slice a,
+ Eurydice_slice out);
+
+/**
+This function found in impl {(core::clone::Clone for
+libcrux_ml_kem::vector::portable::vector_type::PortableVector)}
+*/
+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);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#define __libcrux_mlkem_portable_H_DEFINED
+#endif
diff -up ./lib/freebl/verified/libcrux_sha3.h.mlkem ./lib/freebl/verified/libcrux_sha3.h
--- ./lib/freebl/verified/libcrux_sha3.h.mlkem 2024-10-31 14:54:15.465515959 -0700
+++ ./lib/freebl/verified/libcrux_sha3.h 2024-10-31 14:54:15.465515959 -0700
@@ -0,0 +1,221 @@
+/*
+ * 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: b351338f6a84c7a1afc27433eb0ffdc668b3581d
+ * Eurydice: 7efec1624422fd5e94388ef06b9c76dfe7a48d46
+ * Karamel: c96fb69d15693284644d6aecaa90afa37e4de8f0
+ * F*: 58c915a86a2c07c8eca8d9deafd76cb7a91f0eb7
+ * Libcrux: 6ff01fb3c57ff29ecb59bc62d9dc7fd231060cfb
+ */
+
+#ifndef __libcrux_sha3_H
+#define __libcrux_sha3_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include "eurydice_glue.h"
+#include "libcrux_core.h"
+#include "libcrux_sha3_internal.h"
+
+/**
+ 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_e4(buf0, buf);
+}
+
+/**
+ 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_e40(buf0, buf);
+}
+
+/**
+ 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_e41(buf0, buf);
+}
+
+/**
+ 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_e42(buf0, buf);
+}
+
+/**
+ 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_e43(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));
+}
+
+/**
+ 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_e44(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);
+}
+
+#if defined(__cplusplus)
+}
+#endif
+
+#define __libcrux_sha3_H_DEFINED
+#endif
diff -up ./lib/freebl/verified/libcrux_sha3_internal.h.mlkem ./lib/freebl/verified/libcrux_sha3_internal.h
--- ./lib/freebl/verified/libcrux_sha3_internal.h.mlkem 2024-10-31 14:54:15.466515970 -0700
+++ ./lib/freebl/verified/libcrux_sha3_internal.h 2024-10-31 14:54:15.466515970 -0700
@@ -0,0 +1,3449 @@
+/*
+ * 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: b351338f6a84c7a1afc27433eb0ffdc668b3581d
+ * Eurydice: 7efec1624422fd5e94388ef06b9c76dfe7a48d46
+ * Karamel: c96fb69d15693284644d6aecaa90afa37e4de8f0
+ * F*: 58c915a86a2c07c8eca8d9deafd76cb7a91f0eb7
+ * Libcrux: 6ff01fb3c57ff29ecb59bc62d9dc7fd231060cfb
+ */
+
+#ifndef __libcrux_sha3_internal_H
+#define __libcrux_sha3_internal_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include "eurydice_glue.h"
+#include "libcrux_core.h"
+
+static const uint64_t libcrux_sha3_generic_keccak_ROUNDCONSTANTS[24U] = {
+ 1ULL,
+ 32898ULL,
+ 9223372036854808714ULL,
+ 9223372039002292224ULL,
+ 32907ULL,
+ 2147483649ULL,
+ 9223372039002292353ULL,
+ 9223372036854808585ULL,
+ 138ULL,
+ 136ULL,
+ 2147516425ULL,
+ 2147483658ULL,
+ 2147516555ULL,
+ 9223372036854775947ULL,
+ 9223372036854808713ULL,
+ 9223372036854808579ULL,
+ 9223372036854808578ULL,
+ 9223372036854775936ULL,
+ 32778ULL,
+ 9223372039002259466ULL,
+ 9223372039002292353ULL,
+ 9223372036854808704ULL,
+ 2147483649ULL,
+ 9223372039002292232ULL
+};
+
+/**
+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_d6(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_d6(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_cf(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= 168
+*/
+static KRML_MUSTINLINE void
+libcrux_sha3_portable_keccak_load_block_65(
+ 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];
+ core_result_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]);
+ core_result_unwrap_41_0e(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_d4(
+ 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_65(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_05(
+ 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_d4(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_d60(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_74(uint64_t a, uint64_t b)
+{
+ uint64_t ab = a ^ b;
+ return libcrux_sha3_portable_keccak_rotate_left_d60(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_03(uint64_t a, uint64_t b)
+{
+ return libcrux_sha3_portable_keccak__vxarq_u64_74(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_d61(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_740(uint64_t a, uint64_t b)
+{
+ uint64_t ab = a ^ b;
+ return libcrux_sha3_portable_keccak_rotate_left_d61(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_030(uint64_t a, uint64_t b)
+{
+ return libcrux_sha3_portable_keccak__vxarq_u64_740(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_d62(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_741(uint64_t a, uint64_t b)
+{
+ uint64_t ab = a ^ b;
+ return libcrux_sha3_portable_keccak_rotate_left_d62(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_031(uint64_t a, uint64_t b)
+{
+ return libcrux_sha3_portable_keccak__vxarq_u64_741(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_d63(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_742(uint64_t a, uint64_t b)
+{
+ uint64_t ab = a ^ b;
+ return libcrux_sha3_portable_keccak_rotate_left_d63(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_032(uint64_t a, uint64_t b)
+{
+ return libcrux_sha3_portable_keccak__vxarq_u64_742(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_743(uint64_t a, uint64_t b)
+{
+ uint64_t ab = a ^ b;
+ return libcrux_sha3_portable_keccak_rotate_left_d6(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_033(uint64_t a, uint64_t b)
+{
+ return libcrux_sha3_portable_keccak__vxarq_u64_743(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_d64(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_744(uint64_t a, uint64_t b)
+{
+ uint64_t ab = a ^ b;
+ return libcrux_sha3_portable_keccak_rotate_left_d64(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_034(uint64_t a, uint64_t b)
+{
+ return libcrux_sha3_portable_keccak__vxarq_u64_744(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_d65(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_745(uint64_t a, uint64_t b)
+{
+ uint64_t ab = a ^ b;
+ return libcrux_sha3_portable_keccak_rotate_left_d65(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_035(uint64_t a, uint64_t b)
+{
+ return libcrux_sha3_portable_keccak__vxarq_u64_745(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_d66(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_746(uint64_t a, uint64_t b)
+{
+ uint64_t ab = a ^ b;
+ return libcrux_sha3_portable_keccak_rotate_left_d66(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_036(uint64_t a, uint64_t b)
+{
+ return libcrux_sha3_portable_keccak__vxarq_u64_746(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_d67(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_747(uint64_t a, uint64_t b)
+{
+ uint64_t ab = a ^ b;
+ return libcrux_sha3_portable_keccak_rotate_left_d67(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_037(uint64_t a, uint64_t b)
+{
+ return libcrux_sha3_portable_keccak__vxarq_u64_747(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_d68(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_748(uint64_t a, uint64_t b)
+{
+ uint64_t ab = a ^ b;
+ return libcrux_sha3_portable_keccak_rotate_left_d68(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_038(uint64_t a, uint64_t b)
+{
+ return libcrux_sha3_portable_keccak__vxarq_u64_748(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_d69(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_749(uint64_t a, uint64_t b)
+{
+ uint64_t ab = a ^ b;
+ return libcrux_sha3_portable_keccak_rotate_left_d69(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_039(uint64_t a, uint64_t b)
+{
+ return libcrux_sha3_portable_keccak__vxarq_u64_749(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_d610(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_7410(uint64_t a, uint64_t b)
+{
+ uint64_t ab = a ^ b;
+ return libcrux_sha3_portable_keccak_rotate_left_d610(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_0310(uint64_t a, uint64_t b)
+{
+ return libcrux_sha3_portable_keccak__vxarq_u64_7410(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_d611(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_7411(uint64_t a, uint64_t b)
+{
+ uint64_t ab = a ^ b;
+ return libcrux_sha3_portable_keccak_rotate_left_d611(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_0311(uint64_t a, uint64_t b)
+{
+ return libcrux_sha3_portable_keccak__vxarq_u64_7411(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_d612(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_7412(uint64_t a, uint64_t b)
+{
+ uint64_t ab = a ^ b;
+ return libcrux_sha3_portable_keccak_rotate_left_d612(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_0312(uint64_t a, uint64_t b)
+{
+ return libcrux_sha3_portable_keccak__vxarq_u64_7412(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_d613(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_7413(uint64_t a, uint64_t b)
+{
+ uint64_t ab = a ^ b;
+ return libcrux_sha3_portable_keccak_rotate_left_d613(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_0313(uint64_t a, uint64_t b)
+{
+ return libcrux_sha3_portable_keccak__vxarq_u64_7413(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_d614(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_7414(uint64_t a, uint64_t b)
+{
+ uint64_t ab = a ^ b;
+ return libcrux_sha3_portable_keccak_rotate_left_d614(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_0314(uint64_t a, uint64_t b)
+{
+ return libcrux_sha3_portable_keccak__vxarq_u64_7414(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_d615(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_7415(uint64_t a, uint64_t b)
+{
+ uint64_t ab = a ^ b;
+ return libcrux_sha3_portable_keccak_rotate_left_d615(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_0315(uint64_t a, uint64_t b)
+{
+ return libcrux_sha3_portable_keccak__vxarq_u64_7415(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_d616(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_7416(uint64_t a, uint64_t b)
+{
+ uint64_t ab = a ^ b;
+ return libcrux_sha3_portable_keccak_rotate_left_d616(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_0316(uint64_t a, uint64_t b)
+{
+ return libcrux_sha3_portable_keccak__vxarq_u64_7416(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_d617(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_7417(uint64_t a, uint64_t b)
+{
+ uint64_t ab = a ^ b;
+ return libcrux_sha3_portable_keccak_rotate_left_d617(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_0317(uint64_t a, uint64_t b)
+{
+ return libcrux_sha3_portable_keccak__vxarq_u64_7417(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_d618(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_7418(uint64_t a, uint64_t b)
+{
+ uint64_t ab = a ^ b;
+ return libcrux_sha3_portable_keccak_rotate_left_d618(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_0318(uint64_t a, uint64_t b)
+{
+ return libcrux_sha3_portable_keccak__vxarq_u64_7418(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_d619(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_7419(uint64_t a, uint64_t b)
+{
+ uint64_t ab = a ^ b;
+ return libcrux_sha3_portable_keccak_rotate_left_d619(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_0319(uint64_t a, uint64_t b)
+{
+ return libcrux_sha3_portable_keccak__vxarq_u64_7419(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_d620(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_7420(uint64_t a, uint64_t b)
+{
+ uint64_t ab = a ^ b;
+ return libcrux_sha3_portable_keccak_rotate_left_d620(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_0320(uint64_t a, uint64_t b)
+{
+ return libcrux_sha3_portable_keccak__vxarq_u64_7420(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_d621(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_7421(uint64_t a, uint64_t b)
+{
+ uint64_t ab = a ^ b;
+ return libcrux_sha3_portable_keccak_rotate_left_d621(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_0321(uint64_t a, uint64_t b)
+{
+ return libcrux_sha3_portable_keccak__vxarq_u64_7421(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_d622(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_7422(uint64_t a, uint64_t b)
+{
+ uint64_t ab = a ^ b;
+ return libcrux_sha3_portable_keccak_rotate_left_d622(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_0322(uint64_t a, uint64_t b)
+{
+ return libcrux_sha3_portable_keccak__vxarq_u64_7422(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_a7(
+ 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_03(s->st[1U][0U], t[0U]);
+ s->st[2U][0U] =
+ libcrux_sha3_portable_keccak_xor_and_rotate_5a_030(s->st[2U][0U], t[0U]);
+ s->st[3U][0U] =
+ libcrux_sha3_portable_keccak_xor_and_rotate_5a_031(s->st[3U][0U], t[0U]);
+ s->st[4U][0U] =
+ libcrux_sha3_portable_keccak_xor_and_rotate_5a_032(s->st[4U][0U], t[0U]);
+ s->st[0U][1U] =
+ libcrux_sha3_portable_keccak_xor_and_rotate_5a_033(s->st[0U][1U], t[1U]);
+ s->st[1U][1U] =
+ libcrux_sha3_portable_keccak_xor_and_rotate_5a_034(s->st[1U][1U], t[1U]);
+ s->st[2U][1U] =
+ libcrux_sha3_portable_keccak_xor_and_rotate_5a_035(s->st[2U][1U], t[1U]);
+ s->st[3U][1U] =
+ libcrux_sha3_portable_keccak_xor_and_rotate_5a_036(s->st[3U][1U], t[1U]);
+ s->st[4U][1U] =
+ libcrux_sha3_portable_keccak_xor_and_rotate_5a_037(s->st[4U][1U], t[1U]);
+ s->st[0U][2U] =
+ libcrux_sha3_portable_keccak_xor_and_rotate_5a_038(s->st[0U][2U], t[2U]);
+ s->st[1U][2U] =
+ libcrux_sha3_portable_keccak_xor_and_rotate_5a_039(s->st[1U][2U], t[2U]);
+ s->st[2U][2U] =
+ libcrux_sha3_portable_keccak_xor_and_rotate_5a_0310(s->st[2U][2U], t[2U]);
+ s->st[3U][2U] =
+ libcrux_sha3_portable_keccak_xor_and_rotate_5a_0311(s->st[3U][2U], t[2U]);
+ s->st[4U][2U] =
+ libcrux_sha3_portable_keccak_xor_and_rotate_5a_0312(s->st[4U][2U], t[2U]);
+ s->st[0U][3U] =
+ libcrux_sha3_portable_keccak_xor_and_rotate_5a_0313(s->st[0U][3U], t[3U]);
+ s->st[1U][3U] =
+ libcrux_sha3_portable_keccak_xor_and_rotate_5a_0314(s->st[1U][3U], t[3U]);
+ s->st[2U][3U] =
+ libcrux_sha3_portable_keccak_xor_and_rotate_5a_0315(s->st[2U][3U], t[3U]);
+ s->st[3U][3U] =
+ libcrux_sha3_portable_keccak_xor_and_rotate_5a_0316(s->st[3U][3U], t[3U]);
+ s->st[4U][3U] =
+ libcrux_sha3_portable_keccak_xor_and_rotate_5a_0317(s->st[4U][3U], t[3U]);
+ s->st[0U][4U] =
+ libcrux_sha3_portable_keccak_xor_and_rotate_5a_0318(s->st[0U][4U], t[4U]);
+ s->st[1U][4U] =
+ libcrux_sha3_portable_keccak_xor_and_rotate_5a_0319(s->st[1U][4U], t[4U]);
+ s->st[2U][4U] =
+ libcrux_sha3_portable_keccak_xor_and_rotate_5a_0320(s->st[2U][4U], t[4U]);
+ s->st[3U][4U] =
+ libcrux_sha3_portable_keccak_xor_and_rotate_5a_0321(s->st[3U][4U], t[4U]);
+ uint64_t uu____27 =
+ libcrux_sha3_portable_keccak_xor_and_rotate_5a_0322(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_d5(
+ 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_3e(
+ libcrux_sha3_generic_keccak_KeccakState_48 *s)
+{
+ uint64_t old[5U][5U];
+ memcpy(old, s->st, (size_t)5U * sizeof(uint64_t[5U]));
+ KRML_MAYBE_FOR5(
+ i0, (size_t)0U, (size_t)5U, (size_t)1U, size_t i1 = i0; KRML_MAYBE_FOR5(
+ i, (size_t)0U, (size_t)5U, (size_t)1U, size_t j = i;
+ 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_00(
+ 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_b8(
+ 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_a7(s);
+ libcrux_sha3_generic_keccak_pi_d5(s);
+ libcrux_sha3_generic_keccak_chi_3e(s);
+ libcrux_sha3_generic_keccak_iota_00(s, i0);
+ }
+}
+
+/**
+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_40(
+ 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 } };
+ {
+ size_t i = (size_t)0U;
+ if (last_len > (size_t)0U) {
+ Eurydice_slice uu____0 =
+ Eurydice_array_to_subslice2(blocks[i], (size_t)0U, last_len, uint8_t);
+ Eurydice_slice_copy(uu____0, last[i], uint8_t);
+ }
+ blocks[i][last_len] = 31U;
+ size_t uu____1 = i;
+ 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_05(uu____3, uu____4);
+ libcrux_sha3_generic_keccak_keccakf1600_b8(s);
+}
+
+/**
+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_9b(
+ 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_49(
+ uint64_t (*a)[5U], Eurydice_slice b[1U])
+{
+ libcrux_sha3_portable_keccak_store_block_9b(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_c2(
+ libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U])
+{
+ libcrux_sha3_generic_keccak_keccakf1600_b8(s);
+ libcrux_sha3_portable_keccak_store_block_5a_49(s->st, out);
+}
+
+/**
+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_7b(
+ libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U])
+{
+ libcrux_sha3_portable_keccak_store_block_5a_49(s->st, out);
+}
+
+/**
+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_650(
+ 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];
+ core_result_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]);
+ core_result_unwrap_41_0e(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= 136
+*/
+static KRML_MUSTINLINE void
+libcrux_sha3_portable_keccak_load_block_full_d40(
+ 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_650(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_050(
+ 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_d40(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= 31
+*/
+static KRML_MUSTINLINE void
+libcrux_sha3_generic_keccak_absorb_final_400(
+ 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 } };
+ {
+ size_t i = (size_t)0U;
+ if (last_len > (size_t)0U) {
+ Eurydice_slice uu____0 =
+ Eurydice_array_to_subslice2(blocks[i], (size_t)0U, last_len, uint8_t);
+ Eurydice_slice_copy(uu____0, last[i], uint8_t);
+ }
+ blocks[i][last_len] = 31U;
+ size_t uu____1 = i;
+ 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_050(uu____3, uu____4);
+ libcrux_sha3_generic_keccak_keccakf1600_b8(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_9b0(
+ 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);
+ }
+}
+
+/**
+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_490(
+ uint64_t (*a)[5U], Eurydice_slice b[1U])
+{
+ libcrux_sha3_portable_keccak_store_block_9b0(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_7b0(
+ libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U])
+{
+ libcrux_sha3_portable_keccak_store_block_5a_490(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_c20(
+ libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U])
+{
+ libcrux_sha3_generic_keccak_keccakf1600_b8(s);
+ libcrux_sha3_portable_keccak_store_block_5a_490(s->st, out);
+}
+
+/**
+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_35(
+ 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_650(uu____0, copy_of_b);
+}
+
+/**
+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_350(
+ 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_65(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_403(
+ 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_350(uu____0, uu____1);
+ libcrux_sha3_generic_keccak_keccakf1600_b8(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_7e3(
+ 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_9b(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_273(uint64_t (*a)[5U],
+ uint8_t ret[1U][200U])
+{
+ libcrux_sha3_portable_keccak_store_block_full_7e3(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_883(
+ libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U])
+{
+ uint8_t b[1U][200U];
+ libcrux_sha3_portable_keccak_store_block_full_5a_273(s->st, b);
+ {
+ size_t i = (size_t)0U;
+ Eurydice_slice uu____0 = out[i];
+ uint8_t *uu____1 = b[i];
+ core_ops_range_Range_b3 lit;
+ lit.start = (size_t)0U;
+ lit.end = Eurydice_slice_len(out[i], 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_ca3(
+ libcrux_sha3_generic_keccak_KeccakState_48 s, Eurydice_slice out[1U])
+{
+ libcrux_sha3_generic_keccak_keccakf1600_b8(&s);
+ uint8_t b[1U][200U];
+ libcrux_sha3_portable_keccak_store_block_full_5a_273(s.st, b);
+ {
+ size_t i = (size_t)0U;
+ Eurydice_slice uu____0 = out[i];
+ uint8_t *uu____1 = b[i];
+ core_ops_range_Range_b3 lit;
+ lit.start = (size_t)0U;
+ lit.end = Eurydice_slice_len(out[i], 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_064(
+ Eurydice_slice data[1U], Eurydice_slice out[1U])
+{
+ libcrux_sha3_generic_keccak_KeccakState_48 s =
+ libcrux_sha3_generic_keccak_new_1e_cf();
+ 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_403(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_40(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_883(&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_7b(&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, core_option_Option_b3)
+ .tag == core_option_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_c2(&s, o);
+ memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice));
+ }
+ }
+ if (last < outlen) {
+ libcrux_sha3_generic_keccak_squeeze_last_ca3(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_e44(
+ 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_064(copy_of_data, out);
+}
+
+/**
+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_653(
+ 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];
+ core_result_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]);
+ core_result_unwrap_41_0e(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_353(
+ 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_653(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_402(
+ 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_353(uu____0, uu____1);
+ libcrux_sha3_generic_keccak_keccakf1600_b8(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_d43(
+ 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_653(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_053(
+ 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_d43(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_404(
+ 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 } };
+ {
+ size_t i = (size_t)0U;
+ if (last_len > (size_t)0U) {
+ Eurydice_slice uu____0 =
+ Eurydice_array_to_subslice2(blocks[i], (size_t)0U, last_len, uint8_t);
+ Eurydice_slice_copy(uu____0, last[i], uint8_t);
+ }
+ blocks[i][last_len] = 6U;
+ size_t uu____1 = i;
+ 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_053(uu____3, uu____4);
+ libcrux_sha3_generic_keccak_keccakf1600_b8(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_9b3(
+ 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_7e2(
+ 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_9b3(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_272(uint64_t (*a)[5U],
+ uint8_t ret[1U][200U])
+{
+ libcrux_sha3_portable_keccak_store_block_full_7e2(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_882(
+ libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U])
+{
+ uint8_t b[1U][200U];
+ libcrux_sha3_portable_keccak_store_block_full_5a_272(s->st, b);
+ {
+ size_t i = (size_t)0U;
+ Eurydice_slice uu____0 = out[i];
+ uint8_t *uu____1 = b[i];
+ core_ops_range_Range_b3 lit;
+ lit.start = (size_t)0U;
+ lit.end = Eurydice_slice_len(out[i], 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_493(
+ uint64_t (*a)[5U], Eurydice_slice b[1U])
+{
+ libcrux_sha3_portable_keccak_store_block_9b3(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_7b3(
+ libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U])
+{
+ libcrux_sha3_portable_keccak_store_block_5a_493(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_c23(
+ libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U])
+{
+ libcrux_sha3_generic_keccak_keccakf1600_b8(s);
+ libcrux_sha3_portable_keccak_store_block_5a_493(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_ca2(
+ libcrux_sha3_generic_keccak_KeccakState_48 s, Eurydice_slice out[1U])
+{
+ libcrux_sha3_generic_keccak_keccakf1600_b8(&s);
+ uint8_t b[1U][200U];
+ libcrux_sha3_portable_keccak_store_block_full_5a_272(s.st, b);
+ {
+ size_t i = (size_t)0U;
+ Eurydice_slice uu____0 = out[i];
+ uint8_t *uu____1 = b[i];
+ core_ops_range_Range_b3 lit;
+ lit.start = (size_t)0U;
+ lit.end = Eurydice_slice_len(out[i], 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_063(
+ Eurydice_slice data[1U], Eurydice_slice out[1U])
+{
+ libcrux_sha3_generic_keccak_KeccakState_48 s =
+ libcrux_sha3_generic_keccak_new_1e_cf();
+ 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_402(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_404(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_882(&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_7b3(&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, core_option_Option_b3)
+ .tag == core_option_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_c23(&s, o);
+ memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice));
+ }
+ }
+ if (last < outlen) {
+ libcrux_sha3_generic_keccak_squeeze_last_ca2(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_e43(
+ 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_063(copy_of_data, out);
+}
+
+/**
+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_652(
+ 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];
+ core_result_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]);
+ core_result_unwrap_41_0e(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_352(
+ 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_652(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_401(
+ 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_352(uu____0, uu____1);
+ libcrux_sha3_generic_keccak_keccakf1600_b8(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_d42(
+ 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_652(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_052(
+ 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_d42(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_403(
+ 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 } };
+ {
+ size_t i = (size_t)0U;
+ if (last_len > (size_t)0U) {
+ Eurydice_slice uu____0 =
+ Eurydice_array_to_subslice2(blocks[i], (size_t)0U, last_len, uint8_t);
+ Eurydice_slice_copy(uu____0, last[i], uint8_t);
+ }
+ blocks[i][last_len] = 6U;
+ size_t uu____1 = i;
+ 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_052(uu____3, uu____4);
+ libcrux_sha3_generic_keccak_keccakf1600_b8(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_9b2(
+ 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_7e1(
+ 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_9b2(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_271(uint64_t (*a)[5U],
+ uint8_t ret[1U][200U])
+{
+ libcrux_sha3_portable_keccak_store_block_full_7e1(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_881(
+ libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U])
+{
+ uint8_t b[1U][200U];
+ libcrux_sha3_portable_keccak_store_block_full_5a_271(s->st, b);
+ {
+ size_t i = (size_t)0U;
+ Eurydice_slice uu____0 = out[i];
+ uint8_t *uu____1 = b[i];
+ core_ops_range_Range_b3 lit;
+ lit.start = (size_t)0U;
+ lit.end = Eurydice_slice_len(out[i], 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_492(
+ uint64_t (*a)[5U], Eurydice_slice b[1U])
+{
+ libcrux_sha3_portable_keccak_store_block_9b2(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_7b2(
+ libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U])
+{
+ libcrux_sha3_portable_keccak_store_block_5a_492(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_c22(
+ libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U])
+{
+ libcrux_sha3_generic_keccak_keccakf1600_b8(s);
+ libcrux_sha3_portable_keccak_store_block_5a_492(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_ca1(
+ libcrux_sha3_generic_keccak_KeccakState_48 s, Eurydice_slice out[1U])
+{
+ libcrux_sha3_generic_keccak_keccakf1600_b8(&s);
+ uint8_t b[1U][200U];
+ libcrux_sha3_portable_keccak_store_block_full_5a_271(s.st, b);
+ {
+ size_t i = (size_t)0U;
+ Eurydice_slice uu____0 = out[i];
+ uint8_t *uu____1 = b[i];
+ core_ops_range_Range_b3 lit;
+ lit.start = (size_t)0U;
+ lit.end = Eurydice_slice_len(out[i], 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_062(
+ Eurydice_slice data[1U], Eurydice_slice out[1U])
+{
+ libcrux_sha3_generic_keccak_KeccakState_48 s =
+ libcrux_sha3_generic_keccak_new_1e_cf();
+ 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_401(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_403(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_881(&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_7b2(&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, core_option_Option_b3)
+ .tag == core_option_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_c22(&s, o);
+ memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice));
+ }
+ }
+ if (last < outlen) {
+ libcrux_sha3_generic_keccak_squeeze_last_ca1(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_e42(
+ 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_062(copy_of_data, out);
+}
+
+/**
+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_400(
+ 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_35(uu____0, uu____1);
+ libcrux_sha3_generic_keccak_keccakf1600_b8(s);
+}
+
+/**
+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_7e0(
+ 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_9b0(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_270(uint64_t (*a)[5U],
+ uint8_t ret[1U][200U])
+{
+ libcrux_sha3_portable_keccak_store_block_full_7e0(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_880(
+ libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U])
+{
+ uint8_t b[1U][200U];
+ libcrux_sha3_portable_keccak_store_block_full_5a_270(s->st, b);
+ {
+ size_t i = (size_t)0U;
+ Eurydice_slice uu____0 = out[i];
+ uint8_t *uu____1 = b[i];
+ core_ops_range_Range_b3 lit;
+ lit.start = (size_t)0U;
+ lit.end = Eurydice_slice_len(out[i], 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= 136
+*/
+static KRML_MUSTINLINE void
+libcrux_sha3_generic_keccak_squeeze_last_ca0(
+ libcrux_sha3_generic_keccak_KeccakState_48 s, Eurydice_slice out[1U])
+{
+ libcrux_sha3_generic_keccak_keccakf1600_b8(&s);
+ uint8_t b[1U][200U];
+ libcrux_sha3_portable_keccak_store_block_full_5a_270(s.st, b);
+ {
+ size_t i = (size_t)0U;
+ Eurydice_slice uu____0 = out[i];
+ uint8_t *uu____1 = b[i];
+ core_ops_range_Range_b3 lit;
+ lit.start = (size_t)0U;
+ lit.end = Eurydice_slice_len(out[i], 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= 31
+*/
+static KRML_MUSTINLINE void
+libcrux_sha3_generic_keccak_keccak_061(
+ Eurydice_slice data[1U], Eurydice_slice out[1U])
+{
+ libcrux_sha3_generic_keccak_KeccakState_48 s =
+ libcrux_sha3_generic_keccak_new_1e_cf();
+ 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_400(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_400(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_880(&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_7b0(&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, core_option_Option_b3)
+ .tag == core_option_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_c20(&s, o);
+ memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice));
+ }
+ }
+ if (last < outlen) {
+ libcrux_sha3_generic_keccak_squeeze_last_ca0(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_e41(
+ 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_061(copy_of_data, out);
+}
+
+/**
+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_402(
+ 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 } };
+ {
+ size_t i = (size_t)0U;
+ if (last_len > (size_t)0U) {
+ Eurydice_slice uu____0 =
+ Eurydice_array_to_subslice2(blocks[i], (size_t)0U, last_len, uint8_t);
+ Eurydice_slice_copy(uu____0, last[i], uint8_t);
+ }
+ blocks[i][last_len] = 6U;
+ size_t uu____1 = i;
+ 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_050(uu____3, uu____4);
+ libcrux_sha3_generic_keccak_keccakf1600_b8(s);
+}
+
+/**
+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_060(
+ Eurydice_slice data[1U], Eurydice_slice out[1U])
+{
+ libcrux_sha3_generic_keccak_KeccakState_48 s =
+ libcrux_sha3_generic_keccak_new_1e_cf();
+ 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_400(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_402(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_880(&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_7b0(&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, core_option_Option_b3)
+ .tag == core_option_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_c20(&s, o);
+ memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice));
+ }
+ }
+ if (last < outlen) {
+ libcrux_sha3_generic_keccak_squeeze_last_ca0(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_e40(
+ 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_060(copy_of_data, out);
+}
+
+/**
+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_651(
+ 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];
+ core_result_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]);
+ core_result_unwrap_41_0e(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_351(
+ 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_651(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= 72
+*/
+static KRML_MUSTINLINE void
+libcrux_sha3_generic_keccak_absorb_block_40(
+ 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_351(uu____0, uu____1);
+ libcrux_sha3_generic_keccak_keccakf1600_b8(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_d41(
+ 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_651(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_051(
+ 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_d41(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_401(
+ 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 } };
+ {
+ size_t i = (size_t)0U;
+ if (last_len > (size_t)0U) {
+ Eurydice_slice uu____0 =
+ Eurydice_array_to_subslice2(blocks[i], (size_t)0U, last_len, uint8_t);
+ Eurydice_slice_copy(uu____0, last[i], uint8_t);
+ }
+ blocks[i][last_len] = 6U;
+ size_t uu____1 = i;
+ 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_051(uu____3, uu____4);
+ libcrux_sha3_generic_keccak_keccakf1600_b8(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_9b1(
+ 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_7e(
+ 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_9b1(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_27(
+ uint64_t (*a)[5U], uint8_t ret[1U][200U])
+{
+ libcrux_sha3_portable_keccak_store_block_full_7e(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_88(
+ libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U])
+{
+ uint8_t b[1U][200U];
+ libcrux_sha3_portable_keccak_store_block_full_5a_27(s->st, b);
+ {
+ size_t i = (size_t)0U;
+ Eurydice_slice uu____0 = out[i];
+ uint8_t *uu____1 = b[i];
+ core_ops_range_Range_b3 lit;
+ lit.start = (size_t)0U;
+ lit.end = Eurydice_slice_len(out[i], 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_491(
+ uint64_t (*a)[5U], Eurydice_slice b[1U])
+{
+ libcrux_sha3_portable_keccak_store_block_9b1(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_7b1(
+ libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U])
+{
+ libcrux_sha3_portable_keccak_store_block_5a_491(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_c21(
+ libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U])
+{
+ libcrux_sha3_generic_keccak_keccakf1600_b8(s);
+ libcrux_sha3_portable_keccak_store_block_5a_491(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_ca(
+ libcrux_sha3_generic_keccak_KeccakState_48 s, Eurydice_slice out[1U])
+{
+ libcrux_sha3_generic_keccak_keccakf1600_b8(&s);
+ uint8_t b[1U][200U];
+ libcrux_sha3_portable_keccak_store_block_full_5a_27(s.st, b);
+ {
+ size_t i = (size_t)0U;
+ Eurydice_slice uu____0 = out[i];
+ uint8_t *uu____1 = b[i];
+ core_ops_range_Range_b3 lit;
+ lit.start = (size_t)0U;
+ lit.end = Eurydice_slice_len(out[i], 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_06(
+ Eurydice_slice data[1U], Eurydice_slice out[1U])
+{
+ libcrux_sha3_generic_keccak_KeccakState_48 s =
+ libcrux_sha3_generic_keccak_new_1e_cf();
+ 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_40(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_401(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_88(&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_7b1(&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, core_option_Option_b3)
+ .tag == core_option_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_c21(&s, o);
+ memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice));
+ }
+ }
+ if (last < outlen) {
+ libcrux_sha3_generic_keccak_squeeze_last_ca(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_e4(
+ 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_06(copy_of_data, out);
+}
+
+#if defined(__cplusplus)
+}
+#endif
+
+#define __libcrux_sha3_internal_H_DEFINED
+#endif
diff -up ./lib/pk11wrap/pk11akey.c.mlkem ./lib/pk11wrap/pk11akey.c
--- ./lib/pk11wrap/pk11akey.c.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./lib/pk11wrap/pk11akey.c 2024-10-31 14:54:15.466515970 -0700
@@ -235,12 +235,17 @@ PK11_ImportPublicKey(PK11SlotInfo *slot,
}
break;
case kyberKey:
- keyType = CKK_NSS_KYBER;
switch (pubKey->u.kyber.params) {
case params_kyber768_round3:
case params_kyber768_round3_test_mode:
+ keyType = CKK_NSS_KYBER;
kemParams = CKP_NSS_KYBER_768_ROUND3;
break;
+ case params_ml_kem768:
+ case params_ml_kem768_test_mode:
+ keyType = CKK_NSS_ML_KEM;
+ kemParams = CKP_NSS_ML_KEM_768;
+ break;
default:
kemParams = CKP_INVALID_ID;
break;
@@ -661,6 +666,7 @@ PK11_ExtractPublicKey(PK11SlotInfo *slot
keyType = edKey;
break;
case CKK_NSS_KYBER:
+ case CKK_NSS_ML_KEM:
keyType = kyberKey;
break;
default:
@@ -832,7 +838,12 @@ PK11_ExtractPublicKey(PK11SlotInfo *slot
if (crv != CKR_OK)
break;
- if ((keyClass != CKO_PUBLIC_KEY) || (pk11KeyType != CKK_NSS_KYBER)) {
+ if (keyClass != CKO_PUBLIC_KEY) {
+ crv = CKR_OBJECT_HANDLE_INVALID;
+ break;
+ }
+
+ if (pk11KeyType != CKK_NSS_KYBER && pk11KeyType != CKK_NSS_ML_KEM) {
crv = CKR_OBJECT_HANDLE_INVALID;
break;
}
@@ -846,6 +857,9 @@ PK11_ExtractPublicKey(PK11SlotInfo *slot
case CKP_NSS_KYBER_768_ROUND3:
pubKey->u.kyber.params = params_kyber768_round3;
break;
+ case CKP_NSS_ML_KEM_768:
+ pubKey->u.kyber.params = params_ml_kem768;
+ break;
default:
pubKey->u.kyber.params = params_kyber_invalid;
break;
@@ -909,6 +923,7 @@ PK11_MakePrivKey(PK11SlotInfo *slot, Key
keyType = edKey;
break;
case CKK_NSS_KYBER:
+ case CKK_NSS_ML_KEM:
keyType = kyberKey;
break;
default:
@@ -1525,6 +1540,17 @@ PK11_GenerateKeyPairWithOpFlags(PK11Slot
keyType = kyberKey;
test_mech.mechanism = CKM_NSS_KYBER;
break;
+ case CKM_NSS_ML_KEM_KEY_PAIR_GEN:
+ kemParams = (CK_NSS_KEM_PARAMETER_SET_TYPE *)param;
+ attrs = kyberPubTemplate;
+ PK11_SETATTRS(attrs, CKA_NSS_PARAMETER_SET,
+ kemParams,
+ sizeof(CK_NSS_KEM_PARAMETER_SET_TYPE));
+ attrs++;
+ pubTemplate = kyberPubTemplate;
+ keyType = kyberKey;
+ test_mech.mechanism = CKM_NSS_ML_KEM;
+ break;
case CKM_EC_EDWARDS_KEY_PAIR_GEN:
ecParams = (SECKEYECParams *)param;
attrs = ecPubTemplate;
diff -up ./lib/pk11wrap/pk11mech.c.mlkem ./lib/pk11wrap/pk11mech.c
--- ./lib/pk11wrap/pk11mech.c.mlkem 2024-10-31 14:54:15.446515747 -0700
+++ ./lib/pk11wrap/pk11mech.c 2024-10-31 14:54:15.466515970 -0700
@@ -431,6 +431,8 @@ PK11_GetKeyType(CK_MECHANISM_TYPE type,
return CKK_GENERIC_SECRET;
case CKM_NSS_KYBER_KEY_PAIR_GEN:
return CKK_NSS_KYBER;
+ case CKM_NSS_ML_KEM_KEY_PAIR_GEN:
+ return CKK_NSS_ML_KEM;
default:
return pk11_lookup(type)->keyType;
}
diff -up ./lib/pk11wrap/pk11pars.c.mlkem ./lib/pk11wrap/pk11pars.c
--- ./lib/pk11wrap/pk11pars.c.mlkem 2024-10-31 14:54:15.438515658 -0700
+++ ./lib/pk11wrap/pk11pars.c 2024-10-31 14:54:15.466515970 -0700
@@ -247,6 +247,10 @@ static const oidValDef curveOptList[] =
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
{ CIPHER_NAME("XYBER768D00"), SEC_OID_XYBER768D00,
NSS_USE_ALG_IN_SSL_KX },
+ { CIPHER_NAME("MLKEM768X25519"), SEC_OID_MLKEM768X25519,
+ NSS_USE_ALG_IN_SSL_KX },
+ { CIPHER_NAME("MLKEM768SECP256R1"), SEC_OID_MLKEM768SECP256R1,
+ NSS_USE_ALG_IN_SSL_KX },
/* ANSI X9.62 named elliptic curves (characteristic two field) */
{ CIPHER_NAME("C2PNB163V1"), SEC_OID_ANSIX962_EC_C2PNB163V1,
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
diff -up ./lib/pk11wrap/pk11skey.c.mlkem ./lib/pk11wrap/pk11skey.c
--- ./lib/pk11wrap/pk11skey.c.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./lib/pk11wrap/pk11skey.c 2024-10-31 14:54:15.466515970 -0700
@@ -3083,6 +3083,8 @@ pk11_KyberCiphertextLength(SECKEYKyberPu
switch (pubKey->params) {
case params_kyber768_round3:
case params_kyber768_round3_test_mode:
+ case params_ml_kem768:
+ case params_ml_kem768_test_mode:
return KYBER768_CIPHERTEXT_BYTES;
default:
// unreachable
@@ -3135,16 +3137,18 @@ PK11_Encapsulate(SECKEYPublicKey *pubKey
*outCiphertext = NULL;
CK_MECHANISM_TYPE kemType;
- switch (pubKey->keyType) {
- case kyberKey:
+ CK_NSS_KEM_PARAMETER_SET_TYPE kemParameterSet = PK11_ReadULongAttribute(slot, pubKey->pkcs11ID, CKA_NSS_PARAMETER_SET);
+ switch (kemParameterSet) {
+ case CKP_NSS_KYBER_768_ROUND3:
kemType = CKM_NSS_KYBER;
break;
+ case CKP_NSS_ML_KEM_768:
+ kemType = CKM_NSS_ML_KEM;
+ break;
default:
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ PORT_SetError(SEC_ERROR_INVALID_KEY);
return SECFailure;
}
-
- CK_NSS_KEM_PARAMETER_SET_TYPE kemParameterSet = PK11_ReadULongAttribute(slot, pubKey->pkcs11ID, CKA_NSS_PARAMETER_SET);
CK_MECHANISM mech = { kemType, &kemParameterSet, sizeof(kemParameterSet) };
sharedSecret = pk11_CreateSymKey(slot, target, PR_TRUE, PR_TRUE, NULL);
@@ -3238,16 +3242,18 @@ PK11_Decapsulate(SECKEYPrivateKey *privK
*outKey = NULL;
CK_MECHANISM_TYPE kemType;
- switch (privKey->keyType) {
- case kyberKey:
+ CK_NSS_KEM_PARAMETER_SET_TYPE kemParameterSet = PK11_ReadULongAttribute(slot, privKey->pkcs11ID, CKA_NSS_PARAMETER_SET);
+ switch (kemParameterSet) {
+ case CKP_NSS_KYBER_768_ROUND3:
kemType = CKM_NSS_KYBER;
break;
+ case CKP_NSS_ML_KEM_768:
+ kemType = CKM_NSS_ML_KEM;
+ break;
default:
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ PORT_SetError(SEC_ERROR_INVALID_KEY);
return SECFailure;
}
-
- CK_NSS_KEM_PARAMETER_SET_TYPE kemParameterSet = PK11_ReadULongAttribute(slot, privKey->pkcs11ID, CKA_NSS_PARAMETER_SET);
CK_MECHANISM mech = { kemType, &kemParameterSet, sizeof(kemParameterSet) };
sharedSecret = pk11_CreateSymKey(slot, target, PR_TRUE, PR_TRUE, NULL);
diff -up ./lib/pk11wrap/secmodti.h.mlkem ./lib/pk11wrap/secmodti.h
--- ./lib/pk11wrap/secmodti.h.mlkem 2024-10-31 14:54:15.427515535 -0700
+++ ./lib/pk11wrap/secmodti.h 2024-10-31 14:54:15.466515970 -0700
@@ -207,5 +207,6 @@ struct PK11GenericObjectStr {
* header file that only NSS sees. Currently it's only available through
* the policy code */
#define SEC_OID_TLS_REQUIRE_EMS SEC_OID_PRIVATE_1
+#define SEC_OID_MLKEM768SECP256R1 SEC_OID_PRIVATE_2
#endif /* _SECMODTI_H_ */
diff -up ./lib/softoken/fipsaudt.c.mlkem ./lib/softoken/fipsaudt.c
--- ./lib/softoken/fipsaudt.c.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./lib/softoken/fipsaudt.c 2024-10-31 14:54:15.466515970 -0700
@@ -319,3 +319,51 @@ sftk_AuditDigestKey(CK_SESSION_HANDLE hS
(PRUint32)hSession, (PRUint32)hKey, (PRUint32)rv);
sftk_LogAuditMessage(severity, NSS_AUDIT_DIGEST_KEY, msg);
}
+
+void
+sftk_AuditEncapsulate(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hPublicKey,
+ CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
+ CK_OBJECT_HANDLE_PTR phKey, CK_BYTE_PTR pCiphertext,
+ CK_ULONG_PTR pulCiphertextLen, CK_RV rv)
+{
+ char msg[256];
+ char mech[MECHANISM_BUFSIZE];
+ char shKey[32];
+ NSSAuditSeverity severity = (rv == CKR_OK) ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
+
+ sftk_PrintMechanism(mech, sizeof mech, pMechanism);
+ sftk_PrintReturnedObjectHandle(shKey, sizeof shKey, "phKey", phKey, rv);
+ PR_snprintf(msg, sizeof msg,
+ "C_Encapsulate(hSession=0x%08lX, pMechanism=%s, "
+ "hPublicKey=0x%08lX, pTemplate=%p, ulAttributeCount=%lu, "
+ "phKey=%p pCipherText=%p, pulCiphertextLen=%p)=0x%08lX%s",
+ (PRUint32)hSession, mech,
+ (PRUint32)hPublicKey, pTemplate, (PRUint32)ulAttributeCount,
+ phKey, pCiphertext, pulCiphertextLen, (PRUint32)rv, shKey);
+ sftk_LogAuditMessage(severity, NSS_AUDIT_ENCAPSULATE_KEY, msg);
+}
+
+void
+sftk_AuditDecapsulate(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hPrivateKey,
+ CK_BYTE_PTR pCiphertext, CK_ULONG ulCiphertextLen,
+ CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
+ CK_OBJECT_HANDLE_PTR phKey, CK_RV rv)
+{
+ char msg[256];
+ char mech[MECHANISM_BUFSIZE];
+ char shKey[32];
+ NSSAuditSeverity severity = (rv == CKR_OK) ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
+
+ sftk_PrintMechanism(mech, sizeof mech, pMechanism);
+ sftk_PrintReturnedObjectHandle(shKey, sizeof shKey, "phKey", phKey, rv);
+ PR_snprintf(msg, sizeof msg,
+ "C_Decapsulate(hSession=0x%08lX, pMechanism=%s, "
+ "hPrivateKey=0x%08lX, pCipherText=%p, ulCiphertextLen=%lu,",
+ "pTemplate=%p, ulAttributeCount=%lu, phKey=%p)=0x%08lX%s",
+ (PRUint32)hSession, mech,
+ (PRUint32)hPrivateKey, pCiphertext, (PRUint32)ulCiphertextLen,
+ pTemplate, (PRUint32)ulAttributeCount, phKey, (PRUint32)rv, shKey);
+ sftk_LogAuditMessage(severity, NSS_AUDIT_DECAPSULATE_KEY, msg);
+}
diff -up ./lib/softoken/fipstokn.c.mlkem ./lib/softoken/fipstokn.c
--- ./lib/softoken/fipstokn.c.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./lib/softoken/fipstokn.c 2024-10-31 14:54:15.467515982 -0700
@@ -24,6 +24,7 @@
#include "pkcs11i.h"
#include "prenv.h"
#include "prprf.h"
+#include "kem.h"
#include <ctype.h>
@@ -261,6 +262,30 @@ static CK_FUNCTION_LIST_3_0 sftk_fipsTab
};
+CK_RV FC_Encapsulate(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hPublicKey,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_OBJECT_HANDLE_PTR phKey,
+ CK_BYTE_PTR pCiphertext,
+ CK_ULONG_PTR pulCiphertextLen);
+
+CK_RV FC_Decapsulate(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hPrivateKey,
+ CK_BYTE_PTR pCiphertext,
+ CK_ULONG ulCiphertextLen,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_OBJECT_HANDLE_PTR phKey);
+
+CK_NSS_KEM_FUNCTIONS sftk_fips_kem_funcList = {
+ { 1, 0 },
+ FC_Encapsulate,
+ FC_Decapsulate
+};
+
/* forward declaration of special GetInfo functions */
CK_RV FC_GetInfoV2(CK_INFO_PTR pInfo);
CK_RV NSC_GetInfoV2(CK_INFO_PTR pInfo);
@@ -302,10 +327,11 @@ static CK_INTERFACE fips_interfaces[] =
{ (CK_UTF8CHAR_PTR) "PKCS 11", &sftk_fipsTable, NSS_INTERFACE_FLAGS },
{ (CK_UTF8CHAR_PTR) "PKCS 11", &sftk_fipsTable_v2, NSS_INTERFACE_FLAGS },
{ (CK_UTF8CHAR_PTR) "Vendor NSS Module Interface", &sftk_module_funcList, NSS_INTERFACE_FLAGS },
- { (CK_UTF8CHAR_PTR) "Vendor NSS FIPS Interface", &sftk_fips_funcList, NSS_INTERFACE_FLAGS }
+ { (CK_UTF8CHAR_PTR) "Vendor NSS FIPS Interface", &sftk_fips_funcList, NSS_INTERFACE_FLAGS },
+ { (CK_UTF8CHAR_PTR) "Vendor NSS KEM Interface", &sftk_fips_kem_funcList, NSS_INTERFACE_FLAGS }
};
/* must match the count of interfaces in fips_interfaces above*/
-#define FIPS_INTERFACE_COUNT 4
+#define FIPS_INTERFACE_COUNT 5
/* CKO_NOT_A_KEY can be any object class that's not a key object. */
#define CKO_NOT_A_KEY CKO_DATA
@@ -350,6 +376,8 @@ sftk_mapLinuxAuditType(NSSAuditSeverity
case NSS_AUDIT_LOAD_KEY:
case NSS_AUDIT_UNWRAP_KEY:
case NSS_AUDIT_WRAP_KEY:
+ case NSS_AUDIT_ENCAPSULATE_KEY:
+ case NSS_AUDIT_DECAPSULATE_KEY:
return AUDIT_CRYPTO_KEY_USER;
case NSS_AUDIT_CRYPT:
return (severity == NSS_AUDIT_ERROR) ? AUDIT_CRYPTO_FAILURE_USER : AUDIT_CRYPTO_KEY_USER;
@@ -2078,3 +2106,75 @@ FC_MessageVerifyFinal(CK_SESSION_HANDLE
CHECK_FORK();
return NSC_MessageVerifyFinal(hSession);
}
+
+/*
+ * vendor specific encapsulate/decapsulate
+ */
+CK_RV
+FC_Encapsulate(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hPublicKey,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_OBJECT_HANDLE_PTR phKey,
+ CK_BYTE_PTR pCiphertext,
+ CK_ULONG_PTR pulCiphertextLen)
+{
+ CK_BBOOL *boolptr;
+ SFTK_FIPSCHECK();
+ CHECK_FORK();
+
+ /* all secret keys must be sensitive, if the upper level code tries to say
+ * otherwise, reject it. */
+ boolptr = (CK_BBOOL *)fc_getAttribute(pTemplate,
+ ulAttributeCount, CKA_SENSITIVE);
+ if (boolptr != NULL) {
+ if (!(*boolptr)) {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+ }
+
+ rv = NSC_Encapsulate(hSession, pMechanism, hPublicKey, pTemplate,
+ ulAttributeCount, phKey, pCiphertext,
+ pulCiphertextLen);
+ if (sftk_audit_enabled) {
+ sftk_AuditEncapsulate(hSession, pMechanism, hPublicKey, pTemplate,
+ ulAttributeCount, phKey, pCiphertext,
+ pulCiphertextLen, rv);
+ }
+ return rv;
+}
+
+CK_RV
+FC_Decapsulate(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hPrivateKey,
+ CK_BYTE_PTR pCiphertext,
+ CK_ULONG ulCiphertextLen,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_OBJECT_HANDLE_PTR phKey)
+{
+ CK_BBOOL *boolptr;
+ SFTK_FIPSCHECK();
+ CHECK_FORK();
+
+ /* all secret keys must be sensitive, if the upper level code tries to say
+ * otherwise, reject it. */
+ boolptr = (CK_BBOOL *)fc_getAttribute(pTemplate,
+ ulAttributeCount, CKA_SENSITIVE);
+ if (boolptr != NULL) {
+ if (!(*boolptr)) {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+ }
+
+ rv = NSC_Decapsulate(hSession, pMechanism, hPrivateKey, pCiphertext,
+ ulCiphertextLen, pTemplate, ulAttributeCount, phKey);
+ if (sftk_audit_enabled) {
+ sftk_AuditDecapsulate(hSession, pMechanism, hPrivateKey, pCiphertext,
+ ulCiphertextLen, pTemplate, ulAttributeCount,
+ phKey, rv);
+ }
+ return rv;
+}
diff -up ./lib/softoken/kem.c.mlkem ./lib/softoken/kem.c
--- ./lib/softoken/kem.c.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./lib/softoken/kem.c 2024-10-31 14:54:15.467515982 -0700
@@ -6,6 +6,7 @@
#include "kem.h"
#include "pkcs11i.h"
#include "pkcs11n.h"
+#include "secerr.h"
#include "secitem.h"
#include "secport.h"
#include "softoken.h"
@@ -14,8 +15,8 @@ KyberParams
sftk_kyber_PK11ParamToInternal(CK_NSS_KEM_PARAMETER_SET_TYPE pk11ParamSet)
{
switch (pk11ParamSet) {
- case CKP_NSS_KYBER_768_ROUND3:
- return params_kyber768_round3;
+ case CKP_NSS_ML_KEM_768:
+ return params_ml_kem768;
default:
return params_kyber_invalid;
}
@@ -27,6 +28,8 @@ sftk_kyber_AllocPubKeyItem(KyberParams p
switch (params) {
case params_kyber768_round3:
case params_kyber768_round3_test_mode:
+ case params_ml_kem768:
+ case params_ml_kem768_test_mode:
return SECITEM_AllocItem(NULL, pubkey, KYBER768_PUBLIC_KEY_BYTES);
default:
return NULL;
@@ -39,6 +42,8 @@ sftk_kyber_AllocPrivKeyItem(KyberParams
switch (params) {
case params_kyber768_round3:
case params_kyber768_round3_test_mode:
+ case params_ml_kem768:
+ case params_ml_kem768_test_mode:
return SECITEM_AllocItem(NULL, privkey, KYBER768_PRIVATE_KEY_BYTES);
default:
return NULL;
@@ -51,6 +56,8 @@ sftk_kyber_AllocCiphertextItem(KyberPara
switch (params) {
case params_kyber768_round3:
case params_kyber768_round3_test_mode:
+ case params_ml_kem768:
+ case params_ml_kem768_test_mode:
return SECITEM_AllocItem(NULL, ciphertext, KYBER768_CIPHERTEXT_BYTES);
default:
return NULL;
@@ -64,7 +71,7 @@ sftk_kyber_ValidateParams(const CK_NSS_K
return PR_FALSE;
}
switch (*params) {
- case CKP_NSS_KYBER_768_ROUND3:
+ case CKP_NSS_ML_KEM_768:
return PR_TRUE;
default:
return PR_FALSE;
@@ -78,7 +85,7 @@ sftk_kem_ValidateMechanism(CK_MECHANISM_
return PR_FALSE;
}
switch (pMechanism->mechanism) {
- case CKM_NSS_KYBER:
+ case CKM_NSS_ML_KEM:
return pMechanism->ulParameterLen == sizeof(CK_NSS_KEM_PARAMETER_SET_TYPE) && sftk_kyber_ValidateParams(pMechanism->pParameter);
default:
return PR_FALSE;
@@ -88,14 +95,17 @@ sftk_kem_ValidateMechanism(CK_MECHANISM_
static CK_ULONG
sftk_kem_CiphertextLen(CK_MECHANISM_PTR pMechanism)
{
- /* Assumes pMechanism has been validated with sftk_kem_ValidateMechanism */
- if (pMechanism->mechanism != CKM_NSS_KYBER) {
+#ifdef DEBUG
+ if (!sftk_kem_ValidateMechanism(pMechanism)) {
PORT_Assert(0);
return 0;
}
+#endif
+
+ /* Assumes pMechanism has been validated with sftk_kem_ValidateMechanism */
CK_NSS_KEM_PARAMETER_SET_TYPE *pParameterSet = pMechanism->pParameter;
switch (*pParameterSet) {
- case CKP_NSS_KYBER_768_ROUND3:
+ case CKP_NSS_ML_KEM_768:
return KYBER768_CIPHERTEXT_BYTES;
default:
/* unreachable if pMechanism has been validated */
@@ -185,14 +195,17 @@ NSC_Encapsulate(CK_SESSION_HANDLE hSessi
uint8_t secretBuf[KYBER_SHARED_SECRET_BYTES] = { 0 };
SECItem secret = { siBuffer, secretBuf, sizeof secretBuf };
+ key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_NSS_ENCAPSULATE, key, 0);
+ key->source = SFTK_SOURCE_KEM;
+
switch (pMechanism->mechanism) {
- case CKM_NSS_KYBER: {
+ case CKM_NSS_ML_KEM:
PORT_Assert(secret.len == KYBER_SHARED_SECRET_BYTES);
CK_NSS_KEM_PARAMETER_SET_TYPE *pParameter = pMechanism->pParameter;
KyberParams kyberParams = sftk_kyber_PK11ParamToInternal(*pParameter);
SECStatus rv = Kyber_Encapsulate(kyberParams, /* seed */ NULL, &pubKey, &ciphertext, &secret);
if (rv != SECSuccess) {
- crv = CKR_FUNCTION_FAILED;
+ crv = (PORT_GetError() == SEC_ERROR_INVALID_ARGS) ? CKR_ARGUMENTS_BAD : CKR_FUNCTION_FAILED;
goto cleanup;
}
@@ -210,26 +223,26 @@ NSC_Encapsulate(CK_SESSION_HANDLE hSessi
*phKey = key->handle;
*pulCiphertextLen = ciphertext.len;
break;
- }
default:
crv = CKR_MECHANISM_INVALID;
goto cleanup;
}
cleanup:
+ PORT_Memset(secretBuf, 0, sizeof(secretBuf));
if (session) {
sftk_FreeSession(session);
}
if (key) {
status = sftk_FreeObject(key);
if (status == SFTK_DestroyFailure) {
- return CKR_DEVICE_ERROR;
+ crv = CKR_DEVICE_ERROR;
}
}
if (encapsulationKeyObject) {
status = sftk_FreeObject(encapsulationKeyObject);
if (status == SFTK_DestroyFailure) {
- return CKR_DEVICE_ERROR;
+ crv = CKR_DEVICE_ERROR;
}
}
if (encapsulationKey) {
@@ -315,14 +328,17 @@ NSC_Decapsulate(CK_SESSION_HANDLE hSessi
uint8_t secretBuf[KYBER_SHARED_SECRET_BYTES] = { 0 };
SECItem secret = { siBuffer, secretBuf, sizeof secretBuf };
+ key->isFIPS = sftk_operationIsFIPS(slot, pMechanism, CKA_NSS_DECAPSULATE, key, 0);
+ key->source = SFTK_SOURCE_KEM;
+
switch (pMechanism->mechanism) {
- case CKM_NSS_KYBER: {
+ case CKM_NSS_ML_KEM:
PORT_Assert(secret.len == KYBER_SHARED_SECRET_BYTES);
CK_NSS_KEM_PARAMETER_SET_TYPE *pParameter = pMechanism->pParameter;
KyberParams kyberParams = sftk_kyber_PK11ParamToInternal(*pParameter);
SECStatus rv = Kyber_Decapsulate(kyberParams, &privKey, &ciphertext, &secret);
if (rv != SECSuccess) {
- crv = CKR_FUNCTION_FAILED;
+ crv = (PORT_GetError() == SEC_ERROR_INVALID_ARGS) ? CKR_ARGUMENTS_BAD : CKR_FUNCTION_FAILED;
goto cleanup;
}
@@ -337,26 +353,26 @@ NSC_Decapsulate(CK_SESSION_HANDLE hSessi
}
*phKey = key->handle;
break;
- }
default:
crv = CKR_MECHANISM_INVALID;
goto cleanup;
}
cleanup:
+ PORT_Memset(secretBuf, 0, sizeof(secretBuf));
if (session) {
sftk_FreeSession(session);
}
if (key) {
status = sftk_FreeObject(key);
if (status == SFTK_DestroyFailure) {
- return CKR_DEVICE_ERROR;
+ crv = CKR_DEVICE_ERROR;
}
}
if (decapsulationKeyObject) {
status = sftk_FreeObject(decapsulationKeyObject);
if (status == SFTK_DestroyFailure) {
- return CKR_DEVICE_ERROR;
+ crv = CKR_DEVICE_ERROR;
}
}
if (decapsulationKey) {
diff -up ./lib/softoken/pkcs11c.c.mlkem ./lib/softoken/pkcs11c.c
--- ./lib/softoken/pkcs11c.c.mlkem 2024-10-31 14:54:15.453515825 -0700
+++ ./lib/softoken/pkcs11c.c 2024-10-31 14:54:15.467515982 -0700
@@ -5825,8 +5825,12 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hS
break;
case CKM_NSS_KYBER_KEY_PAIR_GEN:
+ crv = CKR_MECHANISM_INVALID;
+ break;
+
+ case CKM_NSS_ML_KEM_KEY_PAIR_GEN:
sftk_DeleteAttributeType(privateKey, CKA_NSS_DB);
- key_type = CKK_NSS_KYBER;
+ key_type = CKK_NSS_ML_KEM;
SECItem privKey = { siBuffer, NULL, 0 };
SECItem pubKey = { siBuffer, NULL, 0 };
@@ -6009,7 +6013,7 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hS
&cktrue, sizeof(CK_BBOOL));
}
- if (crv == CKR_OK && key_type != CKK_NSS_KYBER) {
+ if (crv == CKR_OK && key_type != CKK_NSS_ML_KEM) {
/* Perform FIPS 140-2 pairwise consistency check. */
crv = sftk_PairwiseConsistencyCheck(hSession, slot,
publicKey, privateKey, key_type);
@@ -7255,6 +7259,7 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_
HMACContext *hmac;
unsigned int bufLen;
SFTKSource saltKeySource = SFTK_SOURCE_DEFAULT;
+ SFTKSource saltKeyIsFIPS = PR_FALSE;
switch (params->ulSaltType) {
case CKF_HKDF_SALT_NULL:
@@ -7293,6 +7298,7 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_
keySize*PR_BITS_PER_BYTE);
}
saltKeySource = saltKey->source;
+ saltKeyIsFIPS = saltKey->isFIPS;
saltKey_att = sftk_FindAttribute(saltKey, CKA_VALUE);
if (saltKey_att == NULL) {
sftk_FreeObject(saltKey);
@@ -7310,9 +7316,10 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_
* turn off the FIPS indicator for other usages */
if (isFIPS && key && sourceKey) {
PRBool fipsOK = PR_FALSE;
- /* case one: mix the kea with a previous or default
+ /* case one: mix the kea/kem with a previous or default
* salt */
- if ((sourceKey->source == SFTK_SOURCE_KEA) &&
+ if (((sourceKey->source == SFTK_SOURCE_KEA) ||
+ (sourceKey->source == SFTK_SOURCE_KEM)) &&
(saltKeySource == SFTK_SOURCE_HKDF_EXPAND) &&
(saltLen == rawHash->length)) {
fipsOK = PR_TRUE;
@@ -7322,7 +7329,7 @@ sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_
(NSS_SecureMemcmpZero(sourceKeyBytes, sourceKeyLen) == 0) &&
(sourceKeyLen == rawHash->length) &&
(saltKeySource == SFTK_SOURCE_HKDF_EXPAND) &&
- (saltLen == rawHash->length)) {
+ (saltLen == rawHash->length) && saltKeyIsFIPS) {
fipsOK = PR_TRUE;
}
if (!fipsOK) {
@@ -8476,6 +8483,8 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession
crv = sftk_forceAttribute(key, CKA_VALUE, buf, keySize);
PORT_ZFree(buf, tmpKeySize);
+ /* preserve the source of the original base key */
+ key->source = sourceKey->source;
sftk_FreeAttribute(att2);
sftk_FreeObject(paramKey);
break;
diff -up ./lib/softoken/pkcs11.c.mlkem ./lib/softoken/pkcs11.c
--- ./lib/softoken/pkcs11.c.mlkem 2024-10-31 14:54:15.453515825 -0700
+++ ./lib/softoken/pkcs11.c 2024-10-31 14:54:15.468515993 -0700
@@ -648,9 +648,9 @@ static const struct mechanismList mechan
{ CKM_NSS_IKE_PRF_DERIVE, { 8, 64, CKF_DERIVE }, PR_TRUE },
{ CKM_NSS_IKE1_PRF_DERIVE, { 8, 64, CKF_DERIVE }, PR_TRUE },
{ CKM_NSS_IKE1_APP_B_PRF_DERIVE, { 8, 255 * 64, CKF_DERIVE }, PR_TRUE },
- /* -------------------- Kyber Operations ----------------------- */
- { CKM_NSS_KYBER_KEY_PAIR_GEN, { 0, 0, CKF_GENERATE_KEY_PAIR }, PR_TRUE },
- { CKM_NSS_KYBER, { 0, 0, 0 }, PR_TRUE },
+ /* -------------------- ML KEM Operations ----------------------- */
+ { CKM_NSS_ML_KEM_KEY_PAIR_GEN, { 0, 0, CKF_GENERATE_KEY_PAIR }, PR_TRUE },
+ { CKM_NSS_ML_KEM, { 0, 0, 0 }, PR_TRUE },
};
static const CK_ULONG mechanismCount = sizeof(mechanisms) / sizeof(mechanisms[0]);
@@ -1096,6 +1096,7 @@ sftk_handlePublicKeyObject(SFTKSession *
wrap = CK_FALSE;
break;
case CKK_NSS_KYBER:
+ case CKK_NSS_ML_KEM:
if (!sftk_hasAttribute(object, CKA_NSS_PARAMETER_SET)) {
return CKR_TEMPLATE_INCOMPLETE;
}
@@ -1309,6 +1310,7 @@ sftk_handlePrivateKeyObject(SFTKSession
createObjectInfo = PR_FALSE;
break;
case CKK_NSS_KYBER:
+ case CKK_NSS_ML_KEM:
if (!sftk_hasAttribute(object, CKA_KEY_TYPE)) {
return CKR_TEMPLATE_INCOMPLETE;
}
@@ -2002,6 +2004,7 @@ sftk_GetPubKey(SFTKObject *object, CK_KE
}
break;
case CKK_NSS_KYBER:
+ case CKK_NSS_ML_KEM:
crv = CKR_OK;
break;
default:
@@ -2160,6 +2163,7 @@ sftk_mkPrivKey(SFTKObject *object, CK_KE
break;
case CKK_NSS_KYBER:
+ case CKK_NSS_ML_KEM:
break;
default:
diff -up ./lib/softoken/pkcs11i.h.mlkem ./lib/softoken/pkcs11i.h
--- ./lib/softoken/pkcs11i.h.mlkem 2024-10-31 14:54:15.433515602 -0700
+++ ./lib/softoken/pkcs11i.h 2024-10-31 14:54:15.468515993 -0700
@@ -157,6 +157,7 @@ typedef enum {
typedef enum {
SFTK_SOURCE_DEFAULT=0,
SFTK_SOURCE_KEA,
+ SFTK_SOURCE_KEM,
SFTK_SOURCE_HKDF_EXPAND,
SFTK_SOURCE_HKDF_EXTRACT
} SFTKSource;
diff -up ./lib/softoken/softoken.h.mlkem ./lib/softoken/softoken.h
--- ./lib/softoken/softoken.h.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./lib/softoken/softoken.h 2024-10-31 14:54:15.468515993 -0700
@@ -137,6 +137,24 @@ extern void sftk_AuditDeriveKey(CK_SESSI
extern void sftk_AuditDigestKey(CK_SESSION_HANDLE hSession,
CK_OBJECT_HANDLE hKey, CK_RV rv);
+extern void sftk_AuditEncapsulate(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hPublicKey,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_OBJECT_HANDLE_PTR phKey,
+ CK_BYTE_PTR pCiphertext,
+ CK_ULONG_PTR pulCiphertextLen, CK_RV rv);
+
+extern void sftk_AuditDecapsulate(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hPrivateKey,
+ CK_BYTE_PTR pCiphertext,
+ CK_ULONG ulCiphertextLen,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_OBJECT_HANDLE_PTR phKey, CK_RV rv);
+
/*
** FIPS 140-2 Error state
*/
diff -up ./lib/softoken/softoknt.h.mlkem ./lib/softoken/softoknt.h
--- ./lib/softoken/softoknt.h.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./lib/softoken/softoknt.h 2024-10-31 14:54:15.468515993 -0700
@@ -40,7 +40,9 @@ typedef enum {
NSS_AUDIT_SELF_TEST,
NSS_AUDIT_SET_PIN,
NSS_AUDIT_UNWRAP_KEY,
- NSS_AUDIT_WRAP_KEY
+ NSS_AUDIT_WRAP_KEY,
+ NSS_AUDIT_ENCAPSULATE_KEY,
+ NSS_AUDIT_DECAPSULATE_KEY
} NSSAuditType;
#endif /* _SOFTOKNT_H_ */
diff -up ./lib/ssl/sslimpl.h.mlkem ./lib/ssl/sslimpl.h
--- ./lib/ssl/sslimpl.h.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./lib/ssl/sslimpl.h 2024-10-31 14:54:15.468515993 -0700
@@ -130,7 +130,7 @@ typedef enum { SSLAppOpRead = 0,
#define DTLS_RETRANSMIT_FINISHED_MS 30000
/* default number of entries in namedGroupPreferences */
-#define SSL_NAMED_GROUP_COUNT 32
+#define SSL_NAMED_GROUP_COUNT 33
/* The maximum DH and RSA bit-length supported. */
#define SSL_MAX_DH_KEY_BITS 8192
diff -up ./lib/ssl/sslsock.c.mlkem ./lib/ssl/sslsock.c
--- ./lib/ssl/sslsock.c.mlkem 2024-10-31 14:54:15.419515446 -0700
+++ ./lib/ssl/sslsock.c 2024-10-31 14:54:15.468515993 -0700
@@ -22,6 +22,7 @@
#include "tls13ech.h"
#include "tls13psk.h"
#include "tls13subcerts.h"
+#include "secmodti.h" /* until SEC_OID_MLKEM768SECP256R1 is upstream */
static const sslSocketOps ssl_default_ops = { /* No SSL. */
ssl_DefConnect,
@@ -159,15 +160,21 @@ static const PRUint16 srtpCiphers[] = {
ssl_grp_ffdhe_##size, size, ssl_kea_dh, \
SEC_OID_TLS_FFDHE_##size, PR_TRUE \
}
+#define HYGROUP(kem, ec, size, kem_oid, ec_oid, assumeSupported) \
+ { \
+ ssl_grp_kem_##kem##ec, size, ssl_kea_ecdh_hybrid, \
+ SEC_OID_##kem_oid##ec_oid, assumeSupported \
+ }
const sslNamedGroupDef ssl_named_groups[] = {
- /* Note that 256 for 25519 is a lie, but we only use it for checking bit
- * security and expect 256 bits there (not 255). */
+ /* Note that 256 for 25519 and hybrid is a lie, but we only use it for
+ * checking bit security and expect 256 bits there (not 255). */
+ HYGROUP(mlkem768, x25519, 256, MLKEM768, X25519, PR_TRUE),
{ ssl_grp_ec_curve25519, 256, ssl_kea_ecdh, SEC_OID_CURVE25519, PR_TRUE },
+ HYGROUP(mlkem768, secp256r1, 256, MLKEM768, SECP256R1, PR_TRUE),
ECGROUP(secp256r1, 256, SECP256R1, PR_TRUE),
ECGROUP(secp384r1, 384, SECP384R1, PR_TRUE),
ECGROUP(secp521r1, 521, SECP521R1, PR_TRUE),
- { ssl_grp_kem_xyber768d00, 256, ssl_kea_ecdh_hybrid, SEC_OID_XYBER768D00, PR_TRUE },
FFGROUP(2048),
FFGROUP(3072),
FFGROUP(4096),
diff -up ./lib/ssl/sslt.h.mlkem ./lib/ssl/sslt.h
--- ./lib/ssl/sslt.h.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./lib/ssl/sslt.h 2024-10-31 14:54:15.469516004 -0700
@@ -260,7 +260,8 @@ typedef enum {
ssl_grp_ffdhe_4096 = 258,
ssl_grp_ffdhe_6144 = 259,
ssl_grp_ffdhe_8192 = 260,
- ssl_grp_kem_xyber768d00 = 25497, /* draft-tls-westerbaan-xyber768d00-02 */
+ ssl_grp_kem_mlkem768x25519 = 4588,
+ ssl_grp_kem_mlkem768secp256r1 = 4587,
ssl_grp_none = 65537, /* special value */
ssl_grp_ffdhe_custom = 65538 /* special value */
} SSLNamedGroup;
diff -up ./lib/ssl/tls13con.c.mlkem ./lib/ssl/tls13con.c
--- ./lib/ssl/tls13con.c.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./lib/ssl/tls13con.c 2024-10-31 16:03:17.443439047 -0700
@@ -374,16 +374,24 @@ tls13_CreateKEMKeyPair(sslSocket *ss, co
sslKeyPair **outKeyPair)
{
PORT_Assert(groupDef);
- if (groupDef->name != ssl_grp_kem_xyber768d00) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
sslKeyPair *keyPair = NULL;
SECKEYPrivateKey *privKey = NULL;
SECKEYPublicKey *pubKey = NULL;
- CK_MECHANISM_TYPE mechanism = CKM_NSS_KYBER_KEY_PAIR_GEN;
- CK_NSS_KEM_PARAMETER_SET_TYPE paramSet = CKP_NSS_KYBER_768_ROUND3;
+ CK_MECHANISM_TYPE mechanism;
+ CK_NSS_KEM_PARAMETER_SET_TYPE paramSet;
+
+ switch (groupDef->name) {
+ case ssl_grp_kem_mlkem768x25519:
+ case ssl_grp_kem_mlkem768secp256r1:
+ mechanism = CKM_NSS_ML_KEM_KEY_PAIR_GEN;
+ paramSet = CKP_NSS_ML_KEM_768;
+ break;
+ default:
+ PORT_Assert(0);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
PK11SlotInfo *slot = PK11_GetBestSlot(mechanism, ss->pkcs11PinArg);
if (!slot) {
@@ -430,6 +438,76 @@ loser:
return SECFailure;
}
+/* only copy the ECDh component of an ephemeral KeyPair */
+sslEphemeralKeyPair *
+tls13_CopyDHEphemeralKeyPair(sslEphemeralKeyPair *copyKeyPair,
+ const sslNamedGroupDef *groupDef) {
+ /* We could use ssl_CopyEphemeralKeyPair here, but we would need to free
+ * the KEM components. So we only copy the ECDH keys */
+ sslEphemeralKeyPair *keyPair = PORT_ZNew(sslEphemeralKeyPair);
+ if (!keyPair) {
+ return NULL;
+ }
+ PR_INIT_CLIST(&keyPair->link);
+ keyPair->group = groupDef;
+ keyPair->keys = ssl_GetKeyPairRef(copyKeyPair->keys);
+ return keyPair;
+}
+
+/*
+ * find a hybrid key Pair they might contain the same ecdh key so we
+ * can reuse them. Each ec group can map to more than one hybrid Pair
+ */
+sslEphemeralKeyPair *
+tls13_FindHybridKeyPair(sslSocket *ss, const sslNamedGroupDef *groupDef)
+{
+ sslEphemeralKeyPair *hybridPair = NULL;
+ switch (groupDef->name) {
+ case ssl_grp_ec_secp256r1:
+ /* future, this may be a loop to check multiple named groups */
+ hybridPair = ssl_LookupEphemeralKeyPair(ss,
+ ssl_LookupNamedGroup(ssl_grp_kem_mlkem768secp256r1));
+ break;
+ case ssl_grp_ec_curve25519:
+ /* future, this will be a loop to check multiple named groups */
+ hybridPair = ssl_LookupEphemeralKeyPair(ss,
+ ssl_LookupNamedGroup(ssl_grp_kem_mlkem768x25519));
+ break;
+ default:
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return NULL;
+ }
+ return hybridPair;
+}
+
+/*
+ * Find a corresponding KEM form another hybrid key
+ */
+#ifdef notdef
+sslKeyPair *
+tls13_FindKEMKeyPairFromHybrid(sslSocket *ss, const sslNamedGroupDef *groupDef)
+{
+ sslEphemeralKeyPair *hybridPair = NULL;
+ switch (groupDef->name) {
+ case ssl_grp_kem_mlkem768x25519:
+ /* future, this may be a loop to check multiple named groups */
+ hybridPair = ssl_LookupEphemeralKeyPair(ss,
+ ssl_LookupNamedGroup(ssl_grp_kem_mlkem768secp256r1));
+ break;
+ case ssl_grp_kem_mlkem768secp256r1:
+ /* future, this will be a loop to check multiple named groups */
+ hybridPair = ssl_LookupEphemeralKeyPair(ss,
+ ssl_LookupNamedGroup(ssl_grp_kem_mlkem768x25519));
+ break;
+ default:
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return NULL;
+ }
+ return hybridPair->kemKeys;
+}
+#endif
+
+
SECStatus
tls13_CreateKeyShare(sslSocket *ss, const sslNamedGroupDef *groupDef,
sslEphemeralKeyPair **outKeyPair)
@@ -437,24 +515,48 @@ tls13_CreateKeyShare(sslSocket *ss, cons
SECStatus rv;
const ssl3DHParams *params;
sslEphemeralKeyPair *keyPair = NULL;
+ const sslNamedGroupDef *dhGroup = NULL;
PORT_Assert(groupDef);
switch (groupDef->keaType) {
case ssl_kea_ecdh_hybrid:
- if (groupDef->name != ssl_grp_kem_xyber768d00) {
+ switch (groupDef->name) {
+ case ssl_grp_kem_mlkem768secp256r1:
+ dhGroup = ssl_LookupNamedGroup(ssl_grp_ec_secp256r1);
+ break;
+ case ssl_grp_kem_mlkem768x25519:
+ dhGroup = ssl_LookupNamedGroup(ssl_grp_ec_curve25519);
+ break;
+ default:
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
- rv = ssl_CreateECDHEphemeralKeyPair(ss, ssl_LookupNamedGroup(ssl_grp_ec_curve25519), &keyPair);
- if (rv != SECSuccess) {
+ if (dhGroup == NULL) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
+ keyPair = ssl_LookupEphemeralKeyPair(ss, dhGroup);
+ if (keyPair) {
+ keyPair= ssl_CopyEphemeralKeyPair(keyPair);
+ }
+ if (!keyPair) {
+ rv = ssl_CreateECDHEphemeralKeyPair(ss, dhGroup, &keyPair);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ }
keyPair->group = groupDef;
break;
case ssl_kea_ecdh:
- rv = ssl_CreateECDHEphemeralKeyPair(ss, groupDef, &keyPair);
- if (rv != SECSuccess) {
- return SECFailure;
+ keyPair = tls13_FindHybridKeyPair(ss, groupDef);
+ if (keyPair) {
+ keyPair = tls13_CopyDHEphemeralKeyPair(keyPair, groupDef);
+ }
+ if (!keyPair) {
+ rv = ssl_CreateECDHEphemeralKeyPair(ss, groupDef, &keyPair);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
}
break;
case ssl_kea_dh:
@@ -474,11 +576,27 @@ tls13_CreateKeyShare(sslSocket *ss, cons
// If we're creating an ECDH + KEM hybrid share and we're the client, then
// we still need to generate the KEM key pair. Otherwise we're done.
if (groupDef->keaType == ssl_kea_ecdh_hybrid && !ss->sec.isServer) {
+#ifdef notdef
+ sslKeyPair *kemPair = NULL;
+ kemPair = tls13_FindKEMKeyPairFromHybrid(ss, groupDef);
+ if (kemPair) {
+ kemPair = ssl_GetKeyPairRef(kemPair);
+ }
+ if (!kemPair) {
+ rv = tls13_CreateKEMKeyPair(ss, groupDef, &kemPair);
+ if (rv != SECSuccess) {
+ ssl_FreeEphemeralKeyPair(keyPair);
+ return SECFailure;
+ }
+ }
+ keyPair->kemKeys = kemPair;
+#else
rv = tls13_CreateKEMKeyPair(ss, groupDef, &keyPair->kemKeys);
if (rv != SECSuccess) {
ssl_FreeEphemeralKeyPair(keyPair);
return SECFailure;
}
+#endif
}
*outKeyPair = keyPair;
@@ -658,21 +776,45 @@ tls13_ImportKEMKeyShare(SECKEYPublicKey
{
SECItem pk = { siBuffer, NULL, 0 };
SECStatus rv;
+ size_t expected_len;
- if (entry->group->name != ssl_grp_kem_xyber768d00) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
+ switch (entry->group->name) {
+ case ssl_grp_kem_mlkem768secp256r1:
+ expected_len = SECP256_PUBLIC_KEY_BYTES + KYBER768_PUBLIC_KEY_BYTES;
+ break;
+ case ssl_grp_kem_mlkem768x25519:
+ expected_len = X25519_PUBLIC_KEY_BYTES + KYBER768_PUBLIC_KEY_BYTES;
+ break;
+ default:
+ PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
+ return SECFailure;
}
- if (entry->key_exchange.len != X25519_PUBLIC_KEY_BYTES + KYBER768_PUBLIC_KEY_BYTES) {
+ if (entry->key_exchange.len != expected_len) {
PORT_SetError(SSL_ERROR_RX_MALFORMED_HYBRID_KEY_SHARE);
return SECFailure;
}
- pk.data = entry->key_exchange.data + X25519_PUBLIC_KEY_BYTES;
- pk.len = entry->key_exchange.len - X25519_PUBLIC_KEY_BYTES;
- peerKey->keyType = kyberKey;
- peerKey->u.kyber.params = params_kyber768_round3;
+ switch (entry->group->name) {
+ case ssl_grp_kem_mlkem768secp256r1:
+ peerKey->keyType = kyberKey;
+ peerKey->u.kyber.params = params_ml_kem768;
+ /* key_exchange.data is `secp256 || mlkem768` */
+ pk.data = entry->key_exchange.data + SECP256_PUBLIC_KEY_BYTES;
+ pk.len = KYBER768_PUBLIC_KEY_BYTES;
+ break;
+ case ssl_grp_kem_mlkem768x25519:
+ peerKey->keyType = kyberKey;
+ peerKey->u.kyber.params = params_ml_kem768;
+ /* key_exchange.data is `mlkem768 || x25519` */
+ pk.data = entry->key_exchange.data;
+ pk.len = KYBER768_PUBLIC_KEY_BYTES;
+ break;
+ default:
+ PORT_Assert(0);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
rv = SECITEM_CopyItem(peerKey->arena, &peerKey->u.kyber.publicValue, &pk);
if (rv != SECSuccess) {
@@ -690,13 +832,21 @@ tls13_HandleKEMCiphertext(sslSocket *ss,
SECStatus rv;
switch (entry->group->name) {
- case ssl_grp_kem_xyber768d00:
+ case ssl_grp_kem_mlkem768secp256r1:
+ if (entry->key_exchange.len != SECP256_PUBLIC_KEY_BYTES + KYBER768_CIPHERTEXT_BYTES) {
+ ssl_MapLowLevelError(SSL_ERROR_RX_MALFORMED_HYBRID_KEY_SHARE);
+ return SECFailure;
+ }
+ ct.data = entry->key_exchange.data + SECP256_PUBLIC_KEY_BYTES;
+ ct.len = KYBER768_CIPHERTEXT_BYTES;
+ break;
+ case ssl_grp_kem_mlkem768x25519:
if (entry->key_exchange.len != X25519_PUBLIC_KEY_BYTES + KYBER768_CIPHERTEXT_BYTES) {
ssl_MapLowLevelError(SSL_ERROR_RX_MALFORMED_HYBRID_KEY_SHARE);
return SECFailure;
}
- ct.data = entry->key_exchange.data + X25519_PUBLIC_KEY_BYTES;
- ct.len = entry->key_exchange.len - X25519_PUBLIC_KEY_BYTES;
+ ct.data = entry->key_exchange.data;
+ ct.len = KYBER768_CIPHERTEXT_BYTES;
break;
default:
PORT_Assert(0);
@@ -736,7 +886,7 @@ tls13_HandleKEMKey(sslSocket *ss,
goto loser;
}
- PK11SlotInfo *slot = PK11_GetBestSlot(CKM_NSS_KYBER, ss->pkcs11PinArg);
+ PK11SlotInfo *slot = PK11_GetBestSlot(CKM_NSS_ML_KEM, ss->pkcs11PinArg);
if (!slot) {
goto loser;
}
@@ -757,7 +907,7 @@ tls13_HandleKEMKey(sslSocket *ss,
PK11_FreeSlot(peerKey->pkcs11Slot);
PORT_DestroyCheapArena(&arena);
- return SECSuccess;
+ return rv;
loser:
PORT_DestroyCheapArena(&arena);
@@ -775,8 +925,11 @@ tls13_HandleKeyShare(sslSocket *ss,
SECKEYPublicKey *peerKey;
CK_MECHANISM_TYPE mechanism;
PK11SymKey *key;
+ unsigned char *ec_data;
SECStatus rv;
int keySize = 0;
+ const sslNamedGroupDef *dhGroup = NULL;
+ int dhLen = 0;
PORT_InitCheapArena(&arena, DER_DEFAULT_CHUNKSIZE);
peerKey = PORT_ArenaZNew(&arena.arena, SECKEYPublicKey);
@@ -789,14 +942,32 @@ tls13_HandleKeyShare(sslSocket *ss,
switch (entry->group->keaType) {
case ssl_kea_ecdh_hybrid:
- if (entry->group->name != ssl_grp_kem_xyber768d00 || entry->key_exchange.len < X25519_PUBLIC_KEY_BYTES) {
+ switch (entry->group->name) {
+ case ssl_grp_kem_mlkem768secp256r1:
+ dhLen = SECP256_PUBLIC_KEY_BYTES;
+ /* secp256 share is at the beginning */
+ ec_data = entry->key_exchange.len < dhLen
+ ? NULL
+ : entry->key_exchange.data;
+ dhGroup = ssl_LookupNamedGroup(ssl_grp_ec_secp256r1);
+ break;
+ case ssl_grp_kem_mlkem768x25519:
+ dhLen = X25519_PUBLIC_KEY_BYTES;
+ /* x25519 share is at the end */
+ ec_data = entry->key_exchange.len < dhLen
+ ? NULL
+ : entry->key_exchange.data + entry->key_exchange.len - dhLen;
+ dhGroup = ssl_LookupNamedGroup(ssl_grp_ec_curve25519);
+ break;
+ default:
+ ec_data = NULL;
+ break;
+ }
+ if (!ec_data) {
PORT_SetError(SSL_ERROR_RX_MALFORMED_HYBRID_KEY_SHARE);
goto loser;
}
- rv = ssl_ImportECDHKeyShare(peerKey,
- entry->key_exchange.data,
- X25519_PUBLIC_KEY_BYTES,
- ssl_LookupNamedGroup(ssl_grp_ec_curve25519));
+ rv = ssl_ImportECDHKeyShare(peerKey, ec_data, dhLen, dhGroup);
mechanism = CKM_ECDH1_DERIVE;
break;
case ssl_kea_ecdh:
@@ -2665,10 +2836,19 @@ tls13_HandleClientKeyShare(sslSocket *ss
if (rv != SECSuccess) {
goto loser; /* Error set by tls13_HandleKEMKey */
}
- // We may need to handle different "combiners" here in the future. For
- // now this is specific to xyber768d00.
- PORT_Assert(peerShare->group->name == ssl_grp_kem_xyber768d00);
- ss->ssl3.hs.dheSecret = PK11_ConcatSymKeys(dheSecret, kemSecret, CKM_HKDF_DERIVE, CKA_DERIVE);
+ switch (peerShare->group->name) {
+ case ssl_grp_kem_mlkem768secp256r1:
+ ss->ssl3.hs.dheSecret = PK11_ConcatSymKeys(dheSecret, kemSecret, CKM_HKDF_DERIVE, CKA_DERIVE);
+ break;
+ case ssl_grp_kem_mlkem768x25519:
+ ss->ssl3.hs.dheSecret = PK11_ConcatSymKeys(kemSecret, dheSecret, CKM_HKDF_DERIVE, CKA_DERIVE);
+ break;
+ default:
+ PORT_Assert(0);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ ss->ssl3.hs.dheSecret = NULL;
+ break;
+ }
if (!ss->ssl3.hs.dheSecret) {
goto loser; /* Error set by PK11_ConcatSymKeys */
}
@@ -3512,10 +3692,19 @@ tls13_HandleServerKeyShare(sslSocket *ss
if (rv != SECSuccess) {
goto loser; /* Error set by tls13_HandleKEMCiphertext */
}
- // We may need to handle different "combiners" here in the future. For
- // now this is specific to xyber768d00.
- PORT_Assert(entry->group->name == ssl_grp_kem_xyber768d00);
- ss->ssl3.hs.dheSecret = PK11_ConcatSymKeys(dheSecret, kemSecret, CKM_HKDF_DERIVE, CKA_DERIVE);
+ switch (entry->group->name) {
+ case ssl_grp_kem_mlkem768secp256r1:
+ ss->ssl3.hs.dheSecret = PK11_ConcatSymKeys(dheSecret, kemSecret, CKM_HKDF_DERIVE, CKA_DERIVE);
+ break;
+ case ssl_grp_kem_mlkem768x25519:
+ ss->ssl3.hs.dheSecret = PK11_ConcatSymKeys(kemSecret, dheSecret, CKM_HKDF_DERIVE, CKA_DERIVE);
+ break;
+ default:
+ PORT_Assert(0);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ ss->ssl3.hs.dheSecret = NULL;
+ break;
+ }
if (!ss->ssl3.hs.dheSecret) {
goto loser; /* Error set by PK11_ConcatSymKeys */
}
diff -up ./lib/ssl/tls13exthandle.c.mlkem ./lib/ssl/tls13exthandle.c
--- ./lib/ssl/tls13exthandle.c.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./lib/ssl/tls13exthandle.c 2024-10-31 14:54:15.469516004 -0700
@@ -12,6 +12,8 @@
#include "pk11pub.h"
#include "ssl3ext.h"
#include "ssl3exthandle.h"
+#include "sslt.h"
+#include "tls13con.h"
#include "tls13ech.h"
#include "tls13exthandle.h"
#include "tls13psk.h"
@@ -78,32 +80,77 @@ tls13_SizeOfKeyShareEntry(const sslEphem
if (keyPair->kemKeys) {
PORT_Assert(!keyPair->kemCt);
- PORT_Assert(keyPair->group->name == ssl_grp_kem_xyber768d00);
+ PORT_Assert(keyPair->group->name == ssl_grp_kem_mlkem768secp256r1 || keyPair->group->name == ssl_grp_kem_mlkem768x25519);
pubKey = keyPair->kemKeys->pubKey;
size += pubKey->u.kyber.publicValue.len;
}
if (keyPair->kemCt) {
PORT_Assert(!keyPair->kemKeys);
- PORT_Assert(keyPair->group->name == ssl_grp_kem_xyber768d00);
+ PORT_Assert(keyPair->group->name == ssl_grp_kem_mlkem768secp256r1 || keyPair->group->name == ssl_grp_kem_mlkem768x25519);
size += keyPair->kemCt->len;
}
return size;
}
-SECStatus
-tls13_EncodeKeyShareEntry(sslBuffer *buf, sslEphemeralKeyPair *keyPair)
+static SECStatus
+tls13_WriteMLKEM768Secp256r1KeyExchangeInfo(sslBuffer *buf, sslEphemeralKeyPair *keyPair)
{
- SECStatus rv;
- unsigned int size = tls13_SizeOfKeyShareEntry(keyPair);
+ PORT_Assert(keyPair->group->name == ssl_grp_kem_mlkem768secp256r1);
+ PORT_Assert(keyPair->keys->pubKey->keyType == ecKey);
- rv = sslBuffer_AppendNumber(buf, keyPair->group->name, 2);
- if (rv != SECSuccess)
+ // Encode the p256 key first, then the Kyber768 key or ciphertext.
+ SECStatus rv;
+ rv = sslBuffer_Append(buf, keyPair->keys->pubKey->u.ec.publicValue.data,
+ keyPair->keys->pubKey->u.ec.publicValue.len);
+ if (rv != SECSuccess) {
return rv;
- rv = sslBuffer_AppendNumber(buf, size - 4, 2);
- if (rv != SECSuccess)
+ }
+
+ if (keyPair->kemKeys) {
+ PORT_Assert(!keyPair->kemCt);
+ rv = sslBuffer_Append(buf, keyPair->kemKeys->pubKey->u.kyber.publicValue.data, keyPair->kemKeys->pubKey->u.kyber.publicValue.len);
+ } else if (keyPair->kemCt) {
+ rv = sslBuffer_Append(buf, keyPair->kemCt->data, keyPair->kemCt->len);
+ } else {
+ PORT_Assert(0);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ rv = SECFailure;
+ }
+ return rv;
+}
+
+static SECStatus
+tls13_WriteMLKEM768X25519KeyExchangeInfo(sslBuffer *buf, sslEphemeralKeyPair *keyPair)
+{
+ PORT_Assert(keyPair->group->name == ssl_grp_kem_mlkem768x25519);
+ PORT_Assert(keyPair->keys->pubKey->keyType == ecKey);
+
+ // Encode the ML-KEM-768 key or ciphertext first, then the X25519 share.
+ SECStatus rv;
+ if (keyPair->kemKeys) {
+ PORT_Assert(!keyPair->kemCt);
+ rv = sslBuffer_Append(buf, keyPair->kemKeys->pubKey->u.kyber.publicValue.data, keyPair->kemKeys->pubKey->u.kyber.publicValue.len);
+ } else if (keyPair->kemCt) {
+ rv = sslBuffer_Append(buf, keyPair->kemCt->data, keyPair->kemCt->len);
+ } else {
+ PORT_Assert(0);
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ rv = SECFailure;
+ }
+ if (rv != SECSuccess) {
return rv;
+ }
+
+ rv = sslBuffer_Append(buf, keyPair->keys->pubKey->u.ec.publicValue.data,
+ keyPair->keys->pubKey->u.ec.publicValue.len);
+ return rv;
+}
+static SECStatus
+tls13_WriteKeyExchangeInfo(sslBuffer *buf, sslEphemeralKeyPair *keyPair)
+{
+ SECStatus rv;
const SECKEYPublicKey *pubKey = keyPair->keys->pubKey;
switch (pubKey->keyType) {
case ecKey:
@@ -116,25 +163,40 @@ tls13_EncodeKeyShareEntry(sslBuffer *buf
default:
PORT_Assert(0);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ rv = SECFailure;
break;
}
+ return rv;
+}
+
+SECStatus
+tls13_EncodeKeyShareEntry(sslBuffer *buf, sslEphemeralKeyPair *keyPair)
+{
+ SECStatus rv;
+ unsigned int size = tls13_SizeOfKeyShareEntry(keyPair);
+
+ rv = sslBuffer_AppendNumber(buf, keyPair->group->name, 2);
if (rv != SECSuccess) {
return rv;
}
- if (keyPair->kemKeys) {
- PORT_Assert(!keyPair->kemCt);
- PORT_Assert(keyPair->group->name == ssl_grp_kem_xyber768d00);
- pubKey = keyPair->kemKeys->pubKey;
- rv = sslBuffer_Append(buf, pubKey->u.kyber.publicValue.data, pubKey->u.kyber.publicValue.len);
- }
- if (keyPair->kemCt) {
- PORT_Assert(!keyPair->kemKeys);
- PORT_Assert(keyPair->group->name == ssl_grp_kem_xyber768d00);
- rv = sslBuffer_Append(buf, keyPair->kemCt->data, keyPair->kemCt->len);
+ rv = sslBuffer_AppendNumber(buf, size - 4, 2);
+ if (rv != SECSuccess) {
+ return rv;
}
+ switch (keyPair->group->name) {
+ case ssl_grp_kem_mlkem768x25519:
+ rv = tls13_WriteMLKEM768X25519KeyExchangeInfo(buf, keyPair);
+ break;
+ case ssl_grp_kem_mlkem768secp256r1:
+ rv = tls13_WriteMLKEM768Secp256r1KeyExchangeInfo(buf, keyPair);
+ break;
+ default:
+ rv = tls13_WriteKeyExchangeInfo(buf, keyPair);
+ break;
+ }
return rv;
}
diff -up ./lib/util/eccutil.h.mlkem ./lib/util/eccutil.h
--- ./lib/util/eccutil.h.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./lib/util/eccutil.h 2024-10-31 14:54:15.469516004 -0700
@@ -6,6 +6,7 @@
#define _FREEBL_H_
#define X25519_PUBLIC_KEY_BYTES 32U
+#define SECP256_PUBLIC_KEY_BYTES 65U
/* deprecated */
typedef enum {
diff -up ./lib/util/kyber.h.mlkem ./lib/util/kyber.h
--- ./lib/util/kyber.h.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./lib/util/kyber.h 2024-10-31 14:54:15.469516004 -0700
@@ -27,6 +27,18 @@ typedef enum {
* the use of a seed in `Kyber_Encapsulate` for testing.
*/
params_kyber768_round3_test_mode,
+
+ /*
+ * The ML-KEM parameters specified in FIPS 203.
+ * https://csrc.nist.gov/pubs/fips/203/final
+ */
+ params_ml_kem768,
+
+ /*
+ * Identical to params_ml_kem768 except that this parameter set allows
+ * the use of a seed in `Kyber_Encapsulate` for testing.
+ */
+ params_ml_kem768_test_mode,
} KyberParams;
#endif /* KYBER_UTIL_H */
diff -up ./lib/util/pkcs11n.h.mlkem ./lib/util/pkcs11n.h
--- ./lib/util/pkcs11n.h.mlkem 2024-10-31 14:54:15.421515468 -0700
+++ ./lib/util/pkcs11n.h 2024-10-31 14:54:15.469516004 -0700
@@ -56,6 +56,7 @@
#define CKK_NSS_CHACHA20 (CKK_NSS + 4)
#define CKK_NSS_KYBER (CKK_NSS + 5)
+#define CKK_NSS_ML_KEM (CKK_NSS + 6)
/*
* NSS-defined certificate types
@@ -67,6 +68,8 @@
#define CKA_DIGEST 0x81000000L
#define CKA_NSS_GENERATE 0x81000001L
#define CKA_NSS_GENERATE_KEY_PAIR 0x81000002L
+#define CKA_NSS_ENCAPSULATE 0x81000003L
+#define CKA_NSS_DECAPSULATE 0x81000004L
#define CKA_NSS_MESSAGE 0x82000000L
#define CKA_NSS_MESSAGE_MASK 0xff000000L
#define CKA_FLAGS_ONLY 0 /* CKA_CLASS */
@@ -268,6 +271,10 @@
#define CKM_NSS_KYBER_KEY_PAIR_GEN (CKM_NSS + 45)
#define CKM_NSS_KYBER (CKM_NSS + 46)
+/* ML-KEM */
+#define CKM_NSS_ML_KEM_KEY_PAIR_GEN (CKM_NSS + 48)
+#define CKM_NSS_ML_KEM (CKM_NSS + 49)
+
/*
* HISTORICAL:
* Do not attempt to use these. They are only used by NSS's internal
@@ -290,6 +297,7 @@
/* Parameter set identifiers */
#define CKP_NSS (CKM_VENDOR_DEFINED | NSSCK_VENDOR_NSS)
#define CKP_NSS_KYBER_768_ROUND3 (CKP_NSS + 1)
+#define CKP_NSS_ML_KEM_768 (CKP_NSS + 2)
/* FIPS Indicator defines */
#define CKS_NSS_UNINITIALIZED 0xffffffffUL
diff -up ./lib/util/secoid.c.mlkem ./lib/util/secoid.c
--- ./lib/util/secoid.c.mlkem 2024-10-31 14:54:15.428515546 -0700
+++ ./lib/util/secoid.c 2024-10-31 14:54:15.470516015 -0700
@@ -644,6 +644,9 @@ CONST_OID curve25519[] = { 0x2B, 0x06, 0
CONST_OID ed25519PublicKey[] = { 0x2B, 0x65, 0x70 };
CONST_OID ed25519Signature[] = { 0x2B, 0x65, 0x70 };
+/*https://www.rfc-editor.org/rfc/rfc8410#section-3*/
+CONST_OID x25519PublicKey[] = { 0x2b, 0x65, 0x6e };
+
#define OI(x) \
{ \
siDEROID, (unsigned char *)x, sizeof x \
@@ -1890,11 +1893,19 @@ const static SECOidData oids[SEC_OID_TOT
ODE(SEC_OID_RC2_64_CBC, "RC2-64-CBC", CKM_RC2_CBC, INVALID_CERT_EXTENSION),
ODE(SEC_OID_RC2_128_CBC, "RC2-128-CBC", CKM_RC2_CBC, INVALID_CERT_EXTENSION),
ODE(SEC_OID_ECDH_KEA, "ECDH", CKM_ECDH1_DERIVE, INVALID_CERT_EXTENSION),
+ OD(x25519PublicKey, SEC_OID_X25519,
+ "X25519 key exchange", CKM_EC_MONTGOMERY_KEY_PAIR_GEN, INVALID_CERT_EXTENSION),
+
+ ODE(SEC_OID_MLKEM768X25519,
+ "ML-KEM-768+X25519 key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+
/* this will change upstream. for now apps shouldn't use it */
/* we need it for the policy code. */
ODE(SEC_OID_PRIVATE_1,
"TLS Require EMS", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ ODE(SEC_OID_PRIVATE_2,
+ "ML-KEM-768+SECP256 key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
};
diff -up ./lib/util/secoidt.h.mlkem ./lib/util/secoidt.h
--- ./lib/util/secoidt.h.mlkem 2024-10-31 14:54:15.428515546 -0700
+++ ./lib/util/secoidt.h 2024-10-31 14:54:15.470516015 -0700
@@ -530,9 +530,14 @@ typedef enum {
SEC_OID_RC2_64_CBC = 385,
SEC_OID_RC2_128_CBC = 386,
SEC_OID_ECDH_KEA = 387,
- /* this will change upstream. for now apps shouldn't use it */
+ SEC_OID_X25519 = 388,
+
+ SEC_OID_MLKEM768X25519 = 389,
+
+ /* these will change upstream. for now apps shouldn't use it */
/* give it an obscure name here */
- SEC_OID_PRIVATE_1 = 388,
+ SEC_OID_PRIVATE_1 = 390,
+ SEC_OID_PRIVATE_2 = 391,
SEC_OID_TOTAL
} SECOidTag;
diff -up ./tests/bogo/bogo.sh.mlkem ./tests/bogo/bogo.sh
--- ./tests/bogo/bogo.sh.mlkem 2024-06-07 09:26:03.000000000 -0700
+++ ./tests/bogo/bogo.sh 2024-10-31 14:54:15.470516015 -0700
@@ -13,7 +13,7 @@
########################################################################
# Currently used BorringSSL version
-BOGO_VERSION=f5e0c8f92a22679b0cd8d24d0d670769c1cc07f3
+BOGO_VERSION=73030794f7aaf4f614486b511908841852807936
bogo_init()
{
diff -up ./tests/ssl/sslcov.txt.mlkem ./tests/ssl/sslcov.txt
--- ./tests/ssl/sslcov.txt.mlkem 2024-10-31 14:54:15.454515836 -0700
+++ ./tests/ssl/sslcov.txt 2024-10-31 14:54:15.470516015 -0700
@@ -147,3 +147,9 @@
ECC TLS13 :1301 TLS13_ECDHE_WITH_AES_128_GCM_SHA256
ECC TLS13 :1302 TLS13_ECDHE_WITH_AES_256_GCM_SHA384
ECC TLS13 :1303 TLS13_ECDHE_WITH_CHACHA20_POLY1305_SHA256
+MLKEM256 TLS13 :1301 TLS13_MLKEMP256_WITH_AES_128_GCM_SHA256
+MLKEM256 TLS13 :1302 TLS13_MLKEMP256_WITH_AES_256_GCM_SHA384
+MLKEM256 TLS13 :1303 TLS13_MLKEMP256_WITH_CHACHA20_POLY1305_SHA256
+MLKEM219 TLS13 :1301 TLS13_MLKEMX25519_WITH_AES_128_GCM_SHA256
+MLKEM219 TLS13 :1302 TLS13_MLKEMX25519_WITH_AES_256_GCM_SHA384
+MLKEM219 TLS13 :1303 TLS13_MLKEMX25519_WITH_CHACHA20_POLY1305_SHA256
diff -up ./tests/ssl/ssl.sh.mlkem ./tests/ssl/ssl.sh
--- ./tests/ssl/ssl.sh.mlkem 2024-10-31 15:03:27.098674318 -0700
+++ ./tests/ssl/ssl.sh 2024-10-31 15:03:27.100674340 -0700
@@ -121,8 +121,12 @@ ssl_init()
CIPHER_SUITES="-c ${EC_SUITES}${NON_EC_SUITES}"
TLS13_CIPHER_SUITES="-c ${TLS13_SUITES}${EC_SUITES}${NON_EC_SUITES}"
+ # FIPS specific options for both clients and servers
+ FIPS_OPTIONS=""
# in fips mode, turn off curve25519 until it's NIST approved
- FIPS_OPTIONS="-I P256,P384,P521,FF2048,FF3072,FF4096,FF6144,FF8192"
+ ALL_GROUPS="P256,P384,P521,x25519,FF2048,FF3072,FF4096,FF6144,FF8192,mlkem768secp256r1,mlkem768x25519"
+ NON_PQ_GROUPS="P256,P384,P521,x25519,FF2048,FF3072,FF4096,FF6144,FF8192"
+ FIPS_GROUPS="P256,P384,P521,FF2048,FF3072,FF4096,FF6144,FF8192,mlkem768secp256r1,mlkem768x25519"
# in non-fips mode, tstclnt may run without the db password in some
# cases, but in fips mode it's always needed
@@ -312,10 +316,12 @@ ssl_cov()
SAVE_SERVER_OPTIONS=${SERVER_OPTIONS}
if [ "${SERVER_MODE}" = "fips" ] ; then
- SERVER_OPTIONS="${SERVER_OPTIONS} ${FIPS_OPTIONS}"
+ SERVER_OPTIONS="${SERVER_OPTIONS} -I ${FIPS_GROUPS} ${FIPS_OPTIONS}"
fi
SAVE_CLIENT_OPTIONS=${CLIENT_OPTIONS}
+ CLIENT_GROUPS=${NON_PQ_GROUPS}
if [ "${CLIENT_MODE}" = "fips" ] ; then
+ CLIENT_GROUPS=${FIPS_GROUPS}
CLIENT_OPTIONS="${CLIENT_OPTIONS} ${FIPS_OPTIONS}"
fi
@@ -340,7 +346,7 @@ ssl_cov()
;;
esac
- echo "$SCRIPTNAME: running $testname ----------------------------"
+ echo "$SCRIPTNAME: running $testname ------------------"
VMAX="ssl3"
if [ "$testmax" = "TLS10" ]; then
VMAX="tls1.0"
@@ -375,13 +381,19 @@ ssl_cov()
VMIN="ssl3"
fi
+ TLS_GROUPS=${CLIENT_GROUPS}
+ if [ "$ectype" = "MLKEM256" ]; then
+ TLS_GROUPS="mlkem768secp256r1"
+ elif [ "$ectype" = "MLKEM219" ]; then
+ TLS_GROUPS="mlkem768x25519"
+ fi
+ echo "TLS_GROUPS=${TLS_GROUPS}"
-
- echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -c ${param} -V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} \\"
+ echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -c ${param} -I \"${TLS_GROUPS}\" -V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} \\"
echo " -f -d ${P_R_CLIENTDIR} $verbose -w nss < ${REQUEST_FILE}"
rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
- ${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -c ${param} -V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} -f \
+ ${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -c ${param} -I "${TLS_GROUPS}" -V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} -f \
-d ${P_R_CLIENTDIR} $verbose -w nss < ${REQUEST_FILE} \
>${TMP}/$HOST.tmp.$$ 2>&1
ret=$?