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 { 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 Pkcs11KeyPa return std::unique_ptr( 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( + 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(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( @@ -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(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( 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( 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(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 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(strlen(k0RttData)); SetupForZeroRtt(); // initial handshake as normal + client_->ConfigNamedGroups(kNonPQDHEGroups); static const std::vector groups = {ssl_grp_ec_secp384r1, ssl_grp_ec_secp521r1}; @@ -107,6 +108,7 @@ TEST_P(TlsConnectTls13, SecondClientHell auto orig_client = std::make_shared(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 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 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(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(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(client_, kTlsHandshakeClientHello); + client_->ConfigNamedGroups(kNonPQDHEGroups); // Add PSK with label long enough to push CH length into [256, 511]. std::vector 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( @@ -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(client_); auto server_sid = MakeTlsFilter(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(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(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(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 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(client_); auto server_records = MakeTlsFilter(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(client_); client_->SetFilter( std::make_shared(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( 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 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 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 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 kFFDHEGroups = { @@ -510,12 +516,14 @@ const std::vector kFFDHEG // Defined because the big DHE groups are ridiculously slow. const std::vector 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 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 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 kAllDHEGroups; +const extern std::vector kNonPQDHEGroups; const extern std::vector kECDHEGroups; const extern std::vector kFFDHEGroups; const extern std::vector 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(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(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& 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 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& 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& 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, ¤t_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& 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(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(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 +#include +#include +#include +#include + +#ifdef _MSC_VER +#include +#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 + * + * 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> for +libcrux_ml_kem::types::MlKemPublicKey)#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} +*/ +/** +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> for +libcrux_ml_kem::types::MlKemPrivateKey)#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> for +libcrux_ml_kem::types::MlKemCiphertext)#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#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> for +libcrux_ml_kem::types::MlKemCiphertext)#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> for +libcrux_ml_kem::types::MlKemPublicKey)#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} +*/ +/** +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> for +libcrux_ml_kem::types::MlKemPrivateKey)#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> for +libcrux_ml_kem::types::MlKemCiphertext)#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#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> for +libcrux_ml_kem::types::MlKemCiphertext)#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> for +libcrux_ml_kem::types::MlKemPublicKey)#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} +*/ +/** +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> for +libcrux_ml_kem::types::MlKemPrivateKey)#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} +*/ +/** +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> for +libcrux_ml_kem::types::MlKemCiphertext)#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#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> for +libcrux_ml_kem::types::MlKemCiphertext)#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} +*/ +/** +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} +*/ +/** +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} +*/ +/** +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} +*/ +/** +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 + * + * 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 + * + * 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[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[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[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[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[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[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[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[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[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[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[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[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[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[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 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 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 + * + * 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> for +libcrux_ml_kem::types::MlKemPublicKey)#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} +*/ +/** +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> for +libcrux_ml_kem::types::MlKemPrivateKey)#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> for +libcrux_ml_kem::types::MlKemCiphertext)#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#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> for +libcrux_ml_kem::types::MlKemCiphertext)#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> for +libcrux_ml_kem::types::MlKemPublicKey)#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} +*/ +/** +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> for +libcrux_ml_kem::types::MlKemPrivateKey)#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> for +libcrux_ml_kem::types::MlKemCiphertext)#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#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> for +libcrux_ml_kem::types::MlKemCiphertext)#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> for +libcrux_ml_kem::types::MlKemPublicKey)#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} +*/ +/** +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> for +libcrux_ml_kem::types::MlKemPrivateKey)#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} +*/ +/** +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> for +libcrux_ml_kem::types::MlKemCiphertext)#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#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> for +libcrux_ml_kem::types::MlKemCiphertext)#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} +*/ +/** +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} +*/ +/** +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} +*/ +/** +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} +*/ +/** +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} +*/ +/** +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 + * + * 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} +*/ +/** +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 + * + * 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 + * + * 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 + * + * 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 + * + * 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 + . +*/ +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 Algorithm 11 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 + . +*/ +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[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 for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +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 for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +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 for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +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 for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +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 partially implements Algorithm + 6 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 + . +*/ +/** +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 for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +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 partially implements Algorithm + 6 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 + . +*/ +/** +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[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 for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +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 Algorithm 7 of the NIST FIPS 203 + standard, which is reproduced below: + + ```plaintext + Input: byte array B ∈ 𝔹^{64η}. + Output: array f ∈ ℤ₂₅₆. + + b ← BytesToBits(B) + for (i ← 0; i < 256; i++) + x ← ∑(j=0 to η - 1) b[2iη + j] + y ← ∑(j=0 to η - 1) b[2iη + η + j] + f[i] ← x−y mod q + end for + return f + ``` + + The NIST FIPS 203 standard can be found at + . +*/ +/** +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[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 Algorithm 10 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 + . +*/ +/** +This function found in impl +{libcrux_ml_kem::polynomial::PolynomialRingElement[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[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[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 for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +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[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[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[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 Algorithm 14 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 + . +*/ +/** +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 for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +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 for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +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 for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +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 for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +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 for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +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 partially implements Algorithm + 6 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 + . +*/ +/** +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 for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +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 partially implements Algorithm + 6 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 + . +*/ +/** +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 for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +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[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 for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +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 for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +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 Algorithm 14 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 + . +*/ +/** +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 for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +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 for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +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 for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +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 for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +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 for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +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 partially implements Algorithm + 6 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 + . +*/ +/** +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 for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +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 partially implements Algorithm + 6 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 + . +*/ +/** +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 for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +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[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 for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +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 Algorithm 14 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 + . +*/ +/** +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 for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +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 + * + * 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 + . +*/ +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 Algorithm 11 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 + . +*/ +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 + * + * 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 + * + * 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[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 @@ -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=$?