From 075222ad7ee1aee1697b62f961524707512324ae Mon Sep 17 00:00:00 2001 From: manastasova Date: Tue, 22 Apr 2025 15:25:34 -0700 Subject: [PATCH 1/6] Update CatKDF and CasKDF Combiners --- README.md | 4 +- main.c | 2430 +++++++++++++++++++++++++++++++++++++++++------------ qshkex.c | 512 +++++++++-- qshkex.h | 47 +- 4 files changed, 2381 insertions(+), 612 deletions(-) diff --git a/README.md b/README.md index 4ecd5d1..dbcc479 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ## TS 103 744 Quantum-safe Hybrid Key Exchanges ## - Informative reference implementation as reported in Annex C of ETSI TS 103 744, + Informative reference implementation as reported in Annex D of ETSI TS 103 744, "CYBER; Quantum-safe Hybrid Key Exchanges. The code is not intended for production use. It is intended to be a reference implementation for test. @@ -16,7 +16,7 @@ ### Build instructions ### -This library requires OpenSSL version 1.1.1d libcrypto. +This library requires OpenSSL version 3.x.x libcrypto. gcc -Wall -o etsi-hkex-test main.c qshkex.c -lcrypto ./etsi-hkex-test diff --git a/main.c b/main.c index a395896..5879b21 100644 --- a/main.c +++ b/main.c @@ -16,476 +16,1293 @@ #include "qshkex.h" -#define TEST_VECTOR_CNT 7 -#define HASH_FUNCTIONS_CNT 2 -#define MAX_LABEL_BYTE_LEN 64 -#define MAX_KEY_BYTE_LEN 128 -#define MAX_LABEL_LEN 32 -#define MAX_MSG_BYTE_LEN 4096 -#define CONCAT_CONTEXT_TEST_VECTOR "CONCATENATION TEST VECTOR 1" -#define CASCADE_CONTEXT_TEST_VECTOR "CASCADE TEST VECTOR 1" - -const EVP_MD *(*evp_hash[TEST_VECTOR_CNT][HASH_FUNCTIONS_CNT])(void) = { - {EVP_sha256, EVP_sha3_256}, - {EVP_sha384, EVP_sha3_384}, - {EVP_sha384, EVP_sha3_384}, - {EVP_sha512, EVP_sha3_512}, - {EVP_sha256, EVP_sha3_256}, - {EVP_sha384, EVP_sha3_384}, - {EVP_sha512, EVP_sha3_512}, +#define TEST_VECTOR_CNT 12 +#define INFO_TEST_VECTOR "ETSI_QSHKE_TEST_VECTORS_V_1_2" + +const char *cids_concatenate_hkdf[TEST_VECTOR_CNT] = { + "1111", // HKDFwSHA256, ECDH with P256, MLKEM512, CatKDF + "1711", // HKDFwSHA256, ECDH with Curve25519, MLKEM512, CatKDF + "1411", // HKDFwSHA256, ECDH with BP-P256, MLKEM512, CatKDF + "1121", // HKDFwSHA256, ECDH with P256, MLKEM768, CatKDF + "1721", // HKDFwSHA256, ECDH with Curve25519, MLKEM768, CatKDF + "1421", // HKDFwSHA256, ECDH with BP-P256, MLKEM768, CatKDF + "2221", // HKDFwSHA384, ECDH with P384, MLKEM768, CatKDF + "2821", // HKDFwSHA384, ECDH with Curve448, MLKEM768, CatKDF + "2521", // HKDFwSHA384, ECDH with BP-P384, MLKEM768, CatKDF + "2231", // HKDFwSHA384, ECDH with P384, MLKEM1024, CatKDF + "2831", // HKDFwSHA384, ECDH with Curve448, MLKEM1024, CatKDF + "2531" // HKDFwSHA384, ECDH with BP-P384, MLKEM1024, CatKDF +}; + const char *cids_concatenate_hmac[TEST_VECTOR_CNT] = { + "4111", // HMACwSHA256, ECDH with P256, MLKEM512, CatKDF + "4711", // HMACwSHA256, ECDH with Curve25519, MLKEM512, CatKDF + "4411", // HMACwSHA256, ECDH with BP-P256, MLKEM512, CatKDF + "4121", // HMACwSHA256, ECDH with P256, MLKEM768, CatKDF + "4721", // HMACwSHA256, ECDH with Curve25519, MLKEM768, CatKDF + "4421", // HMACwSHA256, ECDH with BP-P256, MLKEM768, CatKDF + "5221", // HMACwSHA384, ECDH with P384, MLKEM768, CatKDF + "5821", // HMACwSHA384, ECDH with Curve448, MLKEM768, CatKDF + "5521", // HMACwSHA384, ECDH with BP-P384, MLKEM768, CatKDF + "5231", // HMACwSHA384, ECDH with P384, MLKEM1024, CatKDF + "5831", // HMACwSHA384, ECDH with Curve448, MLKEM1024, CatKDF + "5531" // HMACwSHA384, ECDH with BP-P384, MLKEM1024, CatKDF +}; +const char *cids_concatenate_kmac[TEST_VECTOR_CNT] = { + "7111", // KMAC128, ECDH with P256, MLKEM512, CatKDF + "7711", // KMAC128, ECDH with Curve25519, MLKEM512, CatKDF + "7411", // KMAC128, ECDH with BP-P256, MLKEM512, CatKDF + "7121", // KMAC128, ECDH with P256, MLKEM768, CatKDF + "7721", // KMAC128, ECDH with Curve25519, MLKEM768, CatKDF + "7421", // KMAC128, ECDH with BP-P256, MLKEM768, CatKDF + "8221", // KMAC256, ECDH with P384, MLKEM768, CatKDF + "8821", // KMAC256, ECDH with Curve448, MLKEM768, CatKDF + "8521", // KMAC256, ECDH with BP-P384, MLKEM768, CatKDF + "8231", // KMAC256, ECDH with P384, MLKEM1024, CatKDF + "8831", // KMAC256, ECDH with Curve448, MLKEM1024, CatKDF + "8531" // KMAC256, ECDH with BP-P384, MLKEM1024, CatKDF +}; + +const char *cids_cascade_hkdf[TEST_VECTOR_CNT] = { + "1112", // HKDFwSHA256, ECDH with P256, MLKEM512, CasKDF + "1712", // HKDFwSHA256, ECDH with Curve25519, MLKEM512, CasKDF + "1412", // HKDFwSHA256, ECDH with BP-P256, MLKEM512, CasKDF + "1122", // HKDFwSHA256, ECDH with P256, MLKEM768, CasKDF + "1722", // HKDFwSHA256, ECDH with Curve25519, MLKEM768, CasKDF + "1422", // HKDFwSHA256, ECDH with BP-P256, MLKEM768, CasKDF + "2222", // HKDFwSHA384, ECDH with P384, MLKEM768, CasKDF + "2822", // HKDFwSHA384, ECDH with Curve448, MLKEM768, CasKDF + "2522", // HKDFwSHA384, ECDH with BP-P384, MLKEM768, CasKDF + "2232", // HKDFwSHA384, ECDH with P384, MLKEM1024, CasKDF + "2832", // HKDFwSHA384, ECDH with Curve448, MLKEM1024, CasKDF + "2532" // HKDFwSHA384, ECDH with BP-P384, MLKEM1024, CasKDF +}; +const char *cids_cascade_hmac[TEST_VECTOR_CNT] = { + "4112", // HMACwSHA256, ECDH with P256, MLKEM512, CasKDF + "4712", // HMACwSHA256, ECDH with Curve25519, MLKEM512, CasKDF + "4412", // HMACwSHA256, ECDH with BP-P256, MLKEM512, CasKDF + "4122", // HMACwSHA256, ECDH with P256, MLKEM768, CasKDF + "4722", // HMACwSHA256, ECDH with Curve25519, MLKEM768, CasKDF + "4422", // HMACwSHA256, ECDH with BP-P256, MLKEM768, CasKDF + "5222", // HMACwSHA384, ECDH with P384, MLKEM768, CasKDF + "5822", // HMACwSHA384, ECDH with Curve448, MLKEM768, CasKDF + "5522", // HMACwSHA384, ECDH with BP-P384, MLKEM768, CasKDF + "5232", // HMACwSHA384, ECDH with P384, MLKEM1024, CasKDF + "5832", // HMACwSHA384, ECDH with Curve448, MLKEM1024, CasKDF + "5532" // HMACwSHA384, ECDH with BP-P384, MLKEM1024, CasKDF }; +const char *cids_cascade_kmac[TEST_VECTOR_CNT] = { + "7112", // KMAC128, ECDH with P256, MLKEM512, CasKDF + "7712", // KMAC128, ECDH with Curve25519, MLKEM512, CasKDF + "7412", // KMAC128, ECDH with BP-P256, MLKEM512, CasKDF + "7122", // KMAC128, ECDH with P256, MLKEM768, CasKDF + "7722", // KMAC128, ECDH with Curve25519, MLKEM768, CasKDF + "7422", // KMAC128, ECDH with BP-P256, MLKEM768, CasKDF + "8222", // KMAC256, ECDH with P384, MLKEM768, CasKDF + "8822", // KMAC256, ECDH with Curve448, MLKEM768, CasKDF + "8522", // KMAC256, ECDH with BP-P384, MLKEM768, CasKDF + "8232", // KMAC256, ECDH with P384, MLKEM1024, CasKDF + "8832", // KMAC256, ECDH with Curve448, MLKEM1024, CasKDF + "8532" // KMAC256, ECDH with BP-P384, MLKEM1024, CasKDF +}; + +const EVP_MD *(*evp_hash[TEST_VECTOR_CNT])(void) = { + EVP_sha256, + EVP_sha256, + EVP_sha256, + EVP_sha256, + EVP_sha256, + EVP_sha256, + EVP_sha384, + EVP_sha384, + EVP_sha384, + EVP_sha384, + EVP_sha384, + EVP_sha384}; -const uint32_t key_length[TEST_VECTOR_CNT] = {16, 24, 24, 32, 16, 24, 32}; +const char *kmac[TEST_VECTOR_CNT] = { + SN_kmac128, + SN_kmac128, + SN_kmac128, + SN_kmac128, + SN_kmac128, + SN_kmac128, + SN_kmac256, + SN_kmac256, + SN_kmac256, + SN_kmac256, + SN_kmac256, + SN_kmac256}; + +const int curves[TEST_VECTOR_CNT] = { + NID_X9_62_prime256v1, + EVP_PKEY_X25519, + NID_brainpoolP256r1, + NID_X9_62_prime256v1, + EVP_PKEY_X25519, + NID_brainpoolP256r1, + NID_secp384r1, + EVP_PKEY_X448, + NID_brainpoolP384r1, + NID_secp384r1, + EVP_PKEY_X448, + NID_brainpoolP384r1}; + +const char *kems[TEST_VECTOR_CNT] = { + "mlkem512", + "mlkem512", + "mlkem512", + "mlkem768", + "mlkem768", + "mlkem768", + "mlkem768", + "mlkem768", + "mlkem768", + "mlkem1024", + "mlkem1024", + "mlkem1024"}; + +const char *kems_derand[TEST_VECTOR_CNT] = { + "ML-KEM-512", + "ML-KEM-512", + "ML-KEM-512", + "ML-KEM-768", + "ML-KEM-768", + "ML-KEM-768", + "ML-KEM-768", + "ML-KEM-768", + "ML-KEM-768", + "ML-KEM-1024", + "ML-KEM-1024", + "ML-KEM-1024"}; + +const uint32_t key_length[TEST_VECTOR_CNT] = {16, 16, 16, 16, 16, 16, 24, 24, 24, 24, 24, 24}; + +// 64 bytes +const char strPSK[] = { + "00000000000000000000000000000000000000000000000000000000000000000000000000\ +000000000000000000000000000000000000000000000000000000"}; + +// Label should be of same length agreed /* Label contribution from A */ const char *strLA1[] = { - "0102030405060708090A0B0C0D0E0F10", - "1102030405060708090A0B0C0D0E0F100102030405060708", - "2102030405060708090A0B0C0D0E0F100102030405060709", - "3102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F10", - "10102030405060708090A0B0C0D0E0F1", - "21102030405060708090A0B0C0D0E0F10010203040506070", - "33102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F1"}; + "0102030405060708090A0B0C0D0E0F10102030405060708090A0B0C0D0E0F101", + "0102030405060708090A0B0C0D0E0F12102030405060708090A0B0C0D0E0F122", + "20102030405060708090A0B0C0D0E0F10102030405060708090A0B0C0D0E0F13", + "10102030405060708090A0B0C0D0E0F10102030405060708090A0B0C0D0E0F14", + "0102030405060708090A0B0C0D0E0F1101020304050607081020304050607085", + "1102030405060708090A0B0C0D0E0F1001020304050607081020304050607086", + "2102030405060708090A0B0C0D0E0F100102030405060709102030405060708090A0B0C0D0E0F1001020304050607097", + "3102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F13102030405060708090A0B0C0D0E0F108", + "21102030405060708090A0B0C0D0E0F100102030405060711102030405060708090A0B0C0D0E0F100102030405060719", + "33102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F13102030405060708090A0B0C0D0E0F1A", + "21102030405060708090A0B0C0D0E0F100102030405060701102030405060708090A0B0C0D0E0F10010203040506070B", + "43102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F13102030405060708090A0B0C0D0E0F1C"}; + const char *strLA2[] = { - "4102030405060708090A0B0C0D0E0F11", - "5102030405060708090A0B0C0D0E0F110102030405060708", - "6102030405060708090A0B0C0D0E0F110102030405060709", - "7102030405060708090A0B0C0D0E0F110102030405060708090A0B0C0D0E0F11", - "14102030405060708090A0B0C0D0E0F1", - "25102030405060708090A0B0C0D0E0F11010203040506070", - "3102030405060708090A0B0C0D0E0F110102030405060708090A0B0C0D0E0F11"}; + "4102030405060708090A0B0C0D0E0F11102030405060708090A0B0C0D0E0F11D", + "4102030405060708090A0B0C0D0E0F12102030405060708090A0B0C0D0E0F12E", + "14102030405060708090A0B0C0D0E0F24102030405060708090A0B0C0D0E0F2F", + "3102030405060708090A0B0C0D0E0F110102030405060708090A0B0C0D0E0F30", + "14102030405060708090A0B0C0D0E0F14102030405060708090A0B0C0D0E0F11", + "5102030405060708090A0B0C0D0E0F1101020304050607081020304050607082", + "5102030405060708090A0B0C0D0E0F110102030405060709102030405060708090A0B0C0D0E0F1101020304050607093", + "6102030405060708090A0B0C0D0E0F110102030405060709102030405060708090A0B0C0D0E0F1101020304050607094", + "7102030405060708090A0B0C0D0E0F110102030405060708090A0B0C0D0E0F223102030405060708090A0B0C0D0E0F15", + "35102030405060708090A0B0C0D0E0F110102030405060705102030405060708090A0B0C0D0E0F110102030405060706", + "25102030405060708090A0B0C0D0E0F110102030405060705102030405060708090A0B0C0D0E0F110102030405060707", + "4102030405060708090A0B0C0D0E0F130102030405060708090A0B0C0D0E0F43102030405060708090A0B0C0D0E0F138"}; const char *strPA1[] = { - /* ECDH (NIST P-256, NIST P-384, NIST P-521) public keys from NIST CAVP SP + /* ECDH (NIST P-256, NIST P-384) public keys from NIST CAVP SP * 800-56A ECCCDH Primitive Test Vectors. * http://csrc.nist.gov/groups/STM/cavp/documents/components * /ecccdhtestvectors.zip + * ECDH (Curve25519 and Curve448) public keys from IETF RFC 7748 + * https://datatracker.ietf.org/doc/html/rfc7748#page-4 + * ECDH (BP-P256 and BP-P384) public keys from IETF RFC 8734 + * https://www.rfc-editor.org/rfc/rfc8734.txt */ "119F2F047902782AB0C9E27A54AFF5EB9B964829CA99C06B02DDBA95B0A3F6D08F52B72666\ -4CAC366FC98AC7A012B2682CBD962E5ACB544671D41B9445704D1D", +4CAC366FC98AC7A012B2682CBD962E5ACB544671D41B9445704D1D", // NIST P-256 + "8520F0098930A754748B7DDCB43EF75A0DBF3A0D26381AF4EBA4A98EAA9B4E6A", // Curve25519 + "44106E913F92BC02A1705D9953A8414DB95E1AAA49E81D9E85F929A8E3100BE58AB4846F11\ +CACCB73CE49CBDD120F5A900A69FD32C272223F789EF10EB089BDC", // BP-P256 + "EAD218590119E8876B29146FF89CA61770C4EDBBF97D38CE385ED281D8A6B23028AF61281F\ +D35E2FA7002523ACC85A429CB06EE6648325389F59EDFCE1405141", // NIST P-256 + "8520F0098930A754748B7DDCB43EF75A0DBF3A0D26381AF4EBA4A98EAA9B4E6A", // Curve25519 + "44106E913F92BC02A1705D9953A8414DB95E1AAA49E81D9E85F929A8E3100BE58AB4846F11\ +CACCB73CE49CBDD120F5A900A69FD32C272223F789EF10EB089BDC", // BP-P256 "9803807F2F6D2FD966CDD0290BD410C0190352FBEC7FF6247DE1302DF86F25D34FE4A97BEF\ 60CFF548355C015DBB3E5FBA26CA69EC2F5B5D9DAD20CC9DA711383A9DBE34EA3FA5A2AF75B4650\ -2629AD54DD8B7D73A8ABB06A3A3BE47D650CC99", - "EA4018F5A307C379180BF6A62FD2CECEEBEEB7D4DF063A66FB838AA35243419791F7E2C9D4\ -803C9319AA0EB03C416B6668835A91484F05EF028284DF6436FB88FFEBABCDD69AB0133E6735A1B\ -CFB37203D10D340A8328A7B68770CA75878A1A6", - "00602F9D0CF9E526B29E22381C203C48A886C2B0673033366314F1FFBCBA240BA42F4EF38A\ -76174635F91E6B4ED34275EB01C8467D05CA80315BF1A7BBD945F550A501B7C85F26F5D4B2D7355\ -CF6B02117659943762B6D1DB5AB4F1DBC44CE7B2946EB6C7DE342962893FD387D1B73D7A8672D1F\ -236961170B7EB3579953EE5CDC88CD2D", - "EAD218590119E8876B29146FF89CA61770C4EDBBF97D38CE385ED281D8A6B23028AF61281F\ -D35E2FA7002523ACC85A429CB06EE6648325389F59EDFCE1405141", - "FCFCEA085E8CF74D0DCED1620BA8423694F903A219BBF901B0B59D6AC81BAAD316A242BA32\ -BDE85CB248119B852FAB66972E3C68C7AB402C5836F2A16ED451A33120A7750A6039F3FF15388EE\ -622B7065F7122BF6D51AEFBC29B37B03404581B", - "00D45615ED5D37FDE699610A62CD43BA76BEDD8F85ED31005FE00D6450FBBD101291ABD96D\ -4945A8B57BC73B3FE9F4671105309EC9B6879D0551D930DAC8BA45D25501425332844E592B440C0\ -027972AD1526431C06732DF19CD46A242172D4DD67C2C8C99DFC22E49949A56CF90C6473635CE82\ -F25B33682FB19BC33BD910ED8CE3A7FA"}; +2629AD54DD8B7D73A8ABB06A3A3BE47D650CC99", // NIST P-384 + "9B08F7CC31B7E3E67D22D5AEA121074A273BD2B83DE09C63FAA73D2C22C5D9BBC836647241\ +D953D40C5B12DA88120D53177F80E532C41FA0", // Curve448 + "68B665DD91C195800650CDD363C625F4E742E8134667B767B1B476793588F885AB698C852D\ +4A6E77A252D6380FCAF06855BC91A39C9EC01DEE36017B7D673A931236D2F1F5C83942D049E3FA2\ +0607493E0D038FF2FD30C2AB67D15C85F7FAA59", // BP-P384 + "9803807F2F6D2FD966CDD0290BD410C0190352FBEC7FF6247DE1302DF86F25D34FE4A97BEF\ +60CFF548355C015DBB3E5FBA26CA69EC2F5B5D9DAD20CC9DA711383A9DBE34EA3FA5A2AF75B4650\ +2629AD54DD8B7D73A8ABB06A3A3BE47D650CC99", // NIST P-384 + "9B08F7CC31B7E3E67D22D5AEA121074A273BD2B83DE09C63FAA73D2C22C5D9BBC836647241\ +D953D40C5B12DA88120D53177F80E532C41FA0", // Curve448 + "68B665DD91C195800650CDD363C625F4E742E8134667B767B1B476793588F885AB698C852D\ +4A6E77A252D6380FCAF06855BC91A39C9EC01DEE36017B7D673A931236D2F1F5C83942D049E3FA2\ +0607493E0D038FF2FD30C2AB67D15C85F7FAA59"}; // BP-P384 const char *strPA2[] = { - /* SIKE (sikep434, sikep503, sikep610, sikep751) public keys from Round 3 KATs, - * https://csrc.nist.gov/CSRC/media/Projects/post-quantum-cryptography - * /documents/round-3/submissions/SIKE-Round3.zip - */ - "4484D7AADB44B40CC180DC568B2C142A60E6E2863F5988614A6215254B2F5F6F79B48F329A\ -D1A2DED20B7ABAB10F7DBF59C3E20B59A700093060D2A44ACDC0083A53CF0808E0B3A827C45176B\ -EE0DC6EC7CC16461E38461C12451BB95191407C1E942BB50D4C7B25A49C644B630159E6C4036538\ -38E689FBF4A7ADEA693ED0657BA4A724786AF7953F7BA6E15F9BBF9F5007FB711569E72ACAB05D3\ -463A458536CAB647F00C205D27D5311B2A5113D4B26548000DB237515931A040804E769361F94FF\ -0167C78353D2630A1E6F595A1F80E87F6A5BCD679D7A64C5006F6191D4ADEFA1EA67F6388B7017D\ -453F4FE2DFE80CCC709000B52175BFC3ADE52ECCB0CEBE1654F89D39131C357EACB61E5F13C80AB\ -0165B7714D6BE6DF65F8DE73FF47B7F3304639F0903653ECCFA252F6E2104C4ABAD3C33AF24FD0E\ -56F58DB92CC66859766035419AB2DF600", - "05279D27FF7E3A38ABB05DCFE23B5831C030D832D3EAE35FE06A6538597532D22A0F4012FB\ -2263E160495F8291B58D9DF8A8947C7CF3E6735520BB2D094912408829851AC4B85AA922069F2AA\ -A0A4827DFA4730E9CF05485CBEE411C3D5169DD4953746B6A2E6574957EF920596B1612BE62A883\ -740B5A0C157117AE1C3A07E4CE8CCCE7E9E88FE7C20A507FF019AE0893F34303E173D291F6CB7EC\ -B4C3901FF34A48DE40771F5BAD72DA2B4C1CFD0A61F33E39327A8DA60F5640D4C2E71EF9C7297A4\ -E9BC50493E3BA65D3664610A6D61035CB6600378D017D1E1810ACD113252D60F5915749C2B5CFB4\ -452C40C86F1F40C63297DCCA900686F2D2266F9444539D9BA13B1F52FB2FC3BD4F3EDAA6EB707AA\ -FCA5261EA271ED961B2ED195D5E3B0299179251866CE0EAA31C5C90B7999A8D63BA2DE84A8AFA19\ -F11F2DC0CACA39B982CE053F71D269931D9EE26BCE592A8EA818553BC8F8D244F62FB4F5E5386E3\ -EFF5CD231401C9EC2BA57FF42DC3B3791357A53E1E31394008", - "671B24769304DD18C97AF0C5DE741C53E0B45A9E18C7A13A15C1758125E41605587E450F84\ -52A2BF98B51C2AF6B0503CB8E01F8553C36079EBFADF4948FFA063ABF4866E7AB9B9D4C9A07CA40\ -0C613607E6DB9BB6E7EB8ECA78894C7C8CE9E231B33179B2946C5C5BE1C783FA6AEA218F5EC4B4E\ -6F914E5ED3724C5D7B79403F68438A40775E964C1B2C7D22E11A6C07474EB5D4CFF75965B400167\ -E069FA9908A562DBABF5E30FED46BBA0A208ED4E50764CF320FB8556F07C7F6268084476A47D83B\ -085DC77EB3CD30A2B5EE1E5829738077D52A0D7A4149EE9C1A70269BC047B4BE7E5B28007DEF74A\ -4D813853396708A3A8498CC862F54015B79047014639EB8CA3BB786B27A2CFAF31E6BB9CCB152BE\ -B3232465206973668597AA35EE1940A316F71241FA40D1AC233931E1967E79AAA600AA6D83FEC62\ -80A63924E7375F22F7A47E1DE483FEA17E0DACBAEDBB13D58C0DC9BC21F2DC9525D46E4210AC5D8\ -8567E4F23304EA5BE08D89D57A0246EA21C0CD28C096366D7F3C8D98F5A1FB00FE2F3A183E53A7E\ -8B6C19E9BF979E8D20C703C957D6F06A142BE86A0A09B05ED40953BBD7A15E92098633941730DEB\ -5BC1C5F5154E8BCA38E035580E101E6EE858D91BD8462B906EB2004C6E01", - "E1A758EC0D418BFE86D8077B5BB169133C06C1F2A067D8B202D9D058FFC51F63FD26155A65\ -77C74BA7F1A27E7BA51982517B923615DEB00BE408920A07831DF5978CFDDD0BF690A264353A4A1\ -6B666F90586D7F89A193CE09375D389C1379A7A528581C3ACB002CD2DC4F0FD672568FF9050BA83\ -65C7FEFC5E6ED089B921DE6804091A0744DE3EB14D426A3F7DA215C50312617C1C2697243980D06\ -056F2CCE88AE7AE73C7343C0B7104C9F2870A94FED744CF6E94630514B6CEAB0E64733BB6FA67B9\ -31E5D8206010475CBE8BC587248D65D89D8CD9C8BBFA93E8B5F9EB9130773DED665D52ABBD91C4C\ -8C255F73C0FC82501AE33330E9F308DE7177CBF83E4E26E334D7CB09019E638147FC58ED372AF66\ -0F14C194BC80E9666325C98E0F80877271D4A6BF514F603703D8A697874CD50A34D92F5AAEA8463\ -3CCF96801BD517BF425DEE4A32AAF06684052473EA14643C3D535440FB2240A988D09F297C5A388\ -CB3DE60ED943F124034B90EFF611221F80F78EC124956338A105F6636B063D7E48BFBD5D614310F\ -B97D86F122E4AE6F9DDF4977A93ED7D0CE2A94E346A1A03D3219CF21907B85A5BCDC713F93A4406\ -A22E03B1655A66E1F6741A2F953E6FE0868B2614BABEF1943BBBCB1B66D3E7017E533EA84F29124\ -0B56AB33EF1DC3F3DE99DBF9E8BE51A0076E462BCDD825EA96D7F63C99177C305C257B31461F4C2\ -3D43115F0220409E8880BBB2468586D03461E807BE824B693874911B2B52AF06FDBDC47F5A01597\ -29641A7C950AB9E03F2DC045135", - /* KYBER (kyber512, kyber768, kyber1024) public from Round 3 KATs, - * https://csrc.nist.gov/CSRC/media/Projects/post-quantum-cryptography - * /documents/round-3/submissions/Kyber-Round3.zip + /* FIPS203 ML-KEM (ML-KEM512, ML-KEM768, ML-KEM1024) public keys + * https://github.com/post-quantum-cryptography/KAT + * Tests are used by AWS-LC https://raw.githubusercontent.com/aws/ + * aws-lc/refs/heads/main/crypto/fipsmodule/ml_kem/kat/mlkem512.txt + * NIST ACVP test vectors https://github.com/usnistgov/ACVP-Server + * do not provide matching tests for ML-KEM.KeyGen() and ML-KEM.Encaps()/Decaps() */ - "115ACE0E64677CBB7DCFC93C16D3A305F67615A488D711AA56698C5663AB7AC9CE66D547C0\ -595F98A43F4650BBE08C364D976789117D34F6AE51AC063CB55C6CA32558227DFEF807D19C30DE4\ -14424097F6AA236A1053B4A07A76BE372A5C6B6002791EBE0AFDAF54E1CA237FF545BA68343E745\ -C04AD1639DBC590346B6B9569B56DBBFE53151913066E5C85527DC9468110A136A411497C227DCB\ -8C9B25570B7A0E42AADA6709F23208F5D496EBAB7843F6483BF0C0C73A40296EC2C6440001394C9\ -9CA173D5C775B7F415D02A5A26A07407918587C41169F2B7178755ACC27FC8B19C4C4B3FCD41053\ -F2C74C8A10A8321241B2802432875AE808B9EF1365C7B8A52902F1317BA2FB0269F47930672107B\ -4726FEF64547394D3320C8F120B3C2F4725B0305FAB88CC7981FCB09A76A1CBF7F179F43BB0A4C8\ -B0590857F1E69708466C7F8607391E7BC5268BFD3D7A1DFFCB4ECA2A1C9B597593013D5FC4202EC\ -2B74E57AB76BBCF3632BBAF97CDC418A6F16392838CA9BF45DDF023777B7561833C105190F94F30\ -2C59B531900BBC816361FAA5B3380CA3A893104CA7388B185671B3E5FE3790E9A626EC46D9B0B33\ -C7A419AF7B32B6859894F575D82AC5456B5490A7AF8FE61046360589ECBA7244236F4123116B617\ -4AA179249A49195B356C72FC6641F0251812EAA98570B046699070E0819DC2713F469137DFC6A3D\ -7B92B298995EE780369153AC366B06D7249CD09E1B3378FB04399CECB8650581D637C79AE67D6F2\ -CAF6ABACF598159A7792CB3C971D1499D2373AD20F63F03BB59ED137384AC61A7155143B8CA4932\ -612EC915E4CA346A9BCE5DD60417C6B2A89B1CC435643F875BDC5A7E5B3481CF919EA09172FEBC4\ -6D4FC3FB0CB9591704EE2DBB61844B2F3314A06BB6C6D34005E485CE667BDC7D098586928D2D913\ -40F00419EA401351A240A0B041058BEFB0C2FD32645B7A2DF8F5CBFD873327C978D7B351A280884\ -38837024C52B9C295CD713646FB5D6C0CCFB470734AC2B2BC8123C2C13DF6938E92455A862639FE\ -B8A64B85163E32707E037B38D8AC3922B45187BB65EAFD465FC64A0C5F8F3F9003489415899D59A\ -543D8208C54A3166529B53922", - "A72C2D9C843EE9F8313ECC7F86D6294D59159D9A879A542E260922ADF999051CC45200C9FF\ -DB60449C49465979272367C083A7D6267A3ED7A7FD47957C219327F7CA73A4007E1627F00B11CC8\ -0573C15AEE6640FB8562DFA6B240CA0AD351AC4AC155B96C14C8AB13DD262CDFD51C4BB5572FD61\ -6553D17BDD430ACBEA3E95F0B698D66990AB51E5D03783A8B3D278A5720454CF9695CFDCA08485B\ -A099C51CD92A7EA7587C1D15C28E609A81852601B0604010679AA482D51261EC36E36B871967621\ -7FD74C54786488F4B4969C05A8BA27CA3A77CCE73B965923CA554E422B9B61F4754641608AC16C9\ -B8587A32C1C5DD788F88B36B717A46965635DEB67F45B129B99070909C93EB80B42C2B3F3F70343\ -A7CF37E8520E7BCFC416ACA4F18C7981262BA2BFC756AE03278F0EC66DC2057696824BA6769865A\ -601D7148EF6F54E5AF5686AA2906F994CE38A5E0B938F239007003022C03392DF3401B1E4A3A7EB\ -C6161449F73374C8B0140369343D9295FDF511845C4A46EBAAB6CA5492F6800B98C0CC803653A4B\ -1D6E6AAED1932BACC5FEFAA818BA502859BA5494C5F5402C8536A9C4C1888150617F80098F6B2A9\ -9C39BC5DC7CF3B5900A21329AB59053ABAA64ED163E859A8B3B3CA3359B750CCC3E710C7AC43C81\ -91CB5D68870C06391C0CB8AEC72B897AC6BE7FBAACC676ED66314C83630E89448C88A1DF04ACEB2\ -3ABF2E409EF333C622289C18A2134E650C45257E47475FA33AA537A5A8F7680214716C50D470E32\ -84963CA64F54677AEC54B5272162BF52BC8142E1D4183FC017454A6B5A496831759064024745978\ -CBD51A6CEDC8955DE4CC6D363670A47466E82BE5C23603A17BF22ACDB7CC984AF08C87E14E27753\ -CF587A8EC3447E62C649E887A67C36C9CE98721B697213275646B194F36758673A8ED11284455AF\ -C7A8529F69C97A3C2D7B8C636C0BA55614B768E624E712930F776169B01715725351BC74B47395E\ -D52B25A1313C95164814C34C979CBDFAB85954662CAB485E75087A98CC74BB82CA2D1B5BF280323\ -8480638C40E90B43C7460E7AA917F010151FAB1169987B372ABB59271F7006C24E60236B84B9DDD\ -600623704254617FB498D89E58B0368BCB2103E79353EB587860C1422E476162E425BC2381DB82C\ -6592737E1DD602864B0167A71EC1F223305C02FE25052AF2B3B5A55A0D7A2022D9A798DC0C5874A\ -98702AAF4054C5D80338A5248B5B7BD09C53B5E2A084B047D277A861B1A73BB51488DE04EF573C8\ -5230A0470B73175C9FA50594F66A5F50B4150054C93B68186F8B5CBC49316C8548A642B2B36A1D4\ -54C7489AC33B2D2CE6668096782A2C1E0866D21A65E16B585E7AF8618BDF3184C19868785089172\ -77B93E10706B1614972B2A94C7310FE9C708C231A1A8AC8D9314A529A97F469BF64962D82064844\ -3099A076D55D4CEA824A58304844F99497C10A25148618A315D72CA857D1B04D575B94F85C01D19\ -BEF211BF0AA3362E7041FD16596D808E867B44C4C00D1CDA3418967717F147D0EB21B42AAEE74AC\ -35D0B92414B958531AADF463EC6305AE5ECAF79174002F26DDECC813BF32672E8529D95A4E730A7\ -AB4A3E8F8A8AF979A665EAFD465FC64A0C5F8F3F9003489415899D59A543D8208C54A3166529B53\ -922", - "D22302CBD3399FACC630991FC8F28BDB4354762541527678BCF61F65C241146C426D23B9BF\ -AA6B7DF18C97F20C1B6125BF874B1D89475852C448215DB0EB7737F91480E8CEBD9A0871574F5AB\ -62D9020175EC6927CA0B54C09818E42CF92A383172422C7DC1831D63B0C295DE75159DB8034E9E0\ -7F7B0B910C3C1E5FB66B3DC523F1FA6EB4910CB89A6C17562C83AB4C18D0CD7E0796592A372AA40\ -9B1C557347CCACDC4644A119064D06DD474929D1C6FB4D686E5491CE4BC89A30BB4B8C41BCE5157\ -DFC1360823B1AB618C14B10F98C25067398EA7018C278A4B3DF31334D603B2044EF187CD9BC6CE4\ -2725BD962C264983E9E18155A8B9C47143D70460A26A56FE7658C1F150348C6087EF758AD167887\ -860A007A5FC37358D43B5EBEE820ACEA474F0AC07B76802866199C61231D5C747C93774D2C1E0C1\ -C67E6C81B82752173E125BAF39B4FD19A4F453DC57976B1D97FE6996992BBB65B7CB25D077BBAA6\ -A13322899AF659CF1B3558C1B5001154B625809ED89AEEBB89E6EA7D67F723D045AB05715C42355\ -DA6A5C8DD39C8ABE3037751A01ED1C7374919F3121B5A52C53D1487316769F80721DEEAAAD3C90F\ -76E7AE9E12BA92B32B5FD457E3C752C2650DFB885771CB77AC3C785A8C562E6A1C63C2A55EA47CF\ -8B90EB8225C123C346452566235B2F31823A33521E087937A345D8D663EEAA05658917BBAA008C2\ -E335F8850A90A326D0E66432F44CEB8289E4ECB2D12958E984072ECACB88E1348FF0B55654ACBA5\ -B54971CBAEBA88EC4B91A94C37192FA982BECB9F3DA421603B61A51BC8E36CBD053851C77B1B926\ -B17A272AA9023246B02B3ED47F66A00BD5684823634E7CE58CF8F306E35B1E5322824D904801F0A\ -2FA7C2BC9C252B0A56B7BA2AB0F636021745A70A9A43E2B0A8D615970B65309624B5184BCC30B91\ -1679AEDD76025FE3908FD67897B0CF4BE5A6F5413D7DD98564B23E42A93E4AA8821CD45054C643E\ -DC1158DB6B3DEB13FB5A51EBD1A8A78B87225A7338E101104C4A220D9BDEDD48C85A1C2DAE781A8\ -0C40E13B87EAC73A764201C9B760CCFB1AE392699C7039D27C39362B27B8FC6F07A8A3D4410F154\ -7C48A9997F62C61074452EF1515F8A649EBCA9437205A4E8A61606B41DAF6834D671F4D852C0C9C\ -4096611648C6A3170678B1537CC1828D93580C9E5849A9653175ACB753F2BE7437BE45F6C603E48\ -5F2EC301BB42B6C37C225D7495A584AE231890AB5C8C35C268CF4BBB0213C096019319561A8A694\ -7637AA40D006B415BB2CFA2237E0890B6A3BC134ABF8F6585E108D15940F91F4BF5B0C818055B21\ -DEA6E63B553988C47F4B94E7CF800A493B4734705EDC56A4B6021C629500675876804CF0B951F03\ -8A5C7FE58E89774EF2992FD7C63099D352A7D21560B788B405709861817E59A96B3A3A83CBA803B\ -16934331071905BBEC6532900155D8AC88CB32E4E21A3BD3A03FDEC325A51CD2773964E6784FCF1\ -853737AA64EB67564727272661ABF84313A57A44B123C65509CFB7A6F6641CDCC3B57FE628C7B81\ -92DB44FFBF5796A8613B1FA126F6076883C783DC24E2A4464C40B3A41CA70AE87620866CF4FCB2B\ -D204BF5C283812BA056AC0C345E379C4BA24D750901279BB2F3A16F612BFADB35703332C7C136F6\ -8EAB6755C66B6A4AD1AABA7B768A58ACAACC10A459A1CC8EF29377BC200E4D315A30A6BCC3256F9\ -734D06E9779CAA5442A9A16069081377C76E75154368072DC446ED6C8B8E622A21E383CF9BA1FB4\ -34E2ECC81E7B78CEE986B8FF798AB18CF9634543546284EDA2A26B47F05B735BCDB1202220076DC\ -8B4E4B9F853533C8F6C7FF38817BA49712835785F17F14CA01D0C1C1E98810FE0B36E5B427157B9\ -418449CEDD641A4293C85C32700102ACEC22EBAD98ED160A5F027BD4CDA57F1F3720A12C134654D\ -D5E73F829676495390D0E7929D6034E9C55F7D55BA658BC587988E8AF94960F6CFB8D5AF7A00215\ -35A6E25E437D49A780698BE22AC9953949F571B85A685725F8207A2B0AE849B601AB91B159B3DF4\ -A154C2041E776070AFC42969322380917C97510799F3149131477E16663D3174C7C1CAEA788535C\ -6C005A64F2868631B31B66E205FD38C1D84542D0F1B578F58C9BF5A0FAEAB6AB6494893053165EA\ -FD465FC64A0C5F8F3F9003489415899D59A543D8208C54A3166529B53922"}; + // ML-KEM-512 + "80B70100831D7EE168F47392483119F93863ECB0BC605312D35728876B00F5F57AF4C85EDA\ +97281D574390BC7256193668DC98625354AB52B9BCE781C5771CC26099F6FBACBEE1784D1948877\ +31F097C87E082CBEAC57D30B7B9A293872C841466F2244CC65FF4BA653D6751DFA22051D5533699\ +42C31C29F91307AF573292D697A8C31612E07B5335CF08329FD246BF2A32200A8CB0C4B03B9D09C\ +5BA1C3919539E9229C696924348282F696B1525E5603806B4DB618B3DC8630CB286E4311721BC50\ +31F257AA925BF80960445AA8D8E69788E99DA95C1D10CC3BE858528DB0CFEA003C74693780A65A3\ +6E62843B3BE15406543D22D83507C87B2786792C80FA5628454A310394DDA4C2AB59493850257D6\ +D3BC107186D9062707F354E81A1A10FCB763D31A4EC409AA243ED2E59BB189855EB1656266BB375\ +00785EA08CD88C222A8C53A8777CAB42C9C238A00D59369425026E99D2AE6040AF6709029CA8789\ +C897B329FBA748D69C8A7148C95ABB0C71787C58F12F21F2213E389242AA7FBD320C12AC42C6116\ +06CB8C1D1B4625886A145A535BD65BD0D996B330C1657D61A87E90417003225759820A3BBEC505C\ +DAF11193229AAE173CD12BAD22A7A30A76A9FA7636C3D5AA48E1784012A012F14168B7853D2A16F\ +90CA02CC33B2006C08F26C15FCA29612CC792E1CF02E1321A75A810891986667D4148AF36E65E1A\ +592589029617734C315C0E39B7518C8660CDC265D0C813EF20A043317FAE5B8E40546EECF71D6C0\ +54FA66B49401309BEF30FD51A5519755DA9104689B26F0839154C847BEF2365943C0249483AAD9A\ +7367C980A3D1CE46D2008A15275CA3BCA4834E6F9A3036C0CD80BA228D34B9780244D5C0CBE907C\ +6FB43824A9C0746471639CB86188C60C3B253215CC91692BCD1493D6A444D536446E02968138001\ +CC287E0E518F3AA25D8C3B95B3C35C59F4819D484976029AF05A263C35336B261F77B2CDC29389F\ +084C04CBB370C48562B5B50771C0FB816908E198DD6D53F76E48BF042C2B1F82A3A40B8DAF51F46\ +D76FA4BCC9D3C894FF850C0FAA32E0AC33901A4C79139F5F20417EC1A190607044F18BB824CF350\ +C78AB3DDF3C2C86CA5543F715", + "DEE78922BB8DA2F4764DCA45F8EA4C1F530A1C571D3AD1924B589698CB2719E069FD943C14\ +52C5D168B2B357B265831C019CB3557A0BF7187E4D108BF770C74DB40389CC718F3BC11CE3ABA84\ +366AB245194B941F81B7AE702419BB98D73BA003783306C7B3A3677A543A0100C3175E8C020CA26\ +6512909C3550C4F65C0EA3E24A47237D9A4A0B5AE588F983311FAA36E891AF8EA1B308C83179246\ +154C765AC5B5A15456E193308002837D14354E066A34A4409AFBB15085AADC9E22B8DB5583D45B0\ +A4AC72474A2AB94B792E531AB0CB882C13A4139A71FFA3783B537178F34E111B6C3F120A76D4CDC\ +EC461843035ACD285ED627D8BD2B0B997CCCEB4ADAE3615A73BBA0A7C7BB9B13358BB51FF8A574D\ +86B5000272CD270A0A1B24BB917506701C2F441FC5B79DD451CB3CACC740127BD411604BDAC464D\ +A1A2F83918C5B2FB6E5284C972B93357A837828B1132632BB6F7BFBBEC3D947BD403D86990066DB\ +6553722434C7C0E3992F009BB238F7A6B3E5251EDA943A7703FBA289AA2053A857796C2CB945494\ +C0BA791A9E3CBFA800D8988C8121997D975B3D03595ADD64A3EACB8BA36A4D8B3BFDC11B7D56239\ +087C90F352C0EEC40857F089CCFA7C9A683A1DE3CD8FF28B22153DDE231E5F74805D683EB8C346B\ +A16C7FE68064B2059C8738E5AC19B64D4343F5C9D8BF9780302B0676C202A21292CC15FC1589A69\ +838AD1EA3D0C3706F8E1B011F61299A56EC2515051FB94734B308AF3C35E45ABFADC128FE69838A\ +A37080514D6C3748C916BD655080A1035FF1A763E450B56864CC232AFEE53919FF889A820A7A655\ +8631B88F7318C033800F307C19B2D0A8B65882D8770979A5701AC602F71B72A26B82525AA67D77C\ +75EB6871DC019B465583A250DB4704906187E8DFB3B70726988F9C52C12266C6391D4926CB79978\ +007CA46EF60882806FFD59C64ED70333989AAC5186990440B89C3CD1363BE404706DBB63A5A007A\ +0FAC261A0288F916FAF0AA4E944552F10801A3A5DDE263398015CC35227BD1711356251AA935A89\ +BC2E3D2C08E1C9A8C1E4416F303BB73B314858CA4C210C959283FC865B027768C5D6047FD36DBCB\ +C4EDF3EA5CC6A50CB052BCD31", + "F5E24E4E14B6653665CA0289A3728CBBA228FE116726C1251E9992A9F0060934645B262324\ +ACB5C6B57D26E39226E22CF0C33F7FF5A4D979234F2B7949F566DB66C35B273DC9778A64F2BCFE9\ +14C0D81527D418A112579E5D08B1C429587323425D7A78351453457CD868345AFA16218332002C9\ +5D8406C14938C039693D6C1216AFB9983099031109BE0193A1B6E12436103FDD084A7B84380ACC3\ +5817831C0558D4F8082BA58B9174841A840C2964853656C2327F7952132C6DD129DBF5023CE1B3A\ +92F7736FC19528B71D21A27C3D7B7451D5A8FC02A786F75545D2451549BC95DBBB87724F72D2ADF\ +1D619B1B94386C14C37128C2C1C60F4C02B28CC536C508A370BA9A2F4618CF1C64F355684F25A6E\ +E99D3F89CE0136B47D7B26F0E6A60CC94FC4573834172A3EFB84C9FB66401B76C90007E8F7B19B5\ +13292138B79147A364680DBCB211762358CD32A3C44720DF6BA22DC8D3019C0C4803F2A567D9EBC\ +6A5BC012D1F634719891DA1324EAF228379264B3DA955DAA3A2FB8836894C8E80006782141257C2\ +54D905A238A6B41AC3C76CB87EA342728EA6E48BC66816842FF2455E85C67F8C48874F469BDA56F\ +DD83A57DD4076798A3D854CE40BCC6B349A198FC6FA4713C94794946E249201779709AB7510459E\ +2FA325BB3C816B2AF3D9CAF36FA5C217379CFEB797A9080FE23374FA02F047C775CB4602B7859F7\ +D79C0AF73F11B42847915B3D3246E1044031F61BAAD987F3C6CC93280B23C8390E48A2108092C7B\ +419BAE13AE50067813A99B5DA80E58005C6965FFE453AE573501B242124515257C406278C2F7F39\ +4574894445C612E4114F0A60404CDA976FA63B9A285781E0AB3D77AD2B002F1C885EF746610243B\ +751AB4BCEA388027C41063B01679136087364CFDB1392FAABB9E20A5177B94BF5A393B7BDD83A7D\ +82343173B8781B44334484354B7179B225AABEE99F230795D1FB248AA5615E85C0ADB49B7F51047\ +12B86D4034D457975D41B7C88C0664E091E47E9798303C3901583C13606EED7883A537AC0E14706\ +8B8C4AC056FBA108FF1083A9186EC05B338627A8DCE43E5C41410CD6BB35A330D20B77BB3A9034B\ +4E3C443BBEB41B6691F11AB11", + // ML-KEM-768 + "533145987CB33CD2C8F5AC8A73C03A97FB31D2B89D02B1576CFC77BC97656FC040FCC75697\ +50459EE753EBD69839692B375A0F53165B191CA8C6185B85626282C0A4AD63B36B6A289F661D505\ +850832248D6F39084695C028B979835848931874E037EDF33CD9F1521E2B478BF0C37D859572AB0\ +8C20F7687749032949AB7457B66C1206C08A78C58633BA008E8770224700B84758B22B290E9ED01\ +F750439B00B97729960940817D3BA0CE7F10EB6A0C8EBD975C85A6299A6CE486132292189F9DCC1\ +3F275918704192A417E7B305834323C354213195BAD0A5AA30A3980B028A1E116E97E74ED8D053A\ +2FA51E00068BCD69D325246E93A30AD493D28099AF143016BE454413256A5DA144C9985C70664EE\ +12013DF167E228B921EA3BAC494B5D5140581A4D7E7080B4C284A6DAA955366EAE3217541A0B110\ +9313F7A1AE9305D55B45CB6A5B2F3321A10DB137E92306A3B2A25FC1999495F7A732D7CD83BE092\ +3050A5562A036699F92427CB71C0CA201D958F7A3171740AB477188DB276A52E576703493E289C1\ +4BF896D5A827586492D23B605CDC6932A4ABF902A219F88B12D0479C91B4EE6C586A4A2061FC22D\ +66264772359B569456111574D84606CBA28292C37A40B81F5A113BB9E72871E14184270FE2A87C3\ +3BA7D01E95A578950D098C48A584428BAC781BA938F13BB80F4790EC36F1A394FEC97AB80054F60\ +A90DA86ABE7D84799A604233A5A495294D13805B6CF3505DB833E9F223D102AAA9E666580B088E1\ +CBABC4CB52725CB768B5E990B89411AA652E06A2BDB937B185EB924C59AF6BA9BE2BA09409DB5C2\ +62D751731461A89AAC05ADACC320B6AFC5C4A5FDBB2F56B2483D11779C7117707B121D0B36362B2\ +BF8D4B28F6948F5EB1D5E41B1C8A5053D581019C36AC87988803CB934027909DC4C5BD1AE2EF451\ +D9F7945209C0E9E60AF43C50DC98646F3BB13BE6491E91930D9AA1AA315FB3B1A067579565D170C\ +4E888E9042751106B72A60470A69992508E8CE3101A602A22DA7FB1A744F09488E704481F649DAB\ +6158E5306F573009EC63ACF11B549D280033343FC9750BB927B931B94F9C5475A2B803AF36CC3CC\ +30521EA2A86040E03E7CF90B36D2E370856285AE4523367482E68473CA500200F75C8C423C8AB93\ +C7BFE74DF253AF97114A3FEAC1DDD34E06747C6B386990428100A99351BA14A3C19B1A7A6DA5A71\ +5F6A698E9FC330C13B98D61A2A85AC0E0896CC8032490B93FEB284703F21E6D16307D7886F94875\ +2FE55CEE7291C06AA7BBB79146C644AEA7C2765C5EFA535B729158EB51BC2D4C389B970B3008696\ +6D858D51B78EF3829F9290DAF241C6D370425D83DDD61153DD2AC0FD206120434AD6792D60B2F08\ +4A2950AAC250B4001F309EA45B09D9DB440D6A2C9BB3B140569C51C985A2B0BE03ABA918C2311B1\ +1069FC9A0C762CCA59C1BDAE47C0406AF0CC7BBB1821C0F8733563ABBE896525E1156F7D593F55C\ +39922B6B79E462CE587189247FA045CB19FA7256B960D0B25B7B364ECE250D43E19313C798CE424\ +634DC358A0914FAF33EA2B06EAA748947C6C150E54D7BD3A4C4873B117266145833FF04CAA96424\ +AB678B49BA94D6619F01BBC62961850CF25765C7627910EF8E79F9B3749086AABF75407D7AC4274\ +8BC", + "06F51174F03C2FE07CC31B0659B87EBF124237811B88B980BC277F8C050B265CBEE1A4AE71\ +45CB9253281BBC291F2808E065855FD91C7D14122C589FB21B45FD3B7FBB6562FD53006B565189E\ +C983C7A0D4C21596EF3795AE22ECAD71F75395558B55220662BB66C389ED9AB6B784476E1788F34\ +B28B59A4C6F71F9F6A49DA80C4D3107DB2C306968B5600E18285F8BFA293677F699FD2D2820DE49\ +0F530818D6667686A765FCC0009484D71629C1F148104B462325AC55EF34DD5C7098441A06757CA\ +35C8ADFDAB6D36333310241F9970B1B123478DCBB75AE6CA39BB84FFCB23A593C24BC54E74B4086\ +165BB4B10AE39F45447AA4EA5F55762386B11051B84B0A688C12C73336FC87164B7FBC7F0B07D2A\ +51BB05560606D5558666CC322963AD3CA2BC1293260A94707770C030B2BC9C00477A8D5FF673796\ +1480D48109F66075DA9C8AB516F70A78DA9E444AB65798A2565965A68AD9146FD9267D2A80C4352\ +A0A988157522046620A63D9BA7BBCCAFD50A61384453F8545845B25E7A05745C4B26EF7211200A9\ +16241047FDABB66936BB7351C04F5CD06A10AE3C459B74BB0CD85044BF8B6BF2B33294014B9D685\ +17CB1A9813230BA08813807A2DFCC6A739B6AC79575F19BAB96A7CDED404D0E52508214AD43763A\ +0A048FC36785B2C718F75B3432769C1D2A6240336A82B39D865739AF78E94A92BD7B4703210297F\ +B82E0BE57B97384DB5B24FFA5486C982AF48642D967222A28C6F83E5AD6A59CA486733808BA3BD8\ +6A780E59888011965A351CA949B0D6C72FB3BA0F867834D166819C252D9600207C88997318B2D20\ +4AC3619247A01829484F12BCA2E8F16AAC677C9E8AC209F9BCCF019BBDA66E8F073DFBD934E08CA\ +15BE77576029654E049C1C20B1B123E5F0B50135628CD2C96A5D0B1EEF48FBE08AC4685247721B1\ +28F71DC748452B94A458F39B337BC2305CCC505BB18BF6ABE3EC2C825799B95C13A1F6411CD3B03\ +1F3CEC3D99AFC1A28F2019C1BD129A2EA35F06415C8B717337957CAA964E794881257073FF5C12C\ +3C62034861C343B7F70B9D475CCC10EA5889910E04CA7EAF0B762DB56962EC40CA47CEB4D228600\ +595CF22421148CF02B4CFCE76AD27701F925C01C71C5405534ED54B0100C280DD861D89E967BED4\ +829C568BB76CA500342803835F7983179CDA15899033F797951031138A83669AB4CCB4630058088\ +AA0845FAF7B0761B405AE866C426711EB152889D175E7B20DA03126B7419A766416A68AAC0FBC35\ +5DA07D6E6339BC0539CEB55711F633B8C7392627497821CB9D7174C4E655B5928BF722C84B8233A\ +0993B6DE02D7364443EA4C73A754B8190243DF936184819E1B8AB6F0B0BFBAC6C47E66DDF11757B\ +E55E0787ADC112C63E644D1B904877764D856ABE78B583600CBB2119CB916C689D4543F4D553CAC\ +33AD19B245B4948EF0BA3E7D1151179B9FB2941F3674E5F8771677737C435B2383119A3E7543411\ +4439506E1B9145FF16B1458879A1039962434151619B77915D033A3FAB7385FE861E4A25B125A20\ +5C3F1B16972470B2791534B5FB8731B20C03684CCBEB97A1FA4417655BB485C347519710522C357\ +D50C43FC2644098533FE549C825F5DC8CA82A0DD908891BB4F92EAAB51CBE036CD6FB59A749269A\ +0A3", + "0F6512622B9E8923C5FFBCAAC1401FB3F50D8B0C561AC1BB175634DA089374308CEB287074\ +44B126E6438C4270CD735AED70CD0BDC6B975C480F6C5C5436C263BB604B33B750827792A95BA3A\ +79CA3D9B8174C1BE945AB2BC86580A6778CD11471ABAEF93607B56C887CB12BAA5B3C9A264386C3\ +712EB80F596274192465F18B4862F9A1C666BA71939EDFD67BBF94B35D663D60501308A03B11E47\ +C50A979BB81A2D1310354911AD830691AB5126352418736C76DC7ACB304277806466B4116E1F13E\ +319C4B82E4ABD6C23161458BF0A9C4D3CC3C22F513E6B759C4C73E046055C666518D35BA2BFAC25\ +53B45D2E75BD0916DCD146803F2B9D904C33BD4A2F10AA0AE6230AF55BD985955BC742BACF81387\ +153D0E9C39759707AA4A5FFE0C6655931ED5CB25BE896F2DD74E6F4055C4A4714D084420800FC0B\ +613AD51ACA78B210F062102D88BE45CC56BEC037916A375525C3AE4AF54681C7A90942C8249E8A0\ +5F4CA0673CD92C4767B2F26A68C53A0AEDE9C488547FD9B90355F641EB4B359CBA25F9654F9A67B\ +CF5B6CFDAB4A637636AEC1ABACDC7C7FE0C1D187172E1F2A1E7B5193B6831ED51BECAB244D62A72\ +A5AB022A331992941AEA849CC661018F4A8CE01A4725F4BECDF225983A2404A24CD6A44B0E7156E\ +6A96702D2736ED790908516FB555D2E31B966E2660CB1C766831C583C153F81A6758B0BE4820437\ +7B343E821F2C032BE18314AD24C110DB1656CB8452CC85C4E44879DC61BB083BFCD44A5A304A66C\ +992FB7BBCCD0A83A10943B0A4B8D5CC17C30433EA842F942062ACA3690806B43D6B80590B6088EA\ +81CDD36E9C40839D90AF4DEBC50CA06B716BBE4A732305DC5510A55F8E385509EB1532770775523\ +1C4733A8EB9CE80D395A7613E8627A206A9A9CF57B388A780CEEBC55EB549D4338695355F6B1C98\ +0BD71F2D40CF710C20B468412EC65C3F48799DB74453108C26C609A6E0643D104B65BAA6C0E416E\ +0102D8D261C12E40C3A02A08EEC44C90B99028774C66663A8E5470C715514B4BB4BA2A5C71B424A\ +9929E893248B66B6FCF97646691180254DAF9490BCE53E88057554B15C7D7B8358FA2879112E761\ +A030FF02EFBDCA46E5808A9B75D0A69C4AFB609BA94698181710606885C176232C92AAAE283FCE1\ +520414552A90ACAD9421E4D87EA4171E28B8260A3061DCC50EFFD48B60DB28EE501D33732A82635\ +40F33B9803549D1D936B258863BCA134B156C6D4285B763BD52D807FD7425AFC5334E5961800807\ +9034138EF057246B3A10BBA27117850124BE41353791B67F3B5A5DAE0C9446925A8D4936723982A\ +B43399298026EC9129404031478A148C7290FB100A999BE95582326D35E06294C2AFC531083942B\ +C0B91759B9B53B920F164A53C22D279747107B62A15703798CA4702B5B4EE323424C4DC8FB1E2A7\ +5B21791A8F5C878BDA55657C8ACA47A14C082384A62CF88E483F071063AE33931D8627EBA8A08A1\ +6B08B72DE6F7AB453917CD9145FA4B4FA34AB1A601C4B09136AB91734DEA5CD21C657393857B84A\ +B6CE5693D0A0D8DA853224B301AACA554464450C08187FAA12F9925A0E222D596AB0767A6352B96\ +1CBA921F0A8C03E4AB0118D65330DB1FC759D3204C7E89A3D5BA296A717BDFF283B2F5B17334A36\ +C6E", + // ML-KEM-768 + "533145987CB33CD2C8F5AC8A73C03A97FB31D2B89D02B1576CFC77BC97656FC040FCC75697\ +50459EE753EBD69839692B375A0F53165B191CA8C6185B85626282C0A4AD63B36B6A289F661D505\ +850832248D6F39084695C028B979835848931874E037EDF33CD9F1521E2B478BF0C37D859572AB0\ +8C20F7687749032949AB7457B66C1206C08A78C58633BA008E8770224700B84758B22B290E9ED01\ +F750439B00B97729960940817D3BA0CE7F10EB6A0C8EBD975C85A6299A6CE486132292189F9DCC1\ +3F275918704192A417E7B305834323C354213195BAD0A5AA30A3980B028A1E116E97E74ED8D053A\ +2FA51E00068BCD69D325246E93A30AD493D28099AF143016BE454413256A5DA144C9985C70664EE\ +12013DF167E228B921EA3BAC494B5D5140581A4D7E7080B4C284A6DAA955366EAE3217541A0B110\ +9313F7A1AE9305D55B45CB6A5B2F3321A10DB137E92306A3B2A25FC1999495F7A732D7CD83BE092\ +3050A5562A036699F92427CB71C0CA201D958F7A3171740AB477188DB276A52E576703493E289C1\ +4BF896D5A827586492D23B605CDC6932A4ABF902A219F88B12D0479C91B4EE6C586A4A2061FC22D\ +66264772359B569456111574D84606CBA28292C37A40B81F5A113BB9E72871E14184270FE2A87C3\ +3BA7D01E95A578950D098C48A584428BAC781BA938F13BB80F4790EC36F1A394FEC97AB80054F60\ +A90DA86ABE7D84799A604233A5A495294D13805B6CF3505DB833E9F223D102AAA9E666580B088E1\ +CBABC4CB52725CB768B5E990B89411AA652E06A2BDB937B185EB924C59AF6BA9BE2BA09409DB5C2\ +62D751731461A89AAC05ADACC320B6AFC5C4A5FDBB2F56B2483D11779C7117707B121D0B36362B2\ +BF8D4B28F6948F5EB1D5E41B1C8A5053D581019C36AC87988803CB934027909DC4C5BD1AE2EF451\ +D9F7945209C0E9E60AF43C50DC98646F3BB13BE6491E91930D9AA1AA315FB3B1A067579565D170C\ +4E888E9042751106B72A60470A69992508E8CE3101A602A22DA7FB1A744F09488E704481F649DAB\ +6158E5306F573009EC63ACF11B549D280033343FC9750BB927B931B94F9C5475A2B803AF36CC3CC\ +30521EA2A86040E03E7CF90B36D2E370856285AE4523367482E68473CA500200F75C8C423C8AB93\ +C7BFE74DF253AF97114A3FEAC1DDD34E06747C6B386990428100A99351BA14A3C19B1A7A6DA5A71\ +5F6A698E9FC330C13B98D61A2A85AC0E0896CC8032490B93FEB284703F21E6D16307D7886F94875\ +2FE55CEE7291C06AA7BBB79146C644AEA7C2765C5EFA535B729158EB51BC2D4C389B970B3008696\ +6D858D51B78EF3829F9290DAF241C6D370425D83DDD61153DD2AC0FD206120434AD6792D60B2F08\ +4A2950AAC250B4001F309EA45B09D9DB440D6A2C9BB3B140569C51C985A2B0BE03ABA918C2311B1\ +1069FC9A0C762CCA59C1BDAE47C0406AF0CC7BBB1821C0F8733563ABBE896525E1156F7D593F55C\ +39922B6B79E462CE587189247FA045CB19FA7256B960D0B25B7B364ECE250D43E19313C798CE424\ +634DC358A0914FAF33EA2B06EAA748947C6C150E54D7BD3A4C4873B117266145833FF04CAA96424\ +AB678B49BA94D6619F01BBC62961850CF25765C7627910EF8E79F9B3749086AABF75407D7AC4274\ +8BC", + "06F51174F03C2FE07CC31B0659B87EBF124237811B88B980BC277F8C050B265CBEE1A4AE71\ +45CB9253281BBC291F2808E065855FD91C7D14122C589FB21B45FD3B7FBB6562FD53006B565189E\ +C983C7A0D4C21596EF3795AE22ECAD71F75395558B55220662BB66C389ED9AB6B784476E1788F34\ +B28B59A4C6F71F9F6A49DA80C4D3107DB2C306968B5600E18285F8BFA293677F699FD2D2820DE49\ +0F530818D6667686A765FCC0009484D71629C1F148104B462325AC55EF34DD5C7098441A06757CA\ +35C8ADFDAB6D36333310241F9970B1B123478DCBB75AE6CA39BB84FFCB23A593C24BC54E74B4086\ +165BB4B10AE39F45447AA4EA5F55762386B11051B84B0A688C12C73336FC87164B7FBC7F0B07D2A\ +51BB05560606D5558666CC322963AD3CA2BC1293260A94707770C030B2BC9C00477A8D5FF673796\ +1480D48109F66075DA9C8AB516F70A78DA9E444AB65798A2565965A68AD9146FD9267D2A80C4352\ +A0A988157522046620A63D9BA7BBCCAFD50A61384453F8545845B25E7A05745C4B26EF7211200A9\ +16241047FDABB66936BB7351C04F5CD06A10AE3C459B74BB0CD85044BF8B6BF2B33294014B9D685\ +17CB1A9813230BA08813807A2DFCC6A739B6AC79575F19BAB96A7CDED404D0E52508214AD43763A\ +0A048FC36785B2C718F75B3432769C1D2A6240336A82B39D865739AF78E94A92BD7B4703210297F\ +B82E0BE57B97384DB5B24FFA5486C982AF48642D967222A28C6F83E5AD6A59CA486733808BA3BD8\ +6A780E59888011965A351CA949B0D6C72FB3BA0F867834D166819C252D9600207C88997318B2D20\ +4AC3619247A01829484F12BCA2E8F16AAC677C9E8AC209F9BCCF019BBDA66E8F073DFBD934E08CA\ +15BE77576029654E049C1C20B1B123E5F0B50135628CD2C96A5D0B1EEF48FBE08AC4685247721B1\ +28F71DC748452B94A458F39B337BC2305CCC505BB18BF6ABE3EC2C825799B95C13A1F6411CD3B03\ +1F3CEC3D99AFC1A28F2019C1BD129A2EA35F06415C8B717337957CAA964E794881257073FF5C12C\ +3C62034861C343B7F70B9D475CCC10EA5889910E04CA7EAF0B762DB56962EC40CA47CEB4D228600\ +595CF22421148CF02B4CFCE76AD27701F925C01C71C5405534ED54B0100C280DD861D89E967BED4\ +829C568BB76CA500342803835F7983179CDA15899033F797951031138A83669AB4CCB4630058088\ +AA0845FAF7B0761B405AE866C426711EB152889D175E7B20DA03126B7419A766416A68AAC0FBC35\ +5DA07D6E6339BC0539CEB55711F633B8C7392627497821CB9D7174C4E655B5928BF722C84B8233A\ +0993B6DE02D7364443EA4C73A754B8190243DF936184819E1B8AB6F0B0BFBAC6C47E66DDF11757B\ +E55E0787ADC112C63E644D1B904877764D856ABE78B583600CBB2119CB916C689D4543F4D553CAC\ +33AD19B245B4948EF0BA3E7D1151179B9FB2941F3674E5F8771677737C435B2383119A3E7543411\ +4439506E1B9145FF16B1458879A1039962434151619B77915D033A3FAB7385FE861E4A25B125A20\ +5C3F1B16972470B2791534B5FB8731B20C03684CCBEB97A1FA4417655BB485C347519710522C357\ +D50C43FC2644098533FE549C825F5DC8CA82A0DD908891BB4F92EAAB51CBE036CD6FB59A749269A\ +0A3", + "0F6512622B9E8923C5FFBCAAC1401FB3F50D8B0C561AC1BB175634DA089374308CEB287074\ +44B126E6438C4270CD735AED70CD0BDC6B975C480F6C5C5436C263BB604B33B750827792A95BA3A\ +79CA3D9B8174C1BE945AB2BC86580A6778CD11471ABAEF93607B56C887CB12BAA5B3C9A264386C3\ +712EB80F596274192465F18B4862F9A1C666BA71939EDFD67BBF94B35D663D60501308A03B11E47\ +C50A979BB81A2D1310354911AD830691AB5126352418736C76DC7ACB304277806466B4116E1F13E\ +319C4B82E4ABD6C23161458BF0A9C4D3CC3C22F513E6B759C4C73E046055C666518D35BA2BFAC25\ +53B45D2E75BD0916DCD146803F2B9D904C33BD4A2F10AA0AE6230AF55BD985955BC742BACF81387\ +153D0E9C39759707AA4A5FFE0C6655931ED5CB25BE896F2DD74E6F4055C4A4714D084420800FC0B\ +613AD51ACA78B210F062102D88BE45CC56BEC037916A375525C3AE4AF54681C7A90942C8249E8A0\ +5F4CA0673CD92C4767B2F26A68C53A0AEDE9C488547FD9B90355F641EB4B359CBA25F9654F9A67B\ +CF5B6CFDAB4A637636AEC1ABACDC7C7FE0C1D187172E1F2A1E7B5193B6831ED51BECAB244D62A72\ +A5AB022A331992941AEA849CC661018F4A8CE01A4725F4BECDF225983A2404A24CD6A44B0E7156E\ +6A96702D2736ED790908516FB555D2E31B966E2660CB1C766831C583C153F81A6758B0BE4820437\ +7B343E821F2C032BE18314AD24C110DB1656CB8452CC85C4E44879DC61BB083BFCD44A5A304A66C\ +992FB7BBCCD0A83A10943B0A4B8D5CC17C30433EA842F942062ACA3690806B43D6B80590B6088EA\ +81CDD36E9C40839D90AF4DEBC50CA06B716BBE4A732305DC5510A55F8E385509EB1532770775523\ +1C4733A8EB9CE80D395A7613E8627A206A9A9CF57B388A780CEEBC55EB549D4338695355F6B1C98\ +0BD71F2D40CF710C20B468412EC65C3F48799DB74453108C26C609A6E0643D104B65BAA6C0E416E\ +0102D8D261C12E40C3A02A08EEC44C90B99028774C66663A8E5470C715514B4BB4BA2A5C71B424A\ +9929E893248B66B6FCF97646691180254DAF9490BCE53E88057554B15C7D7B8358FA2879112E761\ +A030FF02EFBDCA46E5808A9B75D0A69C4AFB609BA94698181710606885C176232C92AAAE283FCE1\ +520414552A90ACAD9421E4D87EA4171E28B8260A3061DCC50EFFD48B60DB28EE501D33732A82635\ +40F33B9803549D1D936B258863BCA134B156C6D4285B763BD52D807FD7425AFC5334E5961800807\ +9034138EF057246B3A10BBA27117850124BE41353791B67F3B5A5DAE0C9446925A8D4936723982A\ +B43399298026EC9129404031478A148C7290FB100A999BE95582326D35E06294C2AFC531083942B\ +C0B91759B9B53B920F164A53C22D279747107B62A15703798CA4702B5B4EE323424C4DC8FB1E2A7\ +5B21791A8F5C878BDA55657C8ACA47A14C082384A62CF88E483F071063AE33931D8627EBA8A08A1\ +6B08B72DE6F7AB453917CD9145FA4B4FA34AB1A601C4B09136AB91734DEA5CD21C657393857B84A\ +B6CE5693D0A0D8DA853224B301AACA554464450C08187FAA12F9925A0E222D596AB0767A6352B96\ +1CBA921F0A8C03E4AB0118D65330DB1FC759D3204C7E89A3D5BA296A717BDFF283B2F5B17334A36\ +C6E", + // ML-KEM-1024 + "E2F26491D9370C69C5866B0AA4E5951B2C9602C74B7AE4C27436B130F209DD4915ABBC14F0\ +C154A67369C8504461595310B43BDC10A577F35EDDC16154F587BAA0C37F663739C8AFF34533C56\ +947E4A637155619AD471162E9BFD6D18AB91B6F639B231865840A032E2B617E9A307301D0C27D97\ +7C4A2C7D5E1006FA15329D550E1E27B116A400084BAC35E03698F2035BFB249DCC5224FC3C3B783\ +4B0B0BC7C09B6D48A3AE649CB3B95A131479E609715357A30CBB0C19781A9BB819D55E4385AE7CA\ +53B58CE699084DD96CE2361F47E97E82401F845909BB67707F8B876324BA3C35C712E313D476591\ +47BCDA125349E7767396492E6CA09B3DB2AE2F035769C8F200B4874435098774AFA97B6D60164B7\ +97665428850EF70B51A65924865DCBC4243B9CBD6CC07489772F8F64260BD666EFA2768F3800D82\ +81A4C97B1E3AC8382A62F4C24B65A17322B75C7A63B74724C1DFBBAB7C9B532AE44B020E675412C\ +768210793FE464D8AAC738780281710AFE3BA5EE1A7E4F15458DC27D0EC3B3EE8B41065456BC757\ +67F713BFDCA6222543619C705474C922025351334C71A595F38B31427B40980571A6804A1974B3F\ +C21B6EA52BC074187576A3B062C3712DD69D99683BE6800A1196739FC32E52606B8CC4CB10838AF\ +8733B3F638D03C3423DA7CD5BA971B66C8FA3EA6B60D5B04AE14E7F8C4A66C01BEFDB4520E62138\ +D76667595CE06828BFE31735D73D2228AD88F02545155C85435E4D62264C665B05503E93A7881F1\ +8AC11FA12B293056B695AD275BA41C45ADEDB34D2BCCF8E2C715417A41994270F52C155936363A8\ +0850BA70B2EC53404B7470CB3FDA8B117B138B81B195A51A72ACF50A1CA07F59E420F41B5618203\ +36827415C27B093794124C38B68709E7C2B5C8A11ABCEE6C7A6096EE2545E0F58594AB57AA86CCC\ +3AE33B94E4BA475403471549253896404715E110933290ABEE2C03E301BDBA737D280079362C8FE\ +30143F5171C4349042B421CD5A1565824C21E6A4694F92EDA35A178383ACD854597308A2DC68290\ +B56006DC4C2B6BCB6184835771950B6A590A3B0888578DD9E1135F857FB836A6373C914A429E9BF\ +62A5DC855B954A8B8E606187425E6922DFD975477D32479F0B226F7BD0D0952A6C7AD07D31E4F8B\ +803BB5B3A8071F98895A0773C40D902CCB4B6A6AF24E550A2BF547BF03C00A7236AC7FA82CD31AC\ +7D4A8212DB1AE417006BBF73FE3FA9C155557A449C51EB56C60824105A33EE6E175A51191F1C440\ +F711CB670994D3FBA08AE608BA598FC39B80338C96E25B4FF41B945C56C17BAA946A18AE275288F\ +51571B0F34D67A74127957F0DD979E362B5AD7AB53E5C100D422A0C1400A0AC5ACCA081A07C195B\ +75139477BEBC313DD0E76ACDE0AB1186C18F3AA52D87A2F70C1A6673AC7E1A6DB24B52D2AA1C961\ +78B75DB0AD53AA9DB8A09FFD77D8AB6447EC1429AC85D1BFC361E1BA35A10715A1153434B3E5D07\ +0C1BC7A72A4B7D54521213D429D0D30668037E8B2465B03C7EA170B0428AAF2E0A2A26EB432DB45\ +FC642A20AE06D8A39282BB9246743A77BBB12ED43648FE06236F3B1805C5B0373760DCC5225424A\ +D3E38971671E8E083B922A52E300225171147CEB7F9E9A1B6D155F6987950C62B9456C7E3178CC5\ +B9022A25B25A42C057CD05876936602947467C88255A848EE048256AC2FF7D56E4A250F9CD476E9\ +91449FAA568E8B432901B394CB6EC54836E62C38CD2B3C62D732EE7812DC987A6E8CC5E3D60D4C8\ +56B39B703E7AC2F799A2918DBB343F79C0AE7787438692E780B6444C2B5D8BE2AC06157B65101F7\ +7DF8905BC19915A9D2548A096E79999B45773CDFE18F2AF6461DF2AC82A92F241C450886569C03C\ +9713A457784AFDD0A7B24DB43D3565B25A57E0F766C6CDAC4778A8B5F7074260394E608000EFBB2\ +6DA17282E908921AB37019B019CB16593B9F9296735DB96123B4A3196CBD9A5596D2E6155BB357F\ +1355DE4159076B8611CF07851331C55C835F33967DB045D855B5CC9243E1D16BEF176B9F20165F0\ +A1C073BC8427132618F86C3D731F8A3736AEEB7AA537624A56296273C3C057C1F0213E912A870D6\ +72F84FA193DCC520A514A2900C4C075C9CE0125E11A69ED86024C423B068B529E4BA2D7234C72BD\ +4A09ABB09E4DD7F3C4789027DE5891D7108547F31B006276DD01180C1CFA", + "CC8196E5F1B1BA054644D0B27D952BF3E7AED0D611CB428641432DA8601AAC66ACB6FC3BD5\ +907D2EF7CEB1344A17E656B46558ED53A993472BD5976994356803767F656CC550E04E3F4A256D9\ +4244CD7C8F881233F31C54A805696E5BCB4380BFEF6442A06A98789A54D38B25EB7088145A6A781\ +1D3A083DB4BA245F851D9357B48216B9F3C9CBFE610088F70CB3A018465B7FAC4744975729C4703\ +AA5189B1F88C284E258FAE81EF93C3F41C5B3141CBC1E5432DF767B471BA378B95C2EA717424594\ +1E9227250AA8027B810D8290229742CFD284C137183F6950E372A4B8B03CE8C89B9C471203542ED\ +360474DD663F0A0BA9D804D8C339753AC5B2D2B8EDF33BBA96649F7336A42732917C902723A7B68\ +10658B95BEB31540555600C0B0BBEC1823A273A405C6070990BB80F66ADB58BC1B502603E91B6AD\ +A6AF4780A65D49BC9655EC0B2A919AA2C98C11AA72A0FFA50742CA4907357335C897EDCF25006B8\ +CCB580041FE0061BD2160AD1B42B2A10E2E98E745294D333B6FD5159DE66557096B4BA3A96019B1\ +8D6EAA92A0B6589F579F0998053B8C639A0134241A56DE420FBB82F99B1B3A5292D83BB83396A0E\ +9C5B2CF97145670C6F34DA6E9C0CA3C0C51B20B561C1B85A1F42B7AF8320D3196D18F3A353A942E\ +C676E9DA68B23638FFAF80FFDD55F87885F73C76256358787945217F56634217C91731DBB1382ED\ +765452CA80133A2952B3155165BF26E2550435644D8628EFA974E45B1EEC12CE14C54E76826538C\ +610D76662B6B0251A12CD5B3004610A12B8276A84CA76AECC9E14E524F05B75D445920647C33235\ +8CD779ABF3F97AE54963D8A235EAF0AC94C99FC322A7650890B904B91385CDB4B716F6067ABB353\ +BE5557FC54461A74C415F81ABEFA227004768846192D5E832C8284763285BAE3A1FE0C3C94488A4\ +FA932465E1C3CC6A5A7F6B780FAB431B078E226A237518874747605090B5F3C83B24FA84F555954\ +0C0969C00D0B370A6C1F51E3C4038B401C93FF46BECAB9AD9408DE62A3486E3BAC30A0D3D4B2108\ +2B1123110B196BB294F6509BFC698F520C5D427036AA8D3598B9DAD641ABF8AAFD2574AB741B149\ +03D693851DB705309DBB9C21855FDEB35DA3078AA51629E9537771C877A5C914CB05D8E0633539A\ +CF93ECC0018C4E6AC40BB4C959BFF0450CEB97E24838A9DCBD8037B0047C8EAFAA4483AA3573EA8\ +1E56C2A21D17B302095D14CBFD9C0490F68857C90780C2A1294E08CED2B9CF3BA47D025B99F1C1C\ +E37C4B470529462CA1B1F5547AE01D44400D30B2A4809984E4B53519E604A4086A62CA6BC21C3F2\ +3631D4E188614E72F5E50B976BB7B8320B897433E9D05BEA780280E547DF5537863A761575C8179\ +C49025811578D55ADAE48B88F7A975DC4FB0B4B9C46C020F02303B68987816B2B0792380AC04C8A\ +411A2B226EE91C4B1A45177A83A3AA633252B410F60C7C532C783F15891F51E9DD319CD6C4A5995\ +944BC0695A160F2979C967017598957A2463BC7C943A2D852E410148F32C8C88054900AB0C1DC82\ +F8A316EEDB966078A72E3537B5D969A3F26B93FA3927F774681413E3DE47EF9A5C1F581C2FE4034\ +5A3B783F98CDB9926DF7E93A0EEC4B3201733D1607E5E67366C1CB08DBB1E5AA6DEE3231F150627\ +76C1174C722ABEC857E23A8B21C559FF915E1D67B56AB52E2290276AA5577557EDD5731F0C0A52D\ +2806756CC1FACA5A26F38ED656482A1733226237D4CC910FFA275E77CE60F6637B7C7C4B2921FD5\ +3778383C7C50494F3435310A36D75C75A8404237CC05CC0F96F20BA333690029DA033175A16BB59\ +473E913EB9974A033A01D29AA46BF9667E87A98B05809FA8471827C2C88B873A29A3776A7A51911\ +B291C02D1C1C2F6DA5915C11A181518F32334215796A350306E1BA29EC5CFFDA5C312149523D0A8\ +7D5B5D6B678C11E6C7DD354E51558BD779A814D77BEF6C9DA50412DDA32CA2A7A337B87124562C0\ +F2C81B652735EEB491D155A9777CC7F4C4884ECC29106587DB923A8E50428748547D391E2F282CC\ +4039ECFC5DC902265247381CA73BF948A77916A62AB347C4200CDAF62C30F3AB8036441343A903E\ +6128E1A2803561176F3AE0D3050B0FCBBEF041DEFC72A9A43AB8CF918B8952EB9433CEDF82D01D9\ +F00E44E9B7FA173E2DD8B12BEE781BED3E220007DFD751280B76563610C3", + "9945C4E2DB5B86E311B3450249742A0FCA203D514B68B7898E2599B095123370A302934C27\ +F79C169565F4267BCEEBC67F39CC5881807D68A3EC61A07B3081B2069BDEB27402430AAAB193619\ +C8562D486B21AC8CDF1C571F4CEC0CC991A99058EA3C6007A8A118A385F86A9A8C811A952CAAA5C\ +5B78CC76D553B39C518415EA568AE5AB26353163D94EFCF9005A045269E50EC0C2006BF15896308\ +77AD66B623B52AE4924C8716E32C6833BA65BDE5A86CE4ACDBF3721C7908A32E09981674B446B2B\ +1C2AB9B637B8105C143B29B85E55BB7A36A03DE3395765866EA65BC0E4960088B6D617903CBC14A\ +C12CCEDF8305F0622F83A848F9313F53C504FD8B6EABA4D8420C5B1400224D165A5BA521955CF93\ +C22FD358C88D385C9B349410B50115ABC22BB83010DB0A2A6B227E986E9EE0ABC7C471A719A7EBC\ +7B84D011053BB42538662F7249DF53B422146016997AEFC43398118A82585AF1E700B65198FEEAA\ +2C001A3AD9372F4C9A12A3C3525AE2C38256661229CB567A0C2AB214702CC7FDE1785A41597E496\ +9100BC2153BC7EA153582225EC109AFE2BA851E926BBFA3103DF4A2E72A1AD732365A697E93F900\ +38296DE5925C719423C413C33553AFD8105BC9C7CDAB690544EA5700ECC2F592C4063085C2375F0\ +CC9BB3A5BB057E243DA632AFAB9916AC78DD45ACB5204368E47B20313475253B0A2C152809734E0\ +9ABCABB6934041CA3A8B5A03FCBB29116D4E456E89A0769BEA053E9A888261145D0911E042724A4\ +1B35D154F3A266E9A389783804F4E239F80868C1EC459A2F2C8F5E44EA240B2CEBA3DA2DA93B1A6\ +711DE01009A67E14985416C48830BB56CA6371EA007F87BA3177F558E3383798579F1F873769C05\ +3BFA8CB6FC4C53030839B1343D2C367E2F422BC1C7C00EC392F94C17D4524CD98B071B09693A73B\ +2DC909C8AB26F4A12A8C46C1FDB11A9D6428930351874BB49B919E7D245AA2F14EF183B47917B39\ +FC6B3F8C664A217A11BB1C256D896F5FA68F6250029D49D797163DB011F5067A1C4158A71F8C52A\ +02C4BBFC67621B4A1CA8914D673E25B0C587D1887C638C438459B141849CA906D0B363484A7A1E5\ +778DE74659F05A327470E960948FEB01F66DA1442E1516CFAA42D6BBD5FB6C2F5EB49E50CB7A0D3\ +1462013F65571E6DEB53FA65890D394474D33E1C0B022FF4129E8671AE275B6492886FA94E02401\ +7211BBE60638124A76E9F49234E210380B46B3D686A24713E4F9C47D82BC4501084CC3932DCA5BC\ +1AD02C5426272DB0880443726C4193C2337119F66112C1997E97C6D602562412C9C3A23C0723118\ +F7A4E1383A91A4B7151A0454007066532440E93CD76C6B24163406AD276A9E693F085ACE935CEB3\ +DBA7A3E49F66615D05D47A4AC12972E8BCDEE754BAA0C7652612745A5889518062F46FD00086AEE\ +62731E5557A631D7D19A420398F2E66A08179949F2A9CD7325289252FA714C9FD3CCBB3AC8BC2C5\ +31CB677845749E6BC911CE416708760E8F281F69231BA0893F10A4B4D7AB8FF78387F2DB6D66A9A\ +0F324A1073738553C901D8C3BDE6C7E704159B7F0949210BCC35BCD8E7C1CE92AC8B50564BAE5AF\ +6982174789CDA0F9CFFEE1A3F9C36DF035122642CEEA535CD860C4634B981DD2CBD3B960A587891\ +9ABB9893A2837A0A59AFA98D5D858FF9937FE46248D8003BA1CBF6AAA0BA39876EDEB36FAC726F4\ +052155A85C006389550CCF4BDC20C2363A9D5726EE58806AA878FE7B2F1488953E500013A96441F\ +643DF095195C844487C37B05B70AFAC550A67CEB69659E38A19DD02716CD42406369CDF75C60563\ +27ABA4CCEFF301CFC2290A7458593B599D4549AAABC4973C735AA94F308002CF10B4AFC84B9F445\ +E1A127852DB05ACA68B8CD850EC768A8BC0CF62560246643BDFC08698C3BCB1F1A5771569F4BA95\ +1746845043781CE969B775B08F997DC37AC866C13ACB153957F47BE0338B286717C348455D85424\ +F93CBD4329EEC94A533539A7BA06103FB7079739FE0E08BF8CC4F7D2BBA6A89B100E219EB7C5899\ +E94FDC2CAA385CCFE9E0703AB87317C5C57D2C5DE31722BA1841D7B204FDCB6D66180B43CBB7D94\ +B91D6F48EB478A95EDC71D371B55ACB1616C220965B4BF2B907420B4B4663374DC682E1188A4119\ +33B533F8692AB637028C5D029DCB7A310A3BD6377BB6FE262D26CD38474C"}; + /* Label contribution from B */ const char *strLB1[] = { - "0202030405060708090A0B0C0D0E0F10", - "1202030405060708090A0B0C0D0E0F100202030405060708", - "2202030405060708090A0B0C0D0E0F100202030405060709", - "3202030405060708090A0B0C0D0E0F100202030405060708090A0B0C0D0E0F10", - "10202030405060708090A0B0C0D0E0F1", - "21202030405060708090A0B0C0D0E0F10020203040506070", - "33202030405060708090A0B0C0D0E0F100202030405060708090A0B0C0D0E0F1"}; + "202030405060708090A0B0C0D0E0F10C02030405060708090A0B0C0D0E0F10C8", + "202030405060708090A0B0C0D0E0F10D02030405060708090A0B0C0D0E0F10D9", + "0202030405060708090A0B0C0D0E0F18202030405060708090A0B0C0D0E0F18A", + "0202030405060708090A0B0C0D0E0F14202030405060708090A0B0C0D0E0F14B", + "202030405060708090A0B0C0D0E0F100202030405060708E020304050607080C", + "202030405060708090A0B0C0D0E0F100202030405060708F020304050607080D", + "202030405060708090A0B0C0D0E0F100202030405060709F02030405060708090A0B0C0D0E0F100202030405060709FE", + "202030405060708090A0B0C0D0E0F100202030405060708090A0B0C0D0E0F10F02030405060708090A0B0C0D0E0F100F", + "1202030405060708090A0B0C0D0E0F10020203040506070A202030405060708090A0B0C0D0E0F10020203040506070A0", + "3202030405060708090A0B0C0D0E0F100202030405060708090A0B0C0D0E0F19202030405060708090A0B0C0D0E0F101", + "1202030405060708090A0B0C0D0E0F10020203040506070F202030405060708090A0B0C0D0E0F10020203040506070F2", + "3202030405060708090A0B0C0D0E0F100202030405060708090A0B0C0D0E0F1F202030405060708090A0B0C0D0E0F103"}; const char *strLB2[] = { - "4202030405060708090A0B0C0D0E0F11", - "5202030405060708090A0B0C0D0E0F110202030405060708", - "6202030405060708090A0B0C0D0E0F110202030405060709", - "7202030405060708090A0B0C0D0E0F110202030405060708090A0B0C0D0E0F11", - "84202030405060708090A0B0C0D0E0F1", - "95202030405060708090A0B0C0D0E0F11020203040506070", - "A7202030405060708090A0B0C0D0E0F110202030405060708090A0B0C0D0E0F1"}; + "202030405060708090A0B0C0D0E0F11A02030405060708090A0B0C0D0E0F11A4", + "202030405060708090A0B0C0D0E0F11B02030405060708090A0B0C0D0E0F11B5", + "4202030405060708090A0B0C0D0E0F1A202030405060708090A0B0C0D0E0F1A6", + "4202030405060708090A0B0C0D0E0F1F202030405060708090A0B0C0D0E0F1F7", + "202030405060708090A0B0C0D0E0F110202030405060708A0203040506070808", + "202030405060708090A0B0C0D0E0F110202030405060708C0203040506070809", + "202030405060708090A0B0C0D0E0F110202030405060709A02030405060708090A0B0C0D0E0F110202030405060709AA", + "202030405060708090A0B0C0D0E0F110202030405060708090A0B0C0D0E0F11C02030405060708090A0B0C0D0E0F110B", + "5202030405060708090A0B0C0D0E0F11020203040506070A202030405060708090A0B0C0D0E0F11020203040506070AC", + "7202030405060708090A0B0C0D0E0F110202030405060708090A0B0C0D0E0F1B202030405060708090A0B0C0D0E0F11D", + "5202030405060708090A0B0C0D0E0F11020203040506070E202030405060708090A0B0C0D0E0F11020203040506070EE", + "7202030405060708090A0B0C0D0E0F110202030405060708090A0B0C0D0E0F1A202030405060708090A0B0C0D0E0F11F"}; const char *strPB1[] = { - /* ECDH (NIST P-256, NIST P-384, NIST P-521) public keys from NIST CAVP SP + /* ECDH (NIST P-256, NIST P-384) public keys from NIST CAVP SP * 800-56A ECCCDH Primitive Test Vectors. - * http://csrc.nist.gov/groups/STM/cavp/documents/components/ecccdhtestvectors.zip + * http://csrc.nist.gov/groups/STM/cavp/documents/components + * /ecccdhtestvectors.zip + * ECDH (Curve25519 and Curve448) public keys from IETF RFC 7748 + * https://datatracker.ietf.org/doc/html/rfc7748#page-4 + * ECDH (BP-P256 and BP-P384) public keys from IETF RFC 8734 + * https://www.rfc-editor.org/rfc/rfc8734.txt */ "809F04289C64348C01515EB03D5CE7AC1A8CB9498F5CAA50197E58D43A86A7AEB29D84E811\ -197F25EBA8F5194092CB6FF440E26D4421011372461F579271CDA3", +197F25EBA8F5194092CB6FF440E26D4421011372461F579271CDA3", // NIST P-256 + "DE9EDB7D7B7DC1B4D35B61C2ECE435373F8343C85B78674DADFC7E146F882B4F", // Curve25519 + "8D2D688C6CF93E1160AD04CC4429117DC2C41825E1E9FCA0ADDD34E6F1B39F7B990C575208\ +12BE512641E47034832106BC7D3E8DD0E4C7F1136D7006547CEC6A", // BP-P256 + "700C48F77F56584C5CC632CA65640DB91B6BACCE3A4DF6B42CE7CC838833D287DB71E509E3\ +FD9B060DDB20BA5C51DCC5948D46FBF640DFE0441782CAB85FA4AC", // NIST P-256 + "DE9EDB7D7B7DC1B4D35B61C2ECE435373F8343C85B78674DADFC7E146F882B4F", // Curve25519 + "8D2D688C6CF93E1160AD04CC4429117DC2C41825E1E9FCA0ADDD34E6F1B39F7B990C575208\ +12BE512641E47034832106BC7D3E8DD0E4C7F1136D7006547CEC6A", // BP-P256 "A7C76B970C3B5FE8B05D2838AE04AB47697B9EAF52E764592EFDA27FE7513272734466B400\ 091ADBF2D68C58E0C50066AC68F19F2E1CB879AED43A9969B91A0839C4C38A49749B661EFEDF243\ -451915ED0905A32B060992B468C64766FC8437A", - "30F43FCF2B6B00DE53F624F1543090681839717D53C7C955D1D69EFAF0349B7363ACB44724\ -0101CBB3AF6641CE4B88E025E46C0C54F0162A77EFCC27B6EA792002AE2BA82714299C860857A68\ -153AB62E525EC0530D81B5AA15897981E858757", - "00685A48E86C79F0F0875F7BC18D25EB5FC8C0B07E5DA4F4370F3A9490340854334B1E1B87\ -FA395464C60626124A4E70D0F785601D37C09870EBF176666877A2046D01BA52C56FC8776D9E8F5\ -DB4F0CC27636D0B741BBE05400697942E80B739884A83BDE99E0F6716939E632BC8986FA18DCCD4\ -43A348B6C3E522497955A4F3C302F676", - "700C48F77F56584C5CC632CA65640DB91B6BACCE3A4DF6B42CE7CC838833D287DB71E509E3\ -FD9B060DDB20BA5C51DCC5948D46FBF640DFE0441782CAB85FA4AC", - "1AEFBFA2C6C8C855A1A216774550B79A24CDA37607BB1F7CC906650EE4B3816D68F6A9C75D\ -A6E4242CEBFB6652F65180419D28B723EBADB7658FCEBB9AD9B7ADEA674F1DA3DC6B6397B55DA0F\ -61A3EDDACB4ACDB14441CB214B04A0844C02FA3", - "01DF277C152108349BC34D539EE0CF06B24F5D3500677B4445453CCC21409453AAFB8A72A0\ -BE9EBE54D12270AA51B3AB7F316AA5E74A951C5E53F74CD95FC29AEE7A013D52F33A9F3C14384D1\ -587FA8ABE7AED74BC33749AD9C570B471776422C7D4505D9B0A96B3BFAC041E4C6A6990AE7F700E\ -5B4A6640229112DEAFA0CD8BB0D089B0"}; +451915ED0905A32B060992B468C64766FC8437A", // NIST P-384 + "3EB7A829B0CD20F5BCFC0B599B6FECCF6DA4627107BDB0D4F345B43027D8B972FC3E34FB42\ +32A13CA706DCB57AEC3DAE07BDC1C67BF33609", // Curve448 + "4D44326F269A597A5B58BBA565DA5556ED7FD9A8A9EB76C25F46DB69D19DC8CE6AD18E404B\ +15738B2086DF37E71D1EB462D692136DE56CBE93BF5FA3188EF58BC8A3A0EC6C1E151A21038A42E\ +9185329B5B275903D192F8D4E1F32FE9CC78C48", // BP-P256 + "A7C76B970C3B5FE8B05D2838AE04AB47697B9EAF52E764592EFDA27FE7513272734466B400\ +091ADBF2D68C58E0C50066AC68F19F2E1CB879AED43A9969B91A0839C4C38A49749B661EFEDF243\ +451915ED0905A32B060992B468C64766FC8437A", // NIST P-384 + "3EB7A829B0CD20F5BCFC0B599B6FECCF6DA4627107BDB0D4F345B43027D8B972FC3E34FB42\ +32A13CA706DCB57AEC3DAE07BDC1C67BF33609", // Curve448 + "4D44326F269A597A5B58BBA565DA5556ED7FD9A8A9EB76C25F46DB69D19DC8CE6AD18E404B\ +15738B2086DF37E71D1EB462D692136DE56CBE93BF5FA3188EF58BC8A3A0EC6C1E151A21038A42E\ +9185329B5B275903D192F8D4E1F32FE9CC78C48"}; // BP-P384 + const char *strPB2[] = { - /* SIKE (sikep434, sikep503, sikep610 and sikep751) ciphertexts - Round 2 KATs, - * https://csrc.nist.gov/CSRC/media/Projects/Post-Quantum-Cryptography/documents - * /round-2/submissions/SIKE-Round2.zip + /* FIPS203 ML-KEM (ML-KEM512, ML-KEM768, ML-KEM1024) ciphertexts + * https://github.com/post-quantum-cryptography/KAT + * These tests are used by AWS-LC https://raw.githubusercontent.com/aws/ + * aws-lc/refs/heads/main/crypto/fipsmodule/ml_kem/kat/mlkem512.txt + * NIST ACVP test vectors https://github.com/usnistgov/ACVP-Server + * do not have matching tests for ML-KEM.KeyGen() and ML-KEM.Enccaps()/Decaps() */ - "0FDEB26DBD96E0CD272283CA5BDD1435BC9A7F9AB7FC24F83CA926DEED038AE4E47F39F988\ -6E0BD7EEBEAACD12AB435CC92AA3383B2C01E6B9E02BC3BEF9C6C2719014562A96A0F3E784E3FA4\ -4E5C62ED8CEA79E1108B6FECD5BF8836BF2DAE9FEB1863C4C8B3429220E2797F601FB4B8EBAFDD4\ -F17355508D259CA60721D167F6E5480B5133E824F76D3240E97F31325DBB9A53E9A3EEE2E071273\ -4825615A027857E2000D4D00E11988499A738452C93DA895BFA0E10294895CCF25E3C261CBE38F5\ -D7E19ABE4E322094CB8DEC5BF7484902BABDE33CC69595F6013B20AABA9698C1DEA2BC6F65D5751\ -9294E6FEEA3B549599D480948374D2D21B643573C276E1A5B0745301F648D7982AB46A306563996\ -0182BF365819EFC0D4E61E87D2820DBC0E849E99E875B21501D1CA7588A1D458CD70C7DF793D499\ -3B9B1679886CAE8013A8DD854F010A100C9933FA642DC0AEA9985786ED36B98D3", - "100692A8BD30F01BE8AC6B1AF8D93A060D3821B2587F4038D64B72426A194BEDE63CA60B75\ -A5C3C15532CE307115AA9D77AC232E14D99C1E1AFEF1EB2D6321AE342F990023466E683A2568D59\ -A14325C2C6C272029741D8E36976D1804059BC06B802F3A495EA50D0DBBA93FD263F4CF30BDB5F7\ -83BA6A0775715B05F700C85B316F7AA1A1624973885941DBFF91316BF47AC698E11D6B2418F5533\ -79D67A00F784B8643FB8A94029584391D488775EB4414A5E6E8122B0F282D900F3D05775F1DD994\ -FB232ED826106203CD3433967F60FF925DF9E86CB376CAB5FD90B132E425682741F6AF078E75792\ -CB4CE085D44993CFB6A4ED5AA3541640A0A67687922B92382CAC47C6AD358011A269CC7C17CE651\ -CA2E2393F7DFE19D7054FEF69610A353D676B1F076549510590D406AD13F4A3292CCF206DBDAE47\ -F08D448CC006449F27C1FB54E9C9E6F16ED2F3D120DD5AA2620D76690F00E31904C601310C76A84\ -3A58E1AEB9C5F515FCEC482C08205FDE99A89E64485EBBD43EEFE2E24D18EEE8F20DF6E113C6667\ -512E28396862C98F5C0", - "FB75E7D835313132AC0B29D8732F1F62E6DD10BBF30375B4A50C7B153431BAE6259E1C5526\ -C07164E87EDC70E4F0D8331D73285661D1F639D216372D05B4583C1302932B03FF184D115D0B250\ -297FF26AE81DFA0DE01A1DFB237C8008B22285A289C06BF4BC89C0BD77576932A14B1FEB9CE6D7F\ -8816D710F1B043C8E58DCE1B32EF4EC8FB67E10CD23B6D4CC653DD8CD83B5F4DB0B5B741D30125C\ -F842EE13EB940650E1E34E4666935B178F2351553F0822C8B354C70E47350E74A08F16D4F39F8AA\ -80C3F4E0083C4BA1F31F5F1D04FD4CF835AEA688885E85509133FFE557A7892A0161AC01BBCC8A2\ -7CE37E8CB9C1916A0F62BCF1E82C3F9213275B10CA272BFABCA2713CEEAECD0007C9FB6B562AFA2\ -231FF7FD2C1D20D8ED28C11A840FEE931FE7A0E3BB925D88A852C2EE9BF606AD4000FA27643155A\ -6FECAD9D4BABA8DE8F8D767AEC7A770D007ADB0D9F76E521DE6EF8D3567A32047688E2E8130AAF3\ -EB594A366F3C534E335A3E9EDA326E60394CA10A44340CC78995742E48994002CEE1049870D14C2\ -3C9FF2E5899DD7E3A1516D2F6E70B3DE1D79987379296E99EBCCAC43DA9A475CA3FE756D4649934\ -BADA6DFA8C8F8BB21136172798BDA13E247B2F27874AFE13CCCA31F53D01A94B9520C3CBCDD1B1E\ -B9BBBD6B83C76F64FC5D7C1DCF33A", - "66D24BC4630B2EE312F01B26EC1D3EC1F583795EC93B90FD9B5453E0BEDA2A70FB6181C9B9\ -EA86A9866F1468E62CE853C6C65AA5D0E4535828B3A97E2D1D31DC4372E6A36DA7B0C4733574B91\ -CCE215086C59B54F2364F61298004C8410B17658B4021CD36859C94210DE338869CACF0E2DC1141\ -2FA5172E1663AAEBEF4B5EB0ED9175D6C86C5107DA92B8772342A2F44C93EFFE61F6C76AB8ABA19\ -4E862543EDB707E9D2EE884995B1062FE2F60627D5C7673C7AC0D15B08C2F8510DC239463B1B32A\ -D46873F6D1CB5A8579457386FD75700989BEED2CA547FE505C581B6B436AABC0F75AD6373A08CEC\ -1504258A972C64EC4A1FEB86BFE32ACF3A73ECF815CBC883F39B42C6429A5875BD0BD6A94CEAD58\ -7AF49AC8EFB43E1A447D2D8555CB0ADFBC9F335F1C599BC9FEAB3E4FE5F2D06D930A58C2FFEEDE0\ -E2726EBD85EC890D1CB0E6870DD784AE30286F1A336D57FC41D2F2E2F89765C6A110853BB63E478\ -A64D54A31A18FB4BA44FF58A3662F4D82D544BD9B0E94FC88ABC4E4D27D5F6084B5F2162B357A04\ -A1A28C8938834ECC987E50C0A2CACA442850493CE16C047DF677097D3F7EA034BC3D25355042760\ -03DBBEB12F1949C3D369E7EFBA09831E83D622AB2D9277F523946FBAB1DDE14015857EA47663C5C\ -CF30BDF261CCBF31DBE2A560E96CE87FBA80B783350A42C837EB36B2F39A9FED1B649B8ECCE3D32\ -35825F7C800834740546E0CF42C9C2C8B12495225F991B14547E5EEDB22858B26EE6E0AE13DBE3D\ -50C6C1EF79C4B97DAD1B0239C4037C1AAC29EE1505E0E527EC81348900E7C216A1A1B34B8D2753A\ -F2693647C412", - /* KYBER (kyber512, kyber768, kyber1024) ciphertexts from Round 3 KATs, - * https://csrc.nist.gov/CSRC/media/Projects/post-quantum-cryptography - * /documents/round-3/submissions/Kyber-Round3.zip - */ - "EDF24145E43B4F6DC6BF8332F54E02CAB02DBF3B5605DDC90A15C886AD3ED489462699E4AB\ -ED44350BC3757E2696FBFB2534412E8DD201F1E4540A3970B055FE3B0BEC3A71F9E115B3F9F3910\ -2065B1CCA8314DCC795E3C0E8FA98EE83CA6628457028A4D09E839E554862CF0B7BF56C5C0A829E\ -8657947945FE9C22564FBAEBC1B3AF350D7955508A26D8A8EB547B8B1A2CF03CCA1AABCE6C34977\ -83B6465BA0B6E7ACBA821195124AEF09E628382A1F914043BE7096E952CBC4FB4AFED1360904611\ -7C011FD741EE286C83771690F0AEB50DA0D71285A179B215C6036DEB780F4D16769F72DE16FDADA\ -C73BEFA5BEF8943197F44C59589DC9F4973DE1450BA1D0C3290D6B1D683F294E759C954ABE8A7DA\ -5B1054FD6D21329B8E73D3756AFDA0DCB1FC8B1582D1F90CF275A102ABC6AC699DF0C5870E50A1F\ -989E4E6241B60AAA2ECF9E8E33E0FFCF40FE831E8FDC2E83B52CA7AB6D93F146D29DCA53C7DA1DB\ -4AC4F2DB39EA120D90FA60F4D437C6D00EF483BC94A3175CDA163FC1C2828BE4DBD6430507B584B\ -B5177E171B8DDA9A4293C3200295C803A865D6D2166F66BA5401FB7A0E853168600A2948437E036\ -E3BF19E12FD3F2A2B8B343F784248E8D685EB0AFDE6315338730E7A1001C27D8D2A76FA69D157BA\ -1AC7AD56DA5A8C70FE4B5B8D786DC6FC0566BA8E1B8816334D32A3FB1CE7D4D5E4C332AF7B003D0\ -91741A3D5C965292255DFF8ED2BBF1F9116BE50C17B8E548748AD4B2E957BBD1953482A2E1718CE\ -C66CD2C81F572D552B7187885E6B8943D6431413C59EBB7E036048490BE5289E95B20A89E8B159F\ -61A9A9886E147568F4C9021F362F02688A1C8C3BB0D24086880E55B6EDB43F3745D2C166DC1CB74\ -3C76FE6BE523A893CC764D16435C37851252A81E2FFBA0F18971A3DEE37D4877CB928E36E523503\ -7A6B2057897D518A5F0E348E3AB6D5B52DFC60757F3B41A4FEC7828F1DEEAF4587CCC8EADF647F4\ -D203B2FAA05A649B582340CB4CACE57A30711BE752FACF0227D0A80C4128442DDC544BE805B9CFE\ -8FE9B1237C80F96787CD9281CCF270C1AFC0670D", - "B52C56B92A4B7CE9E4CB7C5B1B163167A8A1675B2FDEF84A5B67CA15DB694C9F11BD027C30\ -AE22EC921A1D911599AF0585E48D20DA70DF9F39E32EF95D4C8F44BFEFDAA5DA64F1054631D04D6\ -D3CFD0A540DD7BA3886E4B5F13E878788604C95C096EAB3919F427521419A946C26CC041475D712\ -4CDC01D0373E5B09C7A70603CFDB4FB3405023F2264DC3F983C4FC02A2D1B268F2208A1F6E2A620\ -9BFF12F6F465F0B069C3A7F84F606D8A94064003D6EC114C8E808D3053884C1D5A142FBF20112EB\ -360FDA3F0F28B172AE50F5E7D83801FB3F0064B687187074BD7FE30EDDAA334CF8FC04FA8CED899\ -CEADE4B4F28B68372BAF98FF482A415B731155B75CEB976BE0EA0285BA01A27F1857A8FB377A3AE\ -0C23B2AA9A079BFABFF0D5B2F1CD9B718BEA03C42F343A39B4F142D01AD8ACBB50E38853CF9A50C\ -8B44C3CF671A4A9043B26DDBB24959AD6715C08521855C79A23B9C3D6471749C40725BDD5C2776D\ -43AED20204BAA141EFB3304917474B7F9F7A4B08B1A93DAED98C67495359D37D67F7438BEE5E435\ -85634B26C6B3810D7CDCBC0F6EB877A6087E68ACB8480D3A8CF6900447E49B417F15A53B607A0E2\ -16B855970D37406870B4568722DA77A4084703816784E2F16BED18996532C5D8B7F5D214464E5F3\ -F6E905867B0CE119E252A66713253544685D208E1723908A0CE97834652E08AE7BDC881A131B73C\ -71E84D20D68FDEFF4F5D70CD1AF57B78E3491A9865942321800A203C05ED1FEEB5A28E584E19F65\ -35E7F84E4A24F84A72DCAF5648B4A4235DD664464482F03176E888C28BFC6C1CB238CFFA35A321E\ -71791D9EA8ED0878C61121BF8D2A4AB2C1A5E120BC40ABB1892D1715090A0EE48252CA297A99AA0\ -E510CF26B1ADD06CA543E1C5D6BDCD3B9C585C8538045DB5C252EC3C8C3C954D9BE5907094A894E\ -60EAB43538CFEE82E8FFC0791B0D0F43AC1627830A61D56DAD96C62958B0DE780B78BD47A604550\ -DAB83FFF227C324049471F35248CFB849B25724FF704D5277AA352D550958BE3B237DFF473EC2AD\ -BAEA48CA2658AEFCC77BBD4264AB374D70EAE5B964416CE8226A7E3255A0F8D7E2ADCA062BCD6D7\ -8D60D1B32E11405BE54B66EF0FDDD567702A3BCCFEDE3C584701269ED14809F06F8968356BB9267\ -FE86E514252E88BB5C30A7ECB3D0E621021EE0FBF7871B09342BF84F55C97EAF86C48189C7FF4DF\ -389F077E2806E5FA73B3E9458A16C7E275F4F602275580EB7B7135FB537FA0CD95D6EA58C108CD8\ -943D70C1643111F4F01CA8A8276A902666ED81B78D168B006F16AAA3D8E4CE4F4D0FB0997E41AEF\ -FB5B3DAA838732F357349447F387776C793C0479DE9E99498CC356FDB0075A703F23C55D47B550E\ -C89B02ADE89329086A50843456FEDC3788AC8D97233C54560467EE1D0F024B18428F0D73B30E19F\ -5C63B9ABF11415BEA4D0170130BAABD33C05E6524E5FB5581B22B0433342248266D0F1053B245CC\ -2462DC44D34965102482A8ED9E4E964D5683E5D45D0C8269", - "A6AF29D5F5B80BD130F518BADDD6C8F17545413D860FB3DE451979EBFA5E4E3112C7C0ADF9\ -9824BB526F2C3550748ED0E134F0457A7C61F9F526F002BAADC03FC13E38131219513C3EDE06166\ -1E74F603C4FCF7951C8E52C9C213B0D22D9293663D669A6B58ED8FCEFCF8249D7BB5298F5576144\ -5B2B83CE7F005CB04248AEC8BDA22FD2D42AA766322014EA038CC32C55C8E4B9E28EC9119F52734\ -1E4F66A035121073B85DE6706DA19E0838A9F33B719A68F039B664DC002659EABFC398679AA7009\ -CE0CD01CDAFB6CD2A26FE4101672C98FF58F7C47D5BDA2906653B3A6F9651F7A121EA77EA74723F\ -AE5B873F9BB7B664F0C8A93831EF9D51C7CC1EF44AC0E55A55CA76D137FE9B75F40509CEF156E5A\ -D18F9FB999680008E547D55EECD5B4D1CB1D9F076CEC21501C7402509ECB77AFB2CB9A61340A8BD\ -1514C6E71B4AA45E47EC37512271B911F8FB46C9082C9DF07204ABB5A50E6E3647A8AD4D8D5D7BF\ -F19C8A509308BCFB895536D045CA2B97CB16A29BB7181CAD0509DDB91735028EBA8C31D74BD275E\ -AA65B5340B3A43FBFE0B3061D6BAE7E75B7098CDABE91D4B31E36C9AA7A8298862AD63C8FD282E0\ -3B460B3AB464CE0F27B1C3D11155ACAA011EB9E2AE3E6DDA07D6F491737CBCE9B05F9BC56BE20E8\ -D326BA132C57FB235161144519CDF40560FBE279BDE411E112531F826D6AB10D4547350ADD2A9DE\ -8D62C2AC82CABE6815646F4DC9742BB0C2A3F77EC7B46C6B537605FA31798CD89281221A33DFB97\ -96E644305630332C2CB931408AB481A16D953F6BEAE3891D6D9AC1FAB38222D9271872D9D0CADB9\ -1ABE9B4E265F75C6E5E829E146C3D8CE1E9D12E0D129801957F46B0D2DBE1F749B1D08E2345F623\ -9A731342EB75B0CF1BF411749BC2CAF2810B788C6B7238B4D3DA2D6315CE9542E24404F145755A3\ -0AB851E4445841BD33F716A586884888ECC6BC6498AA32919AE81D20C26973C2BD54582A0F6AD98\ -ABFD2627E15690A727E69F581DD2A7127982A90E33E2D4A03FE339142C7E44C326AC46ED395A225\ -D3033389917328B45316B1585A01B2C304B2944E903ABBB3EC5619441CFC8965A446DF75DEFA80C\ -6E15ADBD506B7AB2DE12DDA9BC81441CFC89052E2E5808F7126C6FD3AC6AC8081258A84A09AE50F\ -6CD7CC0F4AF336FD1D643E99079996268C2D32D909F22E3504F07FBB563196D4312FDDB9335D5C1\ -D36E8C5EEA2278DBA23B94D193C947CC41CA993DC7DB1396340AD9C4FE687DD7B8D0C7A5120AE02\ -04F2C665BD5F473D644C7FF26BFFBA7A36980830702128A7E661D677A092A36E7428A4139FB29B0\ -095CC11086F447D2A9EF6C9B161F189C6299E084CB7AA00FAF787797BFB069FBC087FDE26252A16\ -64F19C5A8A22EC5EE1AEB076357B7DC37E6B0F1520F958F7851BACB92C89FD114A72FEAC54652D4\ -5B09E1AE7651ABD164BCD537D58FA39D3EC8ACDCDF98425005862FA59692DE162B77E6297C66233\ -348408A8AB695CE2F2728DB9FBE27E958967EC5974767C5A66023074B4A71AFD264AD2890E970A1\ -F31D6E3311B736F9F9488793DDC88F23458064254C82A1D9E59EAD2FCEC40B430687C4B7E289609\ -26AFCACC9BD756A71088C78450E20A2E980AEDE9EBEDFE7FABD6ABFE96F934C4B02C01CA194D01B\ -73C25D5997039D3FCD0F099521F70CAEE69110AC1FC5A99917AD752FC96ADFAD7186D0A7C9CFE56\ -01C07514EA6448D661C57AA20242103C4276A070A489A4CB6BCA0F9ECC4379FB220215FD91F8101\ -9D5B0AE619358B52468F272C178E3A74CF6775AA924FE329C3175D9E4C3E21AB9EC836EDC3ACAB2\ -E3891EE8DEDA515D39AF9B8DDD0EE7B0164F805C3835F6D2BABDB30EAB4756E7EC7F829ECE01E8E\ -ADFBBED12FC283B3D4C69F575E7F80417689FDFCFC7BE27EE3B8CDF57AAEBEC4A95B7E5BB585B85\ -227F7C32BE30DB3E65E42E30DCF5A5FA073DBA399D942F2222ADB9B9898102AFE5432EDC7F04AE3\ -4A8FEC2D81CB49A9A9B43814CE71D97F726E2B1E8F64B50E65DFB4816E12E82A3197484A4E9BBA4\ -D2D69E3F19D0B75C21E2BFFE9FC0C98CF48A3AAF08D467F72687DF0178174B7897F734349B181EC\ -A86A598A0C5E8C25946F24DC5572BD324A40458A788E5137F3C7A7C97FC9F12A3C463A8FE944910\ -1CCE966D7C009323932998D56EF430C73BC24F5D95F737858DDC4F32C013"}; + // ML-KEM-512 + "917E59D1E182A29648A61955A154B304A842F458EBA593F3065FB7D744FBA24FA3A0D53885\ +4E32844DB248D48100C389C4C4B3CA6C234F2F61A67932AEEE808DBFE98D896D1E9668820965C63\ +43BBB4A4DE64B7A99FB53B5264E3199D587FFA5E0479F6B7386B23CB9C243FA6F5457FC97DBC96D\ +CC039BD6C4E7E85A90B5C5232416434EA942CC71134BB9A2F4991E0595E3487FEABAC479CAB9510\ +D57B86250EE7C96A67A9F2C6121F7DAA02C5CFA3B23B0C732C2B15694E1CCBAC82B787CF2118D08\ +425CBBA121882217940C894CBE47AAE2541F5C6E0BD1BAAB31FD2B2ECB34B9E693F6FC0FDEEA906\ +716D08818F51DF0C4694029E8C3234BE0B62471B2769D9AC4CEB947602380F3A497B2A01FF7B874\ +6C1C7AE81983E016BD65C7CD1762C191857E41C2321981F6C7AA8D7AFAAA9FA0B557EC1EC1285F8\ +B4D6C788AFF159EA5862E814D0825C8834B7CA45DB7C8EDA3FA6A6A7B8A40519529BF74B6A0F80C\ +484917F40C107D182BCE3E344FD36D1B377A982F6BF2361B8D662875C166DCCA73240B86DF5EE0F\ +A4231B356F0CDD6B3170FF89113DB0B1B9DD264335783222CBE7BE844642B0B1988D18B268DA6F7\ +8CC944F43B827143C4DC5EE1F0D658B87B9C00862F263D6F5798FC82E8BE079A1108DEFDD4C7863\ +C3147E9BDF0FBC84DEBA215FDFB9CA4237A8419B26FDEFF63A7F95C442BCE67966EBE6B5F9AF1FD\ +2A7CBED648EA7276DB742DAC3E470F6CC741D82E77E9C0DD019B5458177551975B59633BE67B35C\ +0D430B725524DEAFDEBA6D3643C5C82EBB52479669C411BB56B397F8D37B8F7FA4CED0316546CAA\ +EE419C0E7F1D96A0EC614C6C9C8E03E010031765121F1EB8FD549FDE046A50443EBAB9FEA2E78A2\ +9F4964455928DB1F9E7820E533C5712989B3A3637EA00A1DE3E469A800C431D4DF243C1DC7D6A89\ +BA7900D52B78BCC103474F9D2C2128025C3193C4D1A09F50905AD2DE7FE8E09F047E0E72E6DAB0E\ +DF7E3B08ED1316ACF857254B6C1FBF64CE582F2990CCECF9505FD7E8517998AAF583BE1AA641E9B\ +54DBB91CA9D0700913967FB0349201B5D679B32D", + "1C43DE770E9CD59846B6F81F9C61CCD837978E26D32C330D509D8E29D9E7FB1A4FBA52101E\ +48880D80616E533AAC591FEBD393CBB1282DE153560D4373CB882C66D307329597910ED3FF10584\ +0964A640BC762E6329B9F3BA41A9EC31E04C8C9EFEC9635E0A9B456F619F10658BED36A133CED0C\ +230B3CFDD8073775D759492A7E3BE0CE27725EB7C2474C568D039243FE810B31DB2FCE8EE403730\ +6A5A9BBEE1BA745C2B4FC1111659F5DE919941C89C8CC661ECAAAE3E9610EAC66CD4128E3D4BB5A\ +BB38837D996DB7E5C31FD09222F22F854C25FAD8AE12DED3E337C3241468EEEBECDA5DD682E6E57\ +F51AD352858D04048A4703ADC135263C47B3A5D6E6C595BA1EA0602BD34353E191BFDF36D56B205\ +39748AD61C66C250E07F2E3C6D60894472FE7E677C353F70A175F04C60F69DD921E9B9249BD6291\ +4405829AEFA052C929CF23ABA067A7EB7FED0C15F401EF5084A97A61CED6FBF8791487231C05FC2\ +3A387C77C0316538AD09BE82B10EE8F8D6A9D979F63A2EC2364F0867306E9BF6E3C0388496BEC8A\ +D161515B016E91B5AB4E4EE9C48F0DE4950AA496B3BAC3ABFA86B9CBE27A92AC8A817650B2C4C53\ +6EDA1D2AB58195CD423E0F4AFB5BAE7101438821B89A99206BA5FDD9D06C39DFD6F06FBA8C71942\ +13D0E86F80E4E5A24977EFAACF7EBC02B028CFC9673DE6C8A0CC6AE1E577350935C912CE1D56C67\ +0875C4D6BED8750A9EFBB450791C3D560CE510213274F7D4B3B88AD9967034751068580A9DEDF0A\ +B3CADBB2F3BBF3719CE73E938666F2A7FE82F10F08D325D203EC0B0585B582216B7FC05A7291481\ +D1222791385B6416E807E697026BE218C519C1B215842AFA0E58F988F88F3D90CF6CF42187876BD\ +BD7BE0B2C261B0DD36D16DDE6ED8354BD7432B66D10BCACCB69C8944778902FC36DC70F4E6385B9\ +D59AECC6445CE4AD65BCC958E886A92A1D4D175CF354B4FEE8890EA4CE21F5E831F6905AE528DB3\ +991834A2452F591C3EA88D7612A599A3014FC8E10B30D48398BB8991C0FF12A7356645032530D81\ +8D8AA2500B2521A73E18591EC6EF422DAEED66D2", + "5533604256120D548065769413B82FB5ABD0014E7E9F10492FF15FD45DC782B2DC4C55325F\ +CC57685F134FF7E123CF028FA7B45DCC717CF2D7B274D8F2A8B7D1ACD66353A56335F482EC3D045\ +04D2E052DED28112AC7410FA8E47F0D7C5EB1D6A29E948781DB3863767B7EA87A591E0D7EA4130C\ +1C9FA5E8142DABF7EE8C02191CDF1B8C804D38E2B6E4445CD8FD341A63EC0001B9D8829D4C8F5E5\ +3DC6E8786DF67F4AC0BB9D188F064DA50C1FAB3965510A048EB6B4AA78A851C47B106429B30F8A9\ +A3B54648C8B43DCF76190BBC8C66A6A36DF7B95AE3D9784ADD8758235B291C0A1DB1BA805412E8B\ +92C1416FBE64C42DB123830ED1BD97E69E522E482E83325E9E88AD9403F7E86D88D535E391AE4CD\ +330EE05892A114E4439B59B30602D9D98704AA55305FA1F85B23D7C3B0F30654C8B7CB4CE02985E\ +6CBE9A87CF0E999A565413099FDFAF577845A407CD6C2EA5EDEDB04BA434D80E1132467088861D6\ +5199818ED4BA3A095E066339F353394877E3BF7926288CDD37AC31CDB499B5EB8CA06859BEB5C66\ +0730FA793CF11347FBFED73A82E1D2B229A09593279AD0445BC11B4F164D015EC5141DADC10D322\ +C9283E5A641157DFE53BDA4C3CA7364699DF0BF794D4683FB1FDECE8E318DA3FF028B63AA7D9F50\ +B58785378BE79FC7E8A2B1273A8D78774853357AEC523EF7D927644B07D3D0F2876BF0B55D4592E\ +33A658C461C96C8B81CCC2B1D48C3929AD994D015AE6DC4C98A75416767C7BA160BF7491B4A0AAD\ +B5E43A397F63CE1CF7F916479F763350C54DC296A22314B4F484C8C22E364FCE5A6CA6E150B8102\ +1B44B5F49F914927896437213D0ABCAEA28062DB2854138D0E0BEC841E6BE8E039B8A0D762E60EC\ +8B6416DFE7C7C8ED9B7415908B8DD9A698950697FA5FAA5B1926A54DE986A0093DA976C89EDBF83\ +711A4BAABC2C21C74F2B7FE96AAA9EB082DD66E3408CD30002CDBD573D27F66A806EB0B3144C427\ +E07EF7A3967F04F0A4336F55E8E12C63A6780251844802273AC901D4F6A556502DB496D4BB46109\ +BE1F90B7EFA76D3403A3BBEC6A32E8E5CF4EDBA3", + // ML-KEM 768 + "CC1160B24F3AB56D7E3EEF460A2AD73D0E5B50BC5FD6E06D74C80DF6295A5E7FED8664C9B8\ +19ABB90BF1B2481CA3958EDE019E5A8D215E3C3B2FC662E6A6E5F4D6CD36C30C747745FCD8F8556\ +0645EC010987B87A7B42E619F388FDBB9DF0B916A01AD0640A9B761A9353DE373033EC5E2D16B59\ +DB508BA33259B9791691FE35B2F08AFF381BFC9A74E380DFAC915B6165ED8C276DC7112FD36B7C2\ +1710AC6A2201179642BACA216C3D4C39EA74E75A370B9ADE85A2AD8B00EADCC4AE2B3819374FDCE\ +01F4AF02535194B88933ECE5A9B90C1886EFBCF40B1505D4D2603F7FED815F3B101664A90B239FE\ +598E90C09069E102C500912C71F53396EA1C9035682C9ECB1627193FDEE803078E4CAB436B6CACE\ +8A861AD95B5F53E6C9757EEDD7FC9EA369089E82D2D32C95209460BD880C7D856DD8BD589E131C9\ +91E1148B5E4139E7F4EE32B25DA676FCB279ED94D9B28B6C4843F07A93FADC1314869D2E271D90D\ +993E4F5B654157BDBF45215D691AFAECC498E9ADB3A798029C2D68665878634E02B34006BA953DB\ +444203C88C4523BEDCA14358E0B129BC712EAB69D1C253C490DD4E5F751FBA1B38BA200A3E73E78\ +299306855237C6F72B15598B2EAB30224A22C2C7883C6BEDE636C4D1C06ED0B6793E4609969CF8A\ +442614C8C547598C26CC848BC4593E24591FC85F624548A1D01EA5BE04892C5C12EC07F70C8CA51\ +C4CCD1C9F061EE1BFE07112C2577552966EB25759E77882F1B5B327964E6269E36C1D5AC9C94B01\ +D891E1B3AC2660C5D99E32364AB31015986352ABB20A228C358A548D1B413FF534550F2EE0C80E0\ +741B7F90DC22E8D701A44514810820A5A1D5EE62173283F91DAB585615E36A520FD7540FF7E7B9D\ +6F2FB616251F1D2B6A034AF6427E66D559D7E04F1C7C22FEFA5F3F7B256D7225D5F683FE2923875\ +4D66E10687290675202CD15A32A7F71B5750A95BFCC183D2C26BF31D41225C04FBC123683FA911B\ +994C5B9AE5172EE9847356C67302E7C405625543B7FA82D9BE737467F7C000F97FFBB647500DE9E\ +E36A266F97AE83AB58D239533C8A2FB440E649ACDF6EFC8D98BAF10A1BFA0F7681EC9708BAB9D00\ +A78FFF74AA4C7099D6DA69FBEE2B7C5EA7CEB04527D01CA2CCA8416181BA450C2519A8F383881FF\ +439DEDCE45BF0117CAC0A612E52AD1A3B2F2D1C9917264DD131813F3D9F6D2D574D6CE9AA0943AA\ +7E84C9BDEC515B6827921366794FE6B9058769ADCB3A14593CA49A866DC7AF5BCAF2A48BB06271B\ +3948CC64572AE3A9D46A1209D3E70A02D50AC3CB0AA1B820F8EA25DA127931406AAFC9B00C0FD90\ +C7597321586694E35EA291A88665A2FFBAE5C9BE45938E60027C6C6DEB384F873457B5B5C710765\ +1AE0273DF8A23FDFF74A2A6BD67703854FA5E115712E84D6726F27370FDE6390B362142FCD93647\ +BD2D7A3927DE5F5040F60E17C39D1248F6662CF441EE4B2470CD412050CE09EC31075001286F401\ +A58FE6217000D6A9C8BA753C4CE9D1D8CF8B908614DF0A81", + "DB3D4F38A49CC5C1C7766573873F3926184923F570FCDBA6D7086BEA39601FADFEBABB2F9E\ +D0EBD86A6468BE03D3B05713DE50B5E5D58FFDB5500F2AF7419682BC7857870D1E624C2B48A7E0D\ +30A91F141F0764014FBED12A9F72C958EB53A7ED4A1682578B4348A05C183C790FF56D66B23BD60\ +1FB372C771F52045E13CA2D6DAB80A165A2159B8F990B5BBF125883DEC0A2AF4A54C3F386DE4DF6\ +EE96923E9BB2551753DDC6D1F00D7EE910835082C6260974D11FBA49951DB2E27B47362EC4EBF80\ +4327AD968201EDB71BDC8C32887214FB2AAA842AABBE0A4E03FDC695B19610377B9BEA9D3710166\ +74E977E9E45382D236365EFEDF566659F9936D9D14CA8595DDF121AE7ACC6056DD6FE1B58DC0F0B\ +23CF5366D2488C4D6361B09875242B3A39374159CF3654ABD25F8B080BAE117A5F77D15031AD8B3\ +50C6922FFD426EC9F9F80A1918FE722CB7A4B537210EF8A5538A52048BADCE3CAF5C46454EEAF41\ +3819D57EFBA834D7017F9343B302679A0A28F532E93FE8C5B6AEC3C42C160A3FAD20FA2ABADD29C\ +2564DB59FA25A11CA502D11421F7F080A616F9656942932E11BFDCC47B1D8EFFA81D724FFABF461\ +3830631737EB7E52DA78A6B026DB1C4FB80BBF2D8F9393875330B2F9C1A124436028BF2624C1E64\ +797ABE2E526967DD99BC21B555A5833A31ACE7969E3ECC64C1697DEC0B074108F6B17EFA2A51792\ +3B435D8446043FB1A96B2EF3B3D3952F08657997D1D9169FFD14316185EC30457E0FAF7EBA2B5A0\ +2A01993EC530BB9C44C091D2E9D9BC82951E577D76DC2757F2E04E822B6A29F840887A297202E73\ +89A0999F9E69255DE0A33AEB8CD0B21B7F3B5AA7BFD864CF8FF4FFE78FFF166CAF1B805464D5E4B\ +60EB0277E3BA4F3F3390640F5F16E0B784CC8A67940977B2F0202D37A74472161589A7B9E7721CC\ +532904A17AFF8FA86ECDC46A410BD6F9309B2CC310D7941A02A5720CD64241B5C13C78A86010805\ +AC74C3B81D83348C63C410451BD2052CE764DA83CF80B2654CB1D033F259DA36039E4DF1A5C4CE3\ +F8613E28CFC2B25EAE2A21B425B44D0C998977B3ADF5156BFCA1E357EC3F6B5805B2CDC4D46A4C8\ +3154AEF0F50D493BAB0BBCA130E92CA21AF8BDF817F7616B55C4C24C066EBF896F39A7BF50A2415\ +61E578BDD931CB07EADD193986C455F8798AB97B8D732D37C796E09C1C7ABB978BF666CED961373\ +198607AC355FCF6903B4F3047A1D97C344A2D8B73DB310769CCFB4AE3DA6C4E82DEB83BF4060722\ +D9E5A9AFBD3E03B4517E3B7D563F31821D5D8EF7F06F0D92A9F401EA9BEFD52CA8DB331360E603C\ +14A340B806155DE690CD2D92EE6A8EE53BCEED7EEB308D375518C851C109A03EE61960D6CD7CD1F\ +DEE5CC2A401039A15EE4F97A73400801A090FBF09BE42119662D06C3FF8217FCFC2C70CDE6E1C2F\ +9A396A2E08A3C22AE3CE90A5C97C9F69EBC1546898A047C9DCAD128003A90B29B62F7B093CC90C9\ +CD38104C1A3CE62BEA6A3646EF7E3B9FB7C4C44E78FF650C", + "535C387DD4843B57BF015986D2BC366C08FA21A6A3A615A35D82FE8FEA39968C4F6807E2EB\ +EE361208EF9AE25D6E3109A0360CC7802604343337268FF3D91E0F397A0A5BA525D9C93FE897537\ +A2EEE5D261B6CAA466E4FE85071B9DE1A1A8B3E9C2FF9D5ACAC679D101592FD2DFED7E667AD5E0C\ +7FEFC249FCE1431E674D1128E955040DFB6E47D2435B4EF99F1ED38FF688743AC8655BDBE4656AA\ +4E6CCF626020558A99BE753C8974CEDBC9CCF494DF5885B2628FAE4BDE6D26346C2B37BEFA5F1B1\ +F584EBDA4B38D4248D5A3C5BF1ABFD79BF9601F27F9BCECB40DE27B50A8B3FC8F6F9D4375FD5374\ +1DA0385998FBC755550DCDBB92B746EAA7197B903043545AF0792822D1DC3F12E6A3EDAE3C6B9AC\ +81CB24004DBC6C9A7CA934927482E5D13E88D5DDAE92CBD59FB9B1285B3737CD9194A2F33572EAF\ +E02B02BE27B99F283861FC76CDB1239AC0335FC0DBC781A493AB4565BBE01685A58B13CFF22C995\ +4693D118A82948982927B880C790A6420CDC07A5398268EEFAE2BE89B2CF2F13DA535E56D4A046F\ +88C6C34683770ABEDEE2D19F0C24790F83E8A60B0545A75B2BF0ED1308968623519A4C2B12D7B53\ +98FACF4E4963934B96E064144B05CFAB5A2AAB4AF2CF0D226DDBCBE1C2C46A7300B2AA0C69A6D0A\ +0521E1CF3EA836B30F3FA0014141ACAFEDCA5A2332FD083EF19F196C19C273EEAE4EAAB0E67DC0A\ +72910C1FB1BE49F9A71B86A42EADF61ECF08B013A89D1FBA22F74DB93224ECA79D8576B6C97525A\ +3523C24C99B5206722DF4658F2EB8801D9BFDD89D3D87548073620A8920065CBA6D5B0384CCB70D\ +74A6EA328B0FCA71BD4737CD823188AAAA9D0D4534629420214881D1C93FF778032C5FA2A8FDF3D\ +5DCE1C56F8009182FF95FF201ABDC410AFCB031290D3B5710BC45C9F9426A9C41C1A322FF723FF6\ +794179186196648AD7939730189A4C60FA579709E838FE82DFCA775B7CC678BCC14DAD3B15C112A\ +1CF9F432DE281A32DCE0C02370F524B74DD21EFEC5E8A6AF2245E5A3385E8C2C98400FFC1310AC5\ +A7946D929EDC9FF6ACCB89997EA6AC8B1823F008C93526E9053663E5E049B2445EA2009B9C77BC2\ +7D7F99069F2BD9C226118BF510FB20CC9C5E9F08D68D9B3C2E95E594FDB50954AA371CE263F74BB\ +ABFF660218162056C1C60EE679D574508432D793973C9B4B3432DF9A9E8ED784B3274ED00A2E414\ +5609AFBC7DBF6A98CB706EE3A6803A04F19207556E70B55BD12A4D4F3DEE0503369A449EE031486\ +7940ECB4ECAD36C8F9799ADC88F9554E4359AB1D270B58B590411AF89B277AE885773A8E9F3BE1C\ +239324C68EE6BC45728209FD2BA20A01FA8D214F502C34FA4C1449C13B16627C1F8E26BE1313291\ +9D657B8558A584E6575FA829D2096329E60549EE31EC47CD5FB63250F533C7EC30607C5DC61DA29\ +83BEAAAC9CF2408ED2B31B1A91169EB3E59CA3366C24EA09676AB0A48DD3F403FE7B21802AB8140\ +8DFB20FE364F13ABCB986D09FB45CE5F5FC472ACE2C93C66", + // ML-KEM 768 + "CC1160B24F3AB56D7E3EEF460A2AD73D0E5B50BC5FD6E06D74C80DF6295A5E7FED8664C9B8\ +19ABB90BF1B2481CA3958EDE019E5A8D215E3C3B2FC662E6A6E5F4D6CD36C30C747745FCD8F8556\ +0645EC010987B87A7B42E619F388FDBB9DF0B916A01AD0640A9B761A9353DE373033EC5E2D16B59\ +DB508BA33259B9791691FE35B2F08AFF381BFC9A74E380DFAC915B6165ED8C276DC7112FD36B7C2\ +1710AC6A2201179642BACA216C3D4C39EA74E75A370B9ADE85A2AD8B00EADCC4AE2B3819374FDCE\ +01F4AF02535194B88933ECE5A9B90C1886EFBCF40B1505D4D2603F7FED815F3B101664A90B239FE\ +598E90C09069E102C500912C71F53396EA1C9035682C9ECB1627193FDEE803078E4CAB436B6CACE\ +8A861AD95B5F53E6C9757EEDD7FC9EA369089E82D2D32C95209460BD880C7D856DD8BD589E131C9\ +91E1148B5E4139E7F4EE32B25DA676FCB279ED94D9B28B6C4843F07A93FADC1314869D2E271D90D\ +993E4F5B654157BDBF45215D691AFAECC498E9ADB3A798029C2D68665878634E02B34006BA953DB\ +444203C88C4523BEDCA14358E0B129BC712EAB69D1C253C490DD4E5F751FBA1B38BA200A3E73E78\ +299306855237C6F72B15598B2EAB30224A22C2C7883C6BEDE636C4D1C06ED0B6793E4609969CF8A\ +442614C8C547598C26CC848BC4593E24591FC85F624548A1D01EA5BE04892C5C12EC07F70C8CA51\ +C4CCD1C9F061EE1BFE07112C2577552966EB25759E77882F1B5B327964E6269E36C1D5AC9C94B01\ +D891E1B3AC2660C5D99E32364AB31015986352ABB20A228C358A548D1B413FF534550F2EE0C80E0\ +741B7F90DC22E8D701A44514810820A5A1D5EE62173283F91DAB585615E36A520FD7540FF7E7B9D\ +6F2FB616251F1D2B6A034AF6427E66D559D7E04F1C7C22FEFA5F3F7B256D7225D5F683FE2923875\ +4D66E10687290675202CD15A32A7F71B5750A95BFCC183D2C26BF31D41225C04FBC123683FA911B\ +994C5B9AE5172EE9847356C67302E7C405625543B7FA82D9BE737467F7C000F97FFBB647500DE9E\ +E36A266F97AE83AB58D239533C8A2FB440E649ACDF6EFC8D98BAF10A1BFA0F7681EC9708BAB9D00\ +A78FFF74AA4C7099D6DA69FBEE2B7C5EA7CEB04527D01CA2CCA8416181BA450C2519A8F383881FF\ +439DEDCE45BF0117CAC0A612E52AD1A3B2F2D1C9917264DD131813F3D9F6D2D574D6CE9AA0943AA\ +7E84C9BDEC515B6827921366794FE6B9058769ADCB3A14593CA49A866DC7AF5BCAF2A48BB06271B\ +3948CC64572AE3A9D46A1209D3E70A02D50AC3CB0AA1B820F8EA25DA127931406AAFC9B00C0FD90\ +C7597321586694E35EA291A88665A2FFBAE5C9BE45938E60027C6C6DEB384F873457B5B5C710765\ +1AE0273DF8A23FDFF74A2A6BD67703854FA5E115712E84D6726F27370FDE6390B362142FCD93647\ +BD2D7A3927DE5F5040F60E17C39D1248F6662CF441EE4B2470CD412050CE09EC31075001286F401\ +A58FE6217000D6A9C8BA753C4CE9D1D8CF8B908614DF0A81", + "DB3D4F38A49CC5C1C7766573873F3926184923F570FCDBA6D7086BEA39601FADFEBABB2F9E\ +D0EBD86A6468BE03D3B05713DE50B5E5D58FFDB5500F2AF7419682BC7857870D1E624C2B48A7E0D\ +30A91F141F0764014FBED12A9F72C958EB53A7ED4A1682578B4348A05C183C790FF56D66B23BD60\ +1FB372C771F52045E13CA2D6DAB80A165A2159B8F990B5BBF125883DEC0A2AF4A54C3F386DE4DF6\ +EE96923E9BB2551753DDC6D1F00D7EE910835082C6260974D11FBA49951DB2E27B47362EC4EBF80\ +4327AD968201EDB71BDC8C32887214FB2AAA842AABBE0A4E03FDC695B19610377B9BEA9D3710166\ +74E977E9E45382D236365EFEDF566659F9936D9D14CA8595DDF121AE7ACC6056DD6FE1B58DC0F0B\ +23CF5366D2488C4D6361B09875242B3A39374159CF3654ABD25F8B080BAE117A5F77D15031AD8B3\ +50C6922FFD426EC9F9F80A1918FE722CB7A4B537210EF8A5538A52048BADCE3CAF5C46454EEAF41\ +3819D57EFBA834D7017F9343B302679A0A28F532E93FE8C5B6AEC3C42C160A3FAD20FA2ABADD29C\ +2564DB59FA25A11CA502D11421F7F080A616F9656942932E11BFDCC47B1D8EFFA81D724FFABF461\ +3830631737EB7E52DA78A6B026DB1C4FB80BBF2D8F9393875330B2F9C1A124436028BF2624C1E64\ +797ABE2E526967DD99BC21B555A5833A31ACE7969E3ECC64C1697DEC0B074108F6B17EFA2A51792\ +3B435D8446043FB1A96B2EF3B3D3952F08657997D1D9169FFD14316185EC30457E0FAF7EBA2B5A0\ +2A01993EC530BB9C44C091D2E9D9BC82951E577D76DC2757F2E04E822B6A29F840887A297202E73\ +89A0999F9E69255DE0A33AEB8CD0B21B7F3B5AA7BFD864CF8FF4FFE78FFF166CAF1B805464D5E4B\ +60EB0277E3BA4F3F3390640F5F16E0B784CC8A67940977B2F0202D37A74472161589A7B9E7721CC\ +532904A17AFF8FA86ECDC46A410BD6F9309B2CC310D7941A02A5720CD64241B5C13C78A86010805\ +AC74C3B81D83348C63C410451BD2052CE764DA83CF80B2654CB1D033F259DA36039E4DF1A5C4CE3\ +F8613E28CFC2B25EAE2A21B425B44D0C998977B3ADF5156BFCA1E357EC3F6B5805B2CDC4D46A4C8\ +3154AEF0F50D493BAB0BBCA130E92CA21AF8BDF817F7616B55C4C24C066EBF896F39A7BF50A2415\ +61E578BDD931CB07EADD193986C455F8798AB97B8D732D37C796E09C1C7ABB978BF666CED961373\ +198607AC355FCF6903B4F3047A1D97C344A2D8B73DB310769CCFB4AE3DA6C4E82DEB83BF4060722\ +D9E5A9AFBD3E03B4517E3B7D563F31821D5D8EF7F06F0D92A9F401EA9BEFD52CA8DB331360E603C\ +14A340B806155DE690CD2D92EE6A8EE53BCEED7EEB308D375518C851C109A03EE61960D6CD7CD1F\ +DEE5CC2A401039A15EE4F97A73400801A090FBF09BE42119662D06C3FF8217FCFC2C70CDE6E1C2F\ +9A396A2E08A3C22AE3CE90A5C97C9F69EBC1546898A047C9DCAD128003A90B29B62F7B093CC90C9\ +CD38104C1A3CE62BEA6A3646EF7E3B9FB7C4C44E78FF650C", + "535C387DD4843B57BF015986D2BC366C08FA21A6A3A615A35D82FE8FEA39968C4F6807E2EB\ +EE361208EF9AE25D6E3109A0360CC7802604343337268FF3D91E0F397A0A5BA525D9C93FE897537\ +A2EEE5D261B6CAA466E4FE85071B9DE1A1A8B3E9C2FF9D5ACAC679D101592FD2DFED7E667AD5E0C\ +7FEFC249FCE1431E674D1128E955040DFB6E47D2435B4EF99F1ED38FF688743AC8655BDBE4656AA\ +4E6CCF626020558A99BE753C8974CEDBC9CCF494DF5885B2628FAE4BDE6D26346C2B37BEFA5F1B1\ +F584EBDA4B38D4248D5A3C5BF1ABFD79BF9601F27F9BCECB40DE27B50A8B3FC8F6F9D4375FD5374\ +1DA0385998FBC755550DCDBB92B746EAA7197B903043545AF0792822D1DC3F12E6A3EDAE3C6B9AC\ +81CB24004DBC6C9A7CA934927482E5D13E88D5DDAE92CBD59FB9B1285B3737CD9194A2F33572EAF\ +E02B02BE27B99F283861FC76CDB1239AC0335FC0DBC781A493AB4565BBE01685A58B13CFF22C995\ +4693D118A82948982927B880C790A6420CDC07A5398268EEFAE2BE89B2CF2F13DA535E56D4A046F\ +88C6C34683770ABEDEE2D19F0C24790F83E8A60B0545A75B2BF0ED1308968623519A4C2B12D7B53\ +98FACF4E4963934B96E064144B05CFAB5A2AAB4AF2CF0D226DDBCBE1C2C46A7300B2AA0C69A6D0A\ +0521E1CF3EA836B30F3FA0014141ACAFEDCA5A2332FD083EF19F196C19C273EEAE4EAAB0E67DC0A\ +72910C1FB1BE49F9A71B86A42EADF61ECF08B013A89D1FBA22F74DB93224ECA79D8576B6C97525A\ +3523C24C99B5206722DF4658F2EB8801D9BFDD89D3D87548073620A8920065CBA6D5B0384CCB70D\ +74A6EA328B0FCA71BD4737CD823188AAAA9D0D4534629420214881D1C93FF778032C5FA2A8FDF3D\ +5DCE1C56F8009182FF95FF201ABDC410AFCB031290D3B5710BC45C9F9426A9C41C1A322FF723FF6\ +794179186196648AD7939730189A4C60FA579709E838FE82DFCA775B7CC678BCC14DAD3B15C112A\ +1CF9F432DE281A32DCE0C02370F524B74DD21EFEC5E8A6AF2245E5A3385E8C2C98400FFC1310AC5\ +A7946D929EDC9FF6ACCB89997EA6AC8B1823F008C93526E9053663E5E049B2445EA2009B9C77BC2\ +7D7F99069F2BD9C226118BF510FB20CC9C5E9F08D68D9B3C2E95E594FDB50954AA371CE263F74BB\ +ABFF660218162056C1C60EE679D574508432D793973C9B4B3432DF9A9E8ED784B3274ED00A2E414\ +5609AFBC7DBF6A98CB706EE3A6803A04F19207556E70B55BD12A4D4F3DEE0503369A449EE031486\ +7940ECB4ECAD36C8F9799ADC88F9554E4359AB1D270B58B590411AF89B277AE885773A8E9F3BE1C\ +239324C68EE6BC45728209FD2BA20A01FA8D214F502C34FA4C1449C13B16627C1F8E26BE1313291\ +9D657B8558A584E6575FA829D2096329E60549EE31EC47CD5FB63250F533C7EC30607C5DC61DA29\ +83BEAAAC9CF2408ED2B31B1A91169EB3E59CA3366C24EA09676AB0A48DD3F403FE7B21802AB8140\ +8DFB20FE364F13ABCB986D09FB45CE5F5FC472ACE2C93C66", + // ML-KEM 1024 + "7F69C89494C15BEC8C947DC8B743CFD1873ADDE5AF6645F7A8AE24054A7D0931045168298D\ +A2084C7422DBFBE9E521393FDCE998C5A36B7504FBA632DAAE5A61107D0960B318A588D05DC8A65\ +C3FCB8270D2CEE48D35C495C8609343C88FB4D118EE42060FA6AEE25C784ACBB24E5A16445BAA79\ +78CD87AD8237E97432896B592BCA55E82E4B30A654DF55B2C0C89FA0C538FB32C739E21C0BD1D72\ +B3E9C06CA06794AD1F36D95CFE3881620FB224A79EC0875663C1F187AA273806AF4DDEC68FA2A1B\ +62DBD9BE5C849E146C3BECC30C3F8AFA8043881567F8B0A121CD1A5E4CE82E1D081B484D1531AC7\ +51F803BA5F6AC86F43987E6584AF03A077784B797B62496984812C1703B38E4D2CE5BB05E0D0D9A\ +EBF69B20DEEB30D049DFBFB866FE1A7B177CA97C0A6B3FA6F4F98079A29D3D83980F5AFD4F58DB4\ +E11AE73BF94F77823247D406D3F2AF9A095FC097DF5AF9C34A3C566F0BC9879DCA62EFC055E05A4\ +3EF554E9246618372DBA19044DFD6C5A5FDB858F46B50652F1FA1AE6EA6D27FA07658A8A8FB9B49\ +36BCE7D3A1A54B02E2E4E9C75A62A5CDE9501A075FFD7B8E553BAC31245A43610AD857A9C902C77\ +FFEB71CD35C934C61D4C984D6512B54DA034217A076C3EBE7F92D42F2BC76CC1723CF77A6844F54\ +7CFCFB1B6BD1F8A827037D58C787EC5BC2D5D01786881EDE0A9BFB265109B83D78203B13F4E0D3C\ +89E750C8DE284074B7971F1F45595D48FA2E88CDB72AD6BBB97E5E3B1D8E0ECCC29CDEA9EE62C29\ +2075843AAEA9484FEAC18E87B91716893CC8F79D8432722DC9F1581BDA0F81446E677FAD05F6DAB\ +03799FB3C011512B7340DBD8E2D53DE29A29937299D856D3EFE62F11B2BCE098532029147719010\ +7AE93526B3E7F5F804CB530C9B1DE20783CC39E45C7A972935C18349312E900B25C4C0F1D10D51F\ +712CC756CD9A9883C63D36C00DD67ACFF79E85BAB91A8A286F1F63FC398045361B91C02DF423DD8\ +165850EDE70D3DC63B315451B06B7C72926E136D6B80C182EF4E49B359D2B88C91B01EF84DE222E\ +A9BD81D95EABA7A1F04465EBC29481BF2845606745F95F0DBE07BB0C2B0FC760D1C77CAB0F7A186\ +0C4AA8D27133D3A8F903542F1A89B0C6B52AA07BB55ECE46A3FA9455252A28649F6663E05D80CAF\ +912B9836052EE92947178C40676060157005DBF2784B0287E216F012626DD7FE14D6BBDC20B1F9F\ +FCCEDB95C61E3C0926940B2404C0228AB2153DC8097ED58C2B1CDA0561464CC572F2CECB10FF31E\ +C4F3C29016861698D5A0F5D1FBABB20AE33A4CD0D25B8077B251BB6169E5F3E0DF72F0F1F5EE52F\ +90992772D80B34BA88AAD0DDE27948D9992D2AD1EA58EDC45615738EC7AE7A5E1D765C081C64AE8\ +F3BB06F0FC8A64402837618BF209878E4412C9588983C2E377233D0C8920C87A0823E5B51355CD1\ +5D4DB4C071E956D3B9221BFC87A78B3CAC2FCCF2F7FD41240796D776B0C1033B42E902EE5B16705\ +D0F2548FC80F3CBFA6BBF76F3E2948AD5EAA1197D1E3B046DD2FE1652CBAC9892D641BDB5915984\ +0AC3E5811D887256C1920C16DD1EF4DDEBF61FD312F88E2ABF214248FEE41C14DDE538777B5592A\ +3CA309DB8425A60C91141D8642F6481364393627FE6559D096ABF4C26D8F3595A22F8D0A3F96125\ +8DD3F9387855AA9A5A8829A03D53635102542FDB9C99072F80A236B794032C4C29851BF8C297D70\ +7522BF9BCC1697FE238064C1B5E8E7856D3F4F717CC18BEEA8371CC298DEC7695ED4D27542C06C8\ +36D771DA487A78B390EA05E4C14CD5D5187C672E77472D18FD0CDF6991C9F84A46B6331B9CC5318\ +122F3031A31AAE17FFDE3CE93961C06D1EC341F4FE0DCA70BE68CFB2C76F7E8DB6EEE20E66E83E0\ +4CAC137D1EB731A291B68BDC99918B3EF6FC39516F6AE4F07EF9DFE0747701AA86CF78F567C3B3A\ +A993D95249AE04AA4FEBA2B9C484D05652F1C22FCA8E94045BB3B867CB245A9B333F2C7639B305E\ +033E1515FF4FCE8000B1039ECF555400D51DCF374997B9995DF673CCE2D071754C06C03B7D07696\ +807700191C9ED579031FD5362D32FA2043B35A90D1171E68FA562DFEE5A1E4B9CE8EE3ABA0D55D4\ +B24405794A63248F2C5AFAFB4AA94B91ED3D95EA7205AFBBA6B1735AAAF5F8DAACA081FE097B58D\ +76E40FFE6F906FC58D92EBB1BD9504077D18F9397A7250EDA9E6E2920267", + "069BD50C6D7A5C549DD1F2C55A99BBAD9DFB566DEC63024011C97D19BDAA9D855D217686D8\ +D7A6863B90696DBA7B8F8C40C30EDD5F2D622A119F274EA4BFA4EB5073751126E68C1F2FF5A69E7\ +2C9A2414DDD7BE9F70815EFCC0F0D0B745217A65B6E5F3AA9CB634037804507E80A67949E81938B\ +0017A7D65602708297695DB01DD3778154A5D644F5F294493503BD6D0DBE261E92C2EB19C8BC182\ +9FB14B95C2532B5CCA04B3F84E696C3F0BE6118DB84AAA9415E34BBB80F134E40DE6CD27C61B689\ +0C99D7B8F3E5F80E20BA96EE31781EFD25670B62CCB3F899C626BCB735BA855096EEEE45444D2B0\ +C3281C3B9CA0F69564469DF843398E3FC83EA12DA069893ABB72236B28F8547F2B73F871B329855\ +1FA263F60D17A3D46C4A3D9E854D7DB3316F724E088E85F5191C721E7E1BAF95F4F68EE61668B27\ +0D0873977584F0E7D109078C8135D8775816402FA8F3C9071E0488A2EC4AF00398A8BA619B4C8B4\ +BA1841CAF8E9FDE44A80D2F46417EF529BA33D4CDF69A8F5F8822C7DF18802C1865DF6E094E487F\ +992B19AA2C770E1F1A63677A6DC7EDB1D19B5E4F4140ACD6AA79C2826EBAD4D29CE7A75C2500C3A\ +96D5726CE038C05D5A89371D4221C42474558C95CCE44479AEB2FC7972ACF43A92B86FE284A03F0\ +258588397492B13F0E186FB30531D66E566371218D2D90920E997420570EC77AE1B5ADD185B05C5\ +732545A86D0D2959E30C4DBEECAD5114EED7524444290E0652A502AF1BF3F305DF79304FFEB69D3\ +C21780262E398B002FEFB1BC849403C17E6E418B7BEE7137E8C4BA83A05F1451DFF70DAC548C26A\ +DF5F0FAA2170388DE2D2D5F4A4201ADA19EAB0007D744119D18F948DCCCC5D1A455E87B39A4C6DC\ +9EBA7965423C44625AA34ECB175F288DAA832390AA98508467C7A928CBC3177E9AEF32974697085\ +CA8B9F4B028D1F7E0EBD0EC3E8C40781D399D041CCBD29DCD6357FA32641F9B24EB4D3F6F331CEF\ +508A29771DA72DBE343D934B177625AB3D90D9A14986E6395E4E6FEDB7567016F0F9F14776D19BB\ +DFBA46C083AA5E32CA62C8961499C0FFA9FD726331E426BD78CCDEE5F3C6BDA448C0A0A84BEF5E3\ +ABBBB421840D45D9D22B462DCF23CBCCDF72D45680D81DDABA76AD63F997978C9204D2F3FD49F54\ +FDB34377753ABF6BD1B96AAC1CCD90A13DE231F3529646FEB01715BE5F541BBDFC30BF6941E65B9\ +0CCA98BE3F71522AB8193098929BAF22E85C4DC4F04A949DE89363D8080FB1131AD0BA0645FCAF5\ +83E3854C53DE82E2711EA60BF90F72F97F3BFBE2C4DC6DEF6B1DC1ADC96C68484DE80AF9B9CAA66\ +686754FEC89E16DD9C8FF6D91262558F2FAD3B60A90C5FB7B57C12629F70CCE9878FBD649797796\ +9825F9B3AA45AB186DA85B5F30FD46127C911E5AFD2899D0BF291B106686EAB6A4EF6842E7A7674\ +152A7F42D831FD467CD71B3E5E49A89396FC3ACF6B79D6F278DE1DA94AE8C56738CF41AA2307DDC\ +156F88C9B6404AD4F7AB8826B4A7B109051662C665BA63D37B29650E2376CCF7A433C9426F5A327\ +2448A3AC74773ABE0D9671EC234F3CA3FE174BEA73E32DB3EB7F16EEE38E8F5AD8826B6D5ACA161\ +E463BF2694862B9E6238BB72EA8AA73058053615AE7AABDE2B57A69FA5433953C908E6543AB335D\ +415B600CEC73FD2B71E197D820B7B3B80F6ED068FB78156889ACCEC02CFBB729A98DE42CA955F69\ +E15EC64B33C70051E7E32FA30FAF76ABFDAFE06C01E8C2AC3AC4D4498FEA8D34B914ADEAF54C679\ +971E05EDA66895FAD91CC754382C734EDD5D9E85C38A313971BC2FAAF8C562C272640CCADD0F3B3\ +4D318AA06A8489DBCE598DE7A686566B4B989023A7A45672B2D0A0233F2C67BD81950DBB7677457\ +8644959725381A402BCDCB0843546C3FF67AA433D02C22A7EAD87FB395C501B53C25B4E493A07A0\ +77A64972A558D57239834CC2FEB31F49E7272B79122BEC47C5A1C870E89187A679615167DBBC20C\ +93992A20AB79833681A103BBEF5C44F7326EBD0BB4AD367C1E0BB05DAFFE6BA5688F5635A857FBC\ +5B4F7A8B2AF103894EF49692BF13EE91E4ED0A453965656B245EA879B303C27CA30FA70CC50733A\ +205A5EFCAB769BD5442C3882FE5D2E71E8A80CE6867C5F501ADF0E053CB8963777A89BBA8A190FD\ +C2F0803510244FC62834AE40215C90EA76F4860567077DD4B45EABB256BB", + "F82392974467D1DDDD19CE29EE8ECD1A03178815A53839E00B8F8A98D34B32615F3B9DC4BB\ +F7E8C8025DACF7EBB01F90519A58939A8C576A1C302750CE2F7CD5C9A26410CE8F627CDA7FADB99\ +FC85A2687EA4A209959E2D562343F1AEC5031B460596A69F5F5B16EA22A0D152F6B16D62D1A1C1F\ +8167850217F8454E923A1A52B93D2DD36DA5C196498B69B94C34A74336B9CF27C545C878688F84E\ +7F9863D52C87ABD3CA30ACA781896EB77432EAECE2C76027E6025B25017A0B02ED6C559E06A7F27\ +E19CFAF39EE184A5C5FCF7137C58093466ED28B8A8F9C99B8823156C2DC6CEF755AF978B14FD1DC\ +797CF73047DEED138562F468C940A3F266AFD6ADE448D96062BE6B407BE94F137B0A42FA5B124DD\ +7AAEDEF4423776DD643C78148939A4F1DB5BC9CA7C270D9287D5B531EAC41FC4BE3A127C511959A\ +CEB8931823B6D4FF7A5B4AEA6406B854D8B7C54D4A953D554DE0855214017D379F97440787B1076\ +F71D54C7055256BE69B761BE5BC7F1F471592CFA2D7BAB779B8CCD3D13E208353BC7E48BC06D561\ +F3151DE61E4C58087844E036B0C1804919E13648152CEA8ACD62736661E7EDED2C126873B10CD3E\ +6AAE80C73714359E2ABEF4D708AC856AD64389E92FC9D60400410E51007B94487F6D7C7EFC2BD26\ +4E315A27CFFF6B66E9F776D6A600EEE00B9278C411A7FD3151A3A8EDC4909E4B9AA4FEB143B836D\ +CEA125166B3F6E969A71610B5011E94D1D2460D2A7F0D12AF9D449F791F8B54F5D3D635F473481A\ +082D7A7E299CAEC87FCF9311C6D52B178EC71DBEFC38EB665B1460CCB54AB81C6592BBDCDBC3EF8\ +408253FEFEE270D12EB65EC0F357364DB94AE6DEC859BCAFC18A717C7F0CF8EC3F459773DDFB2DF\ +789572BB545BED09F60DA1DA0CFB1F6219242E6E719E4422475B6466094A211FECE1653C3978927\ +25F93E148EB13F02502A20B8A8FB836493132EB4DDBAD06DC2240ECF1F1F8B8C1A99ED877E19345\ +81B96906C0E917EDBF520BB68AC5E8561A643C54CCB385E6C760F6BD37C2AB7E79BECE3902B4BF7\ +46313A236B81A70E7613C95A8E2ED3BFF41E7130B9A0C8A63717E703EF30AB8500ABFFD0F377FAA\ +5436910FA8627B3C8E0BAB4226F73E542A35A2934EACA4A6E18342FC322A150BC99A68385F6D614\ +21704950E717BD26FFE0D0526F825A8AB4E0562C581B0548C3B7E640C71C981B1D224608333AE70\ +07159C199149E3632E43915CF04449AFBF5A5E0929B187279BA227B59B0C75F988B6994245053E3\ +66B47ED3ED8C504DC060F2165B9C657CB767AEA6C14FD5CFE942C4D9189684F812DD3096A1FC4C4\ +A3BB6EFA63F3629AEBF2494EA6E544CC18FD9C2700CDC3816BC76754EEEBA41D836E10280C081A4\ +278F3F00ABA9571DED482F57096950C42BFEC563A154AAE0CBE8D57A9E5FD813BD021AA6F2412C6\ +414539B9E7D5B3A89C8E3D3FE0295A2E6D473552D11171B51C93F35808A1F574BEFEB37C4282EEB\ +95C506EFB0F982984A68422FDFA2AD0B570B57DB2138BD6CD25407828D4133DB6B91AF5E372EE71\ +FB2C4FB57F20FC83B5A567031CA23BDD0C9AFFD8946CC13B16FC94D411EA021EF50ADED2D0A9A0E\ +879F8AE48ADA145F1C7729A5C677793E865D16207D2F511EF000FBABE35EA6B4C9EB94A195D1A1A\ +4C42269701D3A7172A1FCBA71B2686A83FC1B5E2771A463D2B852F464217391595FEA32023E1CC5\ +A0C78529A4F989D62B0CCDDC33EE961614A71BD001497037E7E37B7CE00884E387D9314B8612A45\ +BDA618C4875B5B7854F2B46B1231DD3644F1406BE71620F2EC7D98763012A1620C5E31E96C8626A\ +BB4C76F6A8A5655E5D224AB314075F196DD349B2387FC307916DCB532894F87337BAF4197E168B4\ +30280A63E9BFFFEF57F88E15799A42F5BAC68C2355760A4D3603F72760D30116F746CA56AE59E61\ +1E3A0F4DCF179927301E77E149BAF8CA839F97C2C6CF61409285DF9D5BD947F3D7B97E7DFECCC5E\ +ED111D821EB1E7DC5E71B9D74E5CC0640A89058CC4244183F0700E1A882A6175FFFFEA9A10B0650\ +A5653F42E09B1DF35630914D98331B897F58A3352EDF8DDAECE3D97AE2D31C0E58D929A6CDF96B3\ +B744A0BE91D3CD19339A93997329426536D7FD2081B620CD6B136C3823744AC3C2B133D5851AA89\ +7C5EAEF909E06DBC1173F69D1DAB5121D0C95810C500428837FB3E40F34E"}; const char *strk1[] = { - /* ECDH (NIST P-256, NIST P-384 and NIST P-521) shared secrets from - * NIST CAVP SP 800-56A ECCCDH Primitive Test Vectors. + /* ECDH (NIST P-256, NIST P-384) shared secrets from NIST CAVP SP + * 800-56A ECCCDH Primitive Test Vectors. * http://csrc.nist.gov/groups/STM/cavp/documents/components * /ecccdhtestvectors.zip + * ECDH (Curve25519 and Curve448) shared secrets from IETF RFC 7748 + * https://datatracker.ietf.org/doc/html/rfc7748#page-4 + * ECDH (BP-P256 and BP-P384) shared secrets from IETF RFC 8734 + * https://www.rfc-editor.org/rfc/rfc8734.txt */ "057D636096CB80B67A8C038C890E887D1ADFA4195E9B3CE241C8A778C59CDA67", + "4A5D9D5BA4CE2DE1728E3BF480350F25E07E21C947D19E3376F09B3C1E161742", + "89AFC39D41D3B327814B80940B042590F96556EC91E6AE7939BCE31F3A18BF2B", + "46FC62106420FF012E54A434FBDD2D25CCC5852060561E68040DD7778997BD7B", + "4A5D9D5BA4CE2DE1728E3BF480350F25E07E21C947D19E3376F09B3C1E161742", + "89AFC39D41D3B327814B80940B042590F96556EC91E6AE7939BCE31F3A18BF2B", "5F9D29DC5E31A163060356213669C8CE132E22F57C9A04F40BA7FCEAD493B457E5621E766C\ 40A2E3D4D6A04B25E533F1", - "A23742A2C267D7425FDA94B93F93BBCC24791AC51CD8FD501A238D40812F4CBFC59AAC9520\ -D758CF789C76300C69D2FF", - "005FC70477C3E63BC3954BD0DF3EA0D1F41EE21746ED95FC5E1FDF90930D5E136672D72CC7\ -70742D1711C3C3A4C334A0AD9759436A4D3C5BF6E74B9578FAC148C831", - "46FC62106420FF012E54A434FBDD2D25CCC5852060561E68040DD7778997BD7B", - "3D2E640F350805EED1FF43B40A72B2ABED0A518BCEBE8F2D15B111B6773223DA3C3489121D\ -B173D414B5BD5AD7153435", - "000B3920AC830ADE812C8F96805DA2236E002ACBBF13596A9AB254D44D0E91B6255EBF1229\ -F366FB5A05C5884EF46032C26D42189273CA4EFA4C3DB6BD12A6853759"}; + "07FFF4181AC6CC95EC1C16A94A0F74D12DA232CE40A77552281D282BB60C0B56FD2464C335\ +543936521C24403085D59A449A5037514A879D", + "0BD9D3A7EA0B3D519D09D8E48D0785FB744A6B355E6304BC51C229FBBCE239BBADF6403715\ +C35D4FB2A5444F575D4F42", + "5F9D29DC5E31A163060356213669C8CE132E22F57C9A04F40BA7FCEAD493B457E5621E766C\ +40A2E3D4D6A04B25E533F1", + "07FFF4181AC6CC95EC1C16A94A0F74D12DA232CE40A77552281D282BB60C0B56FD2464C335\ +543936521C24403085D59A449A5037514A879D", + "0BD9D3A7EA0B3D519D09D8E48D0785FB744A6B355E6304BC51C229FBBCE239BBADF6403715\ +C35D4FB2A5444F575D4F42"}; const char *strk2[] = { - /* SIKE (sikep434, sikep503, sikep610, sikep751) secrets keys from Round 3 KATs, - * https://csrc.nist.gov/CSRC/media/Projects/post-quantum-cryptography - * /documents/round-3/submissions/SIKE-Round3.zip + /* FIPS203 ML-KEM (ML-KEM512, ML-KEM768, ML-KEM1024) shared secrets + * https://github.com/post-quantum-cryptography/KAT + * These tests are used by AWS-LC https://raw.githubusercontent.com/aws/ + * aws-lc/refs/heads/main/crypto/fipsmodule/ml_kem/kat/mlkem512.txt + * NIST ACVP test vectors https://github.com/usnistgov/ACVP-Server + * do not have matching tests for ML-KEM.KeyGen() and ML-KEM.Enccaps()/Decaps() + */ + // ML-KEM 512 + "2B5C52EE72946331983BA050BE0F435055C0547901E03559B356517889EA27C5", + "63DFB842BF767F89717839642A9B92FCCF82BF46A9F39BA1A3292995F3F934DC", + "135B9748C6AA6D1AE9B5420C72679FF65CAE622B8A7DF54CD7650131B5FD77F8", + // ML-KEM 768 + "D71BD5A07C158C130283EF854516D290A46ADE09A63831C7B83B8FD0724C8FB0", + "E3E4F4E9D4F5C9AE03836BB9266C50B033285ACE9BC56F73817CE19679D1429A", + "73DCE41A9BFCC57EBEBA4A9F161800F3ABF1C38600F3EFA9A32EB8108819676F", + // ML-KEM 768 + "D71BD5A07C158C130283EF854516D290A46ADE09A63831C7B83B8FD0724C8FB0", + "E3E4F4E9D4F5C9AE03836BB9266C50B033285ACE9BC56F73817CE19679D1429A", + "73DCE41A9BFCC57EBEBA4A9F161800F3ABF1C38600F3EFA9A32EB8108819676F", + // ML-KEM 1024 + "8E012F050FCDE79D0913E1654A7D939A835A4A57943E13AC0FA2541EB3245BA9", + "F36ACE28D4F9F75AFE8FD34FF02AD6C402AF33567C5B33F91E5777CA74F8C840", + "9CC4ABFC04234C2FD68362D14C2EA03342B0D777A7BE4222594F768AA8DDCBB6"}; + +const char *strSA_ECC[] = { + /* ECDH (NIST P-256, NIST P-384) private keys for derandomized tests + * from NIST CAVP SP 800-56A ECCCDH Primitive Test Vectors. + * http://csrc.nist.gov/groups/STM/cavp/documents/components + * /ecccdhtestvectors.zip + * ECDH (Curve25519 and Curve448) shared secrets from IETF RFC 7748 + * https://datatracker.ietf.org/doc/html/rfc7748#page-4 + * ECDH (BP-P256 and BP-P384) shared secrets from IETF RFC 8734 + * https://www.rfc-editor.org/rfc/rfc8734.txt + */ + "38F65D6DCE47676044D58CE5139582D568F64BB16098D179DBAB07741DD5CAF5", + "77076D0A7318A57D3C16C17251B26645DF4C2F87EBC0992AB177FBA51DB92C2A", + "81DB1EE100150FF2EA338D708271BE38300CB54241D79950F77B063039804F1D", + "7D7DC5F71EB29DDAF80D6214632EEAE03D9058AF1FB6D22ED80BADB62BC1A534", + "77076D0A7318A57D3C16C17251B26645DF4C2F87EBC0992AB177FBA51DB92C2A", + "81DB1EE100150FF2EA338D708271BE38300CB54241D79950F77B063039804F1D", + "3CC3122A68F0D95027AD38C067916BA0EB8C38894D22E1B15618B6818A661774AD463B205D\ +A88CF699AB4D43C9CF98A1", +"9A8F4925D1519F5775CF46B04B5800D4EE9EE8BAE8BC5565D498C28DD9C9BAF574A9419744\ +897391006382A6F127AB1D9AC2D8C0A598726B", + "1E20F5E048A5886F1F157C74E91BDE2B98C8B52D58E5003D57053FC4B0BD65D6F15EB5D1EE\ +1610DF870795143627D042", + "3CC3122A68F0D95027AD38C067916BA0EB8C38894D22E1B15618B6818A661774AD463B205D\ +A88CF699AB4D43C9CF98A1", +"9A8F4925D1519F5775CF46B04B5800D4EE9EE8BAE8BC5565D498C28DD9C9BAF574A9419744\ +897391006382A6F127AB1D9AC2D8C0A598726B", + "1E20F5E048A5886F1F157C74E91BDE2B98C8B52D58E5003D57053FC4B0BD65D6F15EB5D1EE\ +1610DF870795143627D042"}; +const char *strPB_ECC[] = { + /* ECDH (NIST P-256, NIST P-384) peer public keys for derandomized tests + * from NIST CAVP SP 800-56A ECCCDH Primitive Test Vectors. + * http://csrc.nist.gov/groups/STM/cavp/documents/components + * /ecccdhtestvectors.zip + * ECDH (Curve25519 and Curve448) shared secrets from IETF RFC 7748 + * https://datatracker.ietf.org/doc/html/rfc7748#page-4 + * ECDH (BP-P256 and BP-P384) shared secrets from IETF RFC 8734 + * https://www.rfc-editor.org/rfc/rfc8734.txt */ - "35F7F8FF388714DEDC41F139078CEDC9", - "AF1280151C2C59B4D4150B18BA7F71590523CEA83C9BDDDA", - "0A5CFC45865775D0CC10F89EFAD9FFD33A6C8A7AB868309D", - "FEE94595E8A05C50113C044D4D8558DA101035EBBF604AA41D0AAA75B8A7F786", - /* KYBER (kyber512, kyber768, kyber1024) secret keys from Round 3 KATs, - * https://csrc.nist.gov/CSRC/media/Projects/post-quantum-cryptography - * /documents/round-3/submissions/Kyber-Round3.zip + "04809F04289C64348C01515EB03D5CE7AC1A8CB9498F5CAA50197E58D43A86A7AEB29D84E8\ +11197F25EBA8F5194092CB6FF440E26D4421011372461F579271CDA3", + "DE9EDB7D7B7DC1B4D35B61C2ECE435373F8343C85B78674DADFC7E146F882B4F", + "048D2D688C6CF93E1160AD04CC4429117DC2C41825E1E9FCA0ADDD34E6F1B39F7B990C5752\ +0812BE512641E47034832106BC7D3E8DD0E4C7F1136D7006547CEC6A", + "04700C48F77F56584C5CC632CA65640DB91B6BACCE3A4DF6B42CE7CC838833D287DB71E509\ +E3FD9B060DDB20BA5C51DCC5948D46FBF640DFE0441782CAB85FA4AC", +"DE9EDB7D7B7DC1B4D35B61C2ECE435373F8343C85B78674DADFC7E146F882B4F", + "048D2D688C6CF93E1160AD04CC4429117DC2C41825E1E9FCA0ADDD34E6F1B39F7B990C5752\ +0812BE512641E47034832106BC7D3E8DD0E4C7F1136D7006547CEC6A", + "04A7C76B970C3B5FE8B05D2838AE04AB47697B9EAF52E764592EFDA27FE7513272734466B4\ +00091ADBF2D68C58E0C50066AC68F19F2E1CB879AED43A9969B91A0839C4C38A49749B661EFEDF2\ +43451915ED0905A32B060992B468C64766FC8437A", + "3EB7A829B0CD20F5BCFC0B599B6FECCF6DA4627107BDB0D4F345B43027D8B972FC3E34FB42\ +32A13CA706DCB57AEC3DAE07BDC1C67BF33609", + "044D44326F269A597A5B58BBA565DA5556ED7FD9A8A9EB76C25F46DB69D19DC8CE6AD18E40\ +4B15738B2086DF37E71D1EB462D692136DE56CBE93BF5FA3188EF58BC8A3A0EC6C1E151A21038A4\ +2E9185329B5B275903D192F8D4E1F32FE9CC78C48", + "04A7C76B970C3B5FE8B05D2838AE04AB47697B9EAF52E764592EFDA27FE7513272734466B4\ +00091ADBF2D68C58E0C50066AC68F19F2E1CB879AED43A9969B91A0839C4C38A49749B661EFEDF2\ +43451915ED0905A32B060992B468C64766FC8437A", + "3EB7A829B0CD20F5BCFC0B599B6FECCF6DA4627107BDB0D4F345B43027D8B972FC3E34FB42\ +32A13CA706DCB57AEC3DAE07BDC1C67BF33609", + "044D44326F269A597A5B58BBA565DA5556ED7FD9A8A9EB76C25F46DB69D19DC8CE6AD18E40\ +4B15738B2086DF37E71D1EB462D692136DE56CBE93BF5FA3188EF58BC8A3A0EC6C1E151A21038A4\ +2E9185329B5B275903D192F8D4E1F32FE9CC78C48"}; + +const char *deterministic_seed[] = { + /* FIPS203 ML-KEM (ML-KEM512, ML-KEM768, ML-KEM1024) keypair and encaps coins + * for derandomized tests https://github.com/post-quantum-cryptography/KAT + * These tests are used by AWS-LC https://raw.githubusercontent.com/aws/ + * aws-lc/refs/heads/main/crypto/fipsmodule/ml_kem/kat/mlkem512.txt + * NIST ACVP test vectors https://github.com/usnistgov/ACVP-Server + * do not have matching tests for ML-KEM.KeyGen() and ML-KEM.Enccaps()/Decaps() */ - "0A6925676F24B22C286F4C81A4224CEC506C9B257D480E02E3B49F44CAA3237F", - "914CB67FE5C38E73BF74181C0AC50428DEDF7750A98058F7D536708774535B29", - "B10F7394926AD3B49C5D62D5AEB531D5757538BCC0DA9E550D438F1B61BD7419"}; + "6DBBC4375136DF3B07F7C70E639E223E177E7FD53B161B3F4D57791794F12624F696484048\ +EC21F96CF50A56D0759C448F3779752F0383D37449690694CF7A68", + "20A7B7E10F70496CC38220B944DEF699BF14D14E55CF4C90A12C1B33FC80FFFF", + "D69CFC64F84D4F33E4C54E166B7FF9283A394986A539B23987A10F39D2D9689B6DE62E3465\ +A55C9C78A07D265BE8540B3E58B0801A124D07FF12B438D5202EA0", + "0121CB32ACD1871135CB34E29C1A0E26CCC001B939EAFAACC28F13F1938DBF91", + "63470357110828F25B23EDC80ED280ECD398A9F53251C3332754DE2AF0B15E901EAAE6BB91\ +B27CD748C402C4111140D5A942CF3C95FF7977F88D2EF515BB26D0", + "34B961AF5D6254AF72C0D50E70DD9B4991150CCC09192AA46F1953D5C29A33EC", + "89B0C4B23019AF3498A27DA290892D981DD59FA08993BC05DA21E1D72503664CB585D4EB01\ +085111A172A87688D0032E3381A9E9A35FDD6EF2F8AEB3B40EB5CE", + "0F4A070A0116194E267437545569D94AA5B2E4400645D5DE88C504B9DBB1455E", + "8D45A2AB49D8C20D4AB5680E5C9D9D0CC9CA8228484946F9AFCE5B8DF6F39D19A9F93C7B79\ +1356B66AFCCEB745A548C7F6B185E4F45EC1FF1A22ACDD96E7A6D8", + "B3DBB0BF61A5230DC0AB9F1D21D5C16566FF9AD805A5E1EB7B2D6913D4CD5607", + "1FD893BD47ED681C7C11C9D00BE9EAFD9DB79AE7E934B03AA6DA99E019A28A5385DA83B471\ +29711A63C2C2F6A5BCB701237B2B0B66814EEC9FCC1C560992A596", + "EF938DBDDEC94C01A845C7F1192C402F33C10F1F0176128AF219D6A0243900E6", + "89B0C4B23019AF3498A27DA290892D981DD59FA08993BC05DA21E1D72503664CB585D4EB01\ +085111A172A87688D0032E3381A9E9A35FDD6EF2F8AEB3B40EB5CE", + "0F4A070A0116194E267437545569D94AA5B2E4400645D5DE88C504B9DBB1455E", + "8D45A2AB49D8C20D4AB5680E5C9D9D0CC9CA8228484946F9AFCE5B8DF6F39D19A9F93C7B79\ +1356B66AFCCEB745A548C7F6B185E4F45EC1FF1A22ACDD96E7A6D8", + "B3DBB0BF61A5230DC0AB9F1D21D5C16566FF9AD805A5E1EB7B2D6913D4CD5607", + "1FD893BD47ED681C7C11C9D00BE9EAFD9DB79AE7E934B03AA6DA99E019A28A5385DA83B471\ +29711A63C2C2F6A5BCB701237B2B0B66814EEC9FCC1C560992A596", + "EF938DBDDEC94C01A845C7F1192C402F33C10F1F0176128AF219D6A0243900E6", + "7838C35785AFF8B54BE30841ED41A87F420AEE847452A4561CDACCFF5B38DFC0F7ECFC9143\ +EE45E44F5E98FD9CA1455340EC5DB4FB098534365EBBFBCC57D34D", + "9BF84A7839F40FAA71B35FCB695C5F41A9443BD94041A042A72C701F0D1D5DF9", + "859C3E3B13F3CBF5CB860BAD2FC6393A78390B0165800661A8F1A7436787C669DAA360ECBB\ +51BCB33F5D36F92FFFE77C2DE7ED43D281DCB5FD68CFA0CE19DF2E", + "D38CEF643F9C6D2F6A4BA6A784AC1D81B32A073E531F79919912D4DB70B53075", + "23CA80A61C0201F08D6B9BFAE101FA573FAC5581EA3E54DAAAD3AD7A00BE5716AD10AD3409\ +A90C4B24AB0DA526F289209ABCB1F05C86C7E4437A144C91E1C867", + "81C5839B15D7335676DBEEE048F6BCA56C4976331B5DF39A212BBC2A450F4143"}; + /* Derived key_material */ -const char *strkmcat[] = { - "5C366F23281D33EB85CAB026D3D9A35A", - "A808667CC0275AEB4A646E442F13E8D0", - "F79E08982B3D2B7C2D0B27F921CCF71C0E3EE98877DA225A", - "6D3F348DAB7EB85F043288112862AD16A10A70F65E73F171", - "933C64D06F5F3FB02D74530BCB093072682FAFDD64D42933", - "05C6E23AF74E3A8E1B1AA9F599C517468B86AB2068591AF8", - "4DB991EEDA686DDA8CB5F128C16267CC7516643FE5EBD8C6176405C9AB4600FA", - "270EF22EEDE80D0100872E307388027E8E12AE331AB81A27D6D166F7241B7BAF", - "1ACFDC16EEC7C8A669EC6007A4CAAB1A", - "9B8DD1A341ADFB821E32980DA418A114", - "1529723880E3E1777F73F8D89724D323572E56858D3DD732", - "7A954FCF3DE3C845B65E1D6F3CCD6186BD2F10FF83525B7A", - "6A4D002A9B310D6E73D87BF36224E2F41EDD8F75CFF448D59493D65D61C07D8B", - "203F634CFF7D7EC462281A65706E50342F025B7145E03A976640137C89F919A1"}; -const char *strkmcas[] = { - "C1EF63BE6F26F6EBE2078C940AC47E59", - "5C0D6EE9B187EEE46C22EB3C3F36349A", - "CA58B87E512FCAEF2B11B1A1A8550FB4B1C1E2ACF7C364D5", - "007B8F4E6C95851C3598F59484D75A2A6FCFC931B42D74E4", - "DBC55D5F607CF981CB9774E920288ED030C3A13CADD4E594", - "944DC1D2AD91B40E3B3B6D2B19981D8571E27A0C49EE4767", - "109654A3D902FC17C83AD709D436E10FDA9A901CF6A1BDF9A02CB087171A8732", - "70D1D1AF1A736B6C648B7410F728D0AC689E2D8CD54F8B1DDA410CAD566F5CFE", - "A324764EEA9EBA338F0596D6D64DFA55", - "07930E42BCA7B1C60F530DA08A1C85F1", - "45F0EA18A6B22D94139BAF38F3C932277B48B4113A6B4E27", - "220D8F8C87FC3CD29FB1E9D24E5C6FAE4A6E42E085EB2D5F", - "EC38A129393864C9A949365155FD6A6943E30459DB80304EFEB83047B903D117", - "C2D57FA0CF6175F31581634849703060E203346823D091C182B5520F3714A487"}; +const char *strkmcat_hkdf[] = { + "370705EB882B5629F955D01A5FFCA748", + "36C6BDE2BE72B35F3A51CA8EF72489E9", + "3DDF171F7569D9174DEDBD48893D328C", + "99B5DC7F166C3158043BC626DD0C4498", + "701675524E4986A391AFEFBB604AA63D", + "740CB65DD232C9D7804092733D2D7361", + "9E721A4AC9E7BB18562920725032BCA75947882E9E96D418", + "C3C3D576335BF6D31522B3A72A00765981CE67B99FCBE85D", + "833A314FE8BD6326B5B1FD51DD4CBA2ACE5C5F80C9B8D544", + "C65CD95DE189F21CD5726B2D595919461FCF3238DA50D538", + "C2B0B1967FC9C3A75B1D77F32B19EDEE39CBE94796A13536", + "B1E57722B3FB93C71EFCA4C8826C6C5C8BD491827B70A613"}; +const char *strkmcas_hkdf[] = { + "6CB6C62AA34F1E4C23943663B4D48840", + "F1029D322632B91BA97FA308929E61D5", + "2025D7CC500F4C7759A7201A34A9E205", + "B4D24420223C495C2E12A50FD93C05B9", + "2D490429EE1F9F17CB05AE44691CCD09", + "4DF6A0FB71249E97C098BFF8F68C9760", + "33FB725B966F6C2D990B98265B467F6BB611ACF6AD284AA4", + "E22BDF8A0F358DC7AA80BB142FF0FD328DF575352D010950", + "A540725E733D8CCE09BC084385DDD8F03A9B4AF92AD7CF08", + "4AD2FA93C1E58F1DE44D5A6C5ED216F2E931E28A4C44662C", + "EF002D66B13574A50565FD949FA697B1E4E638D422C98080", + "ED94D90E304126A86A4BCD030236A306E2E6BA1824E8D90F"}; + +const char *strkmcat_hmac[] = { + "E5D337DF2D77ECE50E2DAA9E65F73D77", + "8EEC8502D551A1E46408D5673C8CB98F", + "B450CB239F23CCD820C0D4994D260234", + "3F0EC466248B91B18FA82A557C12E0E4", + "56617E0EC39843C6E41935F02A5D7FFD", + "1B57FF0AAA460D55099195DA71A9E23D", + "E26CB07AF36999973DE321AE13DB977C0EF37B18A430FC5F", + "C5AADE55D5BCE6EA33E971EF6A80F32EEECC418F490D1457", + "8C9700BE1498879F3AA886CCBDB513D91E4B73FDDF9ECEAD", + "7335508D7C14D92D98C3E8319773DC2B591245A7E926FAB0", + "A4E26D3B2EACC8E708DFA571CEEE057D2DF870A65F3C4E75", + "D0F6CBD16C466F331BD8E1716679673A5D73AADD221659ED"}; +const char *strkmcas_hmac[] = { + "D696D1E075EA3B435D773C15B50F2A28", + "42B4C5C1162F0E47E004456310D3E460", + "85AB7C8DC9C922368C1F6FF48BE81ECD", + "7E12FBC4071218FA9D7B3DC21A651EA3", + "37A9900F776007E7FBE40A5486322855", + "3530F7B3284AFDEC9571E4F967C8025C", + "E157B71E03BB2D72D6709AEA3DDF8D6A86A248DCC9691B75", + "887AEC133D7D1B967A913F766AB9A61A78506652EBFEDEC9", + "B723BF81451D5A97CF6D9BB58421A94F588BCDD30EBC3710", + "9EFD0C9771DF02CF0EF9E031B3B872E4951D3CCB51B2DC02", + "1BE6EC5DF5765602EC08BC90205F5801B48FCF6797B5B340", + "5F6AC454E255DEDF959D9A92379C05837872343EE6A26E0A"}; + +const char * strkmcat_kmac[] = { + "E0C0450A61C8D41399EC6E977B01A9B8", + "EA6284682CBD30A9E3B0F8E12D82C3FC", + "7B8C1993F70989F49CDA53EE425104FC", + "1154D484AAB6231EE566F303C68B1EE1", + "1B697069B3382C389E30ED03D59D2BAA", + "4AD0977C7B13CC303F80AF94CEF4F794", + "2E2AAD04AAEC48A1E63CB71CD0809B371337BDA451284320", + "396256789FF63394A529C19C675ED76D153E6B26260434BF", + "A4E152F60978ED019D81925026B34AD38BF3AE585871A834", + "D031355CD04CB5641B2427F03EBDE1316317C40202BCA698", + "A0034BE961F28D59F51A2F19EF46C73E178E64B1FF40A830", + "D42F58186B93D75205FAACB4C12E2137432D810332C0E463"}; +const char * strkmcas_kmac[] = { + "C259F87E2ED94BB7B14A7B1671B7331F", + "ED5DA8596698221195B037DD33E3D48D", + "BBCAAACFB0C2D5A118C6065DDAD69D9A", + "A21B0F3D7546FFD4C2A7058AC9AE4D5B", + "BF7487D94D53B67C9F73A40293481833", + "2E36C5A9C64F3B12C5E990F4863A6E5E", + "3375C5D5743B7FD5296D2B637BE9A7F99205513399DBFA70", + "140A796FF48D8676B0827DEC83270A947C08A02D1A2BE6E7", + "F8D21D6F3A76A53E9E01273BE568FE838FA091309041BEA1", + "C1A533E56B5E65CB1389CD027FA16C7F1EFA213E5431BEAF", + "E43B62DBA135BAA51C3A75B55330FE2525AF33C12EA8158B", + "B991336BDE64ACE280989E26C8FEB6E772A662B3FF0567AB"}; + /* * print_array( ) - this function is intended only for use within this * application. @@ -507,7 +1324,8 @@ void print_array(const char *label, const uint8_t *array, const uint32_t alength return; } -/* Helper functions to loads a set of ascii hex strings to an internal +/* + * Helper functions to loads a set of ascii hex strings to an internal * buffers. For example, if called with (array, alength, 3, "0ABC", "0132", * "015AF4"), it wiill set array = { 0x0A, 0xBC, 0x01, 0x32, 0x01, 0x5A, 0xF4}, * and *alength = 6 @@ -550,15 +1368,65 @@ void ascii_hex_strings_to_uint8(uint8_t *array, uint32_t *alength, const uint32_ va_end(args); return; } -/* Testing harness for concatenation KDF with two exchanges */ -int test_hkex_concatenate() + +/* + * Message Formatting function as recommended in Annex C.1 + */ +void message_formatting_function(uint8_t *array, uint32_t *alength, const uint32_t scount, ...) +{ + const char *pos; + uint32_t str_length, remaining_length, i, j, length; + uint8_t * ptr; + va_list args; + + if ((array == NULL) || (alength == NULL)) { + exit(0); + } + ptr = array; + remaining_length = *alength; + *alength = 0; + va_start(args, scount); + for (i = 0; i < scount; i++) { + if ((pos = va_arg(args, const char *)) == NULL) { + va_end(args); + exit(0); + } + str_length = (uint32_t)strlen(pos); + if (str_length % 2) { + va_end(args); + exit(0); + } + if (remaining_length < str_length / 2) { + va_end(args); + exit(0); + } + if (i != 0){ + length = htonl(str_length); + memcpy(ptr, &length, 4); + ptr += 4; + *alength = *alength + ((str_length + 8) / 2 ); + } + else { + *alength = *alength + ((str_length) / 2 ); + } + + for (j = 0; j < ((str_length) / 2); j++) { + sscanf(pos, "%2hhx", ptr++); + pos += 2; + } + remaining_length -= (str_length ) / 2; + } + va_end(args); + return; +} +/* Testing harness for concatenation KDF (HMAC) with two exchanges */ +int test_hkex_concatenate_hkdf() { uint8_t k1[MAX_KEY_BYTE_LEN], k2[MAX_KEY_BYTE_LEN]; uint8_t km[MAX_KEY_BYTE_LEN], key_material[MAX_KEY_BYTE_LEN]; uint8_t MA[MAX_MSG_BYTE_LEN], MB[MAX_MSG_BYTE_LEN]; - uint8_t label[MAX_LABEL_BYTE_LEN]; - uint32_t alength, blength, llength, klength, kmlength, k1length; - uint32_t k2length, r, j; + uint8_t label[MAX_LABEL_BYTE_LEN], labelA[MAX_LABEL_BYTE_LEN], labelB[MAX_LABEL_BYTE_LEN]; + uint32_t alength, blength, llengthA, llengthB, klength, kmlength, k1length, k2length, r; const EVP_MD *md_type; for (r = 0; r < TEST_VECTOR_CNT; r++) { @@ -566,60 +1434,226 @@ int test_hkex_concatenate() ascii_hex_strings_to_uint8(k1, &k1length, 1, strk1[r]); k2length = sizeof(k2); ascii_hex_strings_to_uint8(k2, &k2length, 1, strk2[r]); - for (j = 0; j < HASH_FUNCTIONS_CNT; j++) { - md_type = (*evp_hash[r][j])(); - /* MA = LA1 || PA1 || PA2 - NOTE: for test vector purposes ONLY not a suggested message format - */ - alength = sizeof(MA); - ascii_hex_strings_to_uint8(MA, &alength, 3, strLA1[r], strPA1[r], strPA2[r]); - /* MB = LB1 || PB1 || PB2 - NOTE: for test vector purposes ONLY not a suggested message format - */ - blength = sizeof(MB); - ascii_hex_strings_to_uint8(MB, &blength, 3, strLB1[r], strPB1[r], strPB2[r]); - /* label = LA || LB */ - llength = sizeof(label); - ascii_hex_strings_to_uint8(label, &llength, 2, strLA1[r], strLB1[r]); - klength = key_length[r]; - if (hkex_concat(md_type, key_material, klength, NULL, 0, k1, k1length, k2, k2length, MA, alength, MB, - blength, (uint8_t *)CONCAT_CONTEXT_TEST_VECTOR, - (uint32_t)strlen(CONCAT_CONTEXT_TEST_VECTOR), label, llength)) { - return FAILURE; - } - kmlength = sizeof(km); - ascii_hex_strings_to_uint8(km, &kmlength, 1, strkmcat[j + HASH_FUNCTIONS_CNT * r]); - printf("LA = %s\n", strLA1[r]); - printf("PA1 = %s\n", strPA1[r]); - printf("PA2 = %s\n", strPA2[r]); - printf("LB = %s\n", strLB1[r]); - printf("PB1 = %s\n", strPB1[r]); - printf("PB2 = %s\n", strPB2[r]); - printf("k1 = %s\n", strk1[r]); - printf("k2 = %s\n", strk2[r]); - printf("context = %s\n", CONCAT_CONTEXT_TEST_VECTOR); - printf("label = LA || LB\n"); - printf("MA = LA || PA1 || PA2\n"); - printf("MB = LB || PB1 || PB2\n\n"); - print_array("key material = ", key_material, klength); - if (memcmp(km, key_material, key_length[r]) != 0) { - printf("Test vector %d failed\n", j + r * HASH_FUNCTIONS_CNT); - return FAILURE; - } + md_type = (*evp_hash[r])(); + + printf("\nCatKDF as HKDF/HMAC with %s, ECDH with %s, and %s \n\n", EVP_MD_name(md_type), OBJ_nid2sn(curves[r]), kems[r]); + printf("CID %s \n", cids_concatenate_hkdf[r]); + + /* MA = cid || len(LA1) || LA1 || len(PA1) || PA1 || len(PA2) || PA2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + alength = sizeof(MA); + message_formatting_function(MA, &alength, 4, cids_concatenate_hkdf[r], strLA1[r], strPA1[r], strPA2[r]); + + /* MB = cid || len(LB1) || LB1 || len(PB1) || PB1 || len(PB2) || PB2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + blength = sizeof(MB); + message_formatting_function(MB, &blength, 4, cids_concatenate_hkdf[r], strLB1[r], strPB1[r], strPB2[r]); + + /* label = LA ^ LB */ + llengthA = sizeof(labelA); + ascii_hex_strings_to_uint8(labelA, &llengthA, 1, strLA1[r]); + llengthB = sizeof(labelB); + ascii_hex_strings_to_uint8(labelB, &llengthB, 1, strLB1[r]); + if (llengthA != llengthB) { + return FAILURE; + } + for (int i = 0; i < llengthA; i++) { + label[i] = labelA[i] ^ labelB[i]; + } + + klength = key_length[r]; + if (hkex_concat_hkdf(md_type, key_material, klength, NULL, 0, k1, k1length, k2, k2length, MA, alength, MB, + blength, (uint8_t *)INFO_TEST_VECTOR, + (uint32_t)strlen(INFO_TEST_VECTOR), label, llengthA)) { + return FAILURE; + } + printf("LA = %s\n", strLA1[r]); + printf("PA1 = %s\n", strPA1[r]); + printf("PA2 = %s\n", strPA2[r]); + printf("LB = %s\n", strLB1[r]); + printf("PB1 = %s\n", strPB1[r]); + printf("PB2 = %s\n", strPB2[r]); + printf("k1 = %s\n", strk1[r]); + printf("k2 = %s\n", strk2[r]); + printf("info = \"%s\"\n", INFO_TEST_VECTOR); + print_array("label = LA ^ LB = ", label, llengthA); + printf("MA = cid || len(LA)|| LA || len(PA1) || PA1 || len(PA2) || PA2\n"); + printf("MB = cid || len(LB)|| LB || len(PB1) || PB1 || len(PB2) || PB2\n\n"); + + print_array("key material = ", key_material, klength); + + kmlength = sizeof(km); + ascii_hex_strings_to_uint8(km, &kmlength, 1, strkmcat_hkdf[r]); + if (memcmp(km, key_material, key_length[r]) != 0) { + printf("Test vector %u failed\n", r); + return FAILURE; } } return SUCCESS; } -/* Testing harness for the cascade KDF using two rounds */ -int test_hkex_cascade() +/* Testing harness for concatenation KDF (HMAC) with two exchanges */ +int test_hkex_concatenate_hmac() +{ + uint8_t k1[MAX_KEY_BYTE_LEN], k2[MAX_KEY_BYTE_LEN]; + uint8_t km[MAX_KEY_BYTE_LEN], key_material[MAX_KEY_BYTE_LEN]; + uint8_t MA[MAX_MSG_BYTE_LEN], MB[MAX_MSG_BYTE_LEN]; + uint8_t label[MAX_LABEL_BYTE_LEN], labelA[MAX_LABEL_BYTE_LEN], labelB[MAX_LABEL_BYTE_LEN]; + uint32_t alength, blength, llengthA, llengthB, klength, kmlength, k1length; + uint32_t k2length, r; + const EVP_MD *md_type; + + for (r = 0; r < TEST_VECTOR_CNT; r++) { + k1length = sizeof(k1); + ascii_hex_strings_to_uint8(k1, &k1length, 1, strk1[r]); + k2length = sizeof(k2); + ascii_hex_strings_to_uint8(k2, &k2length, 1, strk2[r]); + md_type = (*evp_hash[r])(); + + printf("\nCatKDF as HMAC with %s, ECDH with %s, and %s \n\n", EVP_MD_name(md_type), OBJ_nid2sn(curves[r]), kems[r]); + printf("CID %s \n", cids_concatenate_hmac[r]); + + /* MA = cid || len(LA1) || LA1 || len(PA1) || PA1 || len(PA2) || PA2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + alength = sizeof(MA); + message_formatting_function(MA, &alength, 4, cids_concatenate_hmac[r], strLA1[r], strPA1[r], strPA2[r]); + + /* MB = cid || len(LB1) || LB1 || len(PB1) || PB1 || len(PB2) || PB2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + blength = sizeof(MB); + message_formatting_function(MB, &blength, 4, cids_concatenate_hmac[r], strLB1[r], strPB1[r], strPB2[r]); + + /* label = LA ^ LB */ + llengthA = sizeof(labelA); + ascii_hex_strings_to_uint8(labelA, &llengthA, 1, strLA1[r]); + llengthB = sizeof(labelB); + ascii_hex_strings_to_uint8(labelB, &llengthB, 1, strLB1[r]); + if (llengthA != llengthB) { + return FAILURE; + } + for (int i = 0; i < llengthA; i++) { + label[i] = labelA[i] ^ labelB[i]; + } + + klength = key_length[r]; + if (hkex_concat_hmac(md_type, key_material, klength, NULL, 0, k1, k1length, k2, k2length, MA, alength, MB, + blength, (uint8_t *)INFO_TEST_VECTOR, + (uint32_t)strlen(INFO_TEST_VECTOR), label, llengthA)) { + return FAILURE; + } + + printf("LA = %s\n", strLA1[r]); + printf("PA1 = %s\n", strPA1[r]); + printf("PA2 = %s\n", strPA2[r]); + printf("LB = %s\n", strLB1[r]); + printf("PB1 = %s\n", strPB1[r]); + printf("PB2 = %s\n", strPB2[r]); + printf("k1 = %s\n", strk1[r]); + printf("k2 = %s\n", strk2[r]); + printf("info = \"%s\"\n", INFO_TEST_VECTOR); + print_array("label = LA ^ LB = ", label, llengthA); + printf("MA = cid || len(LA)|| LA || len(PA1) || PA1 || len(PA2) || PA2\n"); + printf("MB = cid || len(LB)|| LB || len(PB1) || PB1 || len(PB2) || PB2\n\n"); + + print_array("key material = ", key_material, klength); + + kmlength = sizeof(km); + ascii_hex_strings_to_uint8(km, &kmlength, 1, strkmcat_hmac[r]); + if (memcmp(km, key_material, key_length[r]) != 0) { + printf("Test vector %u failed\n", r); + return FAILURE; + } + } + return SUCCESS; +} + + +/* Testing harness for concatenation KDF (KMAC) with two exchanges */ +int test_hkex_concatenate_kmac() +{ + uint8_t k1[MAX_KEY_BYTE_LEN], k2[MAX_KEY_BYTE_LEN]; + uint8_t km[MAX_KEY_BYTE_LEN], key_material[MAX_KEY_BYTE_LEN]; + uint8_t MA[MAX_MSG_BYTE_LEN], MB[MAX_MSG_BYTE_LEN]; + uint8_t label[MAX_LABEL_BYTE_LEN], labelA[MAX_LABEL_BYTE_LEN], labelB[MAX_LABEL_BYTE_LEN]; + uint32_t alength, blength, llengthA, llengthB, klength, kmlength, k1length; + uint32_t k2length, r; + + for (r = 0; r < TEST_VECTOR_CNT; r++) { + printf("\nCatKDF as %s, ECDH with %s, and %s \n\n", kmac[r], OBJ_nid2sn(curves[r]), kems[r]); + printf("CID %s \n", cids_concatenate_kmac[r]); + + k1length = sizeof(k1); + ascii_hex_strings_to_uint8(k1, &k1length, 1, strk1[r]); + k2length = sizeof(k2); + ascii_hex_strings_to_uint8(k2, &k2length, 1, strk2[r]); + /* MA = cid || len(LA1) || LA1 || len(PA1) || PA1 || len(PA2) || PA2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + alength = sizeof(MA); + message_formatting_function(MA, &alength, 4, cids_concatenate_kmac[r], strLA1[r], strPA1[r], strPA2[r]); + + /* MB = cid || len(LB1) || LB1 || len(PB1) || PB1 || len(PB2) || PB2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + blength = sizeof(MB); + message_formatting_function(MB, &blength, 4, cids_concatenate_kmac[r], strLB1[r], strPB1[r], strPB2[r]); + + /* label = LA ^ LB */ + llengthA = sizeof(labelA); + ascii_hex_strings_to_uint8(labelA, &llengthA, 1, strLA1[r]); + llengthB = sizeof(labelB); + ascii_hex_strings_to_uint8(labelB, &llengthB, 1, strLB1[r]); + if (llengthA != llengthB) { + return FAILURE; + } + for (int i = 0; i < llengthA; i++) { + label[i] = labelA[i] ^ labelB[i]; + } + + klength = key_length[r]; + if (hkex_concat_kmac(kmac[r], key_material, klength, NULL, 0, k1, k1length, k2, k2length, MA, alength, MB, + blength, (uint8_t *)INFO_TEST_VECTOR, + (uint32_t)strlen(INFO_TEST_VECTOR), label, llengthA)) { + return FAILURE; + } + + printf("LA = %s\n", strLA1[r]); + printf("PA1 = %s\n", strPA1[r]); + printf("PA2 = %s\n", strPA2[r]); + printf("LB = %s\n", strLB1[r]); + printf("PB1 = %s\n", strPB1[r]); + printf("PB2 = %s\n", strPB2[r]); + printf("k1 = %s\n", strk1[r]); + printf("k2 = %s\n", strk2[r]); + printf("info = \"%s\"\n", INFO_TEST_VECTOR); + printf("label = LA ^ LB\n"); + printf("MA = cid || len(LA)|| LA || len(PA1) || PA1 || len(PA2) || PA2\n"); + printf("MB = cid || len(LB)|| LB || len(PB1) || PB1 || len(PB1) || PB2\n\n"); + + print_array("key material = ", key_material, klength); + + kmlength = sizeof(km); + ascii_hex_strings_to_uint8(km, &kmlength, 1, strkmcat_kmac[r]); + if (memcmp(km, key_material, key_length[r]) != 0) { + printf("Test vector %u failed\n", r); + return FAILURE; + } + } + return SUCCESS; +} +/* Testing harness for the cascade KDF (HKDF) using two rounds */ +int test_hkex_cascade_hkdf() { uint8_t k1[MAX_KEY_BYTE_LEN], k2[MAX_KEY_BYTE_LEN]; uint8_t km[MAX_KEY_BYTE_LEN], round_secret[MAX_KEY_BYTE_LEN]; uint8_t MA[MAX_MSG_BYTE_LEN], MB[MAX_MSG_BYTE_LEN]; - uint8_t label[MAX_LABEL_BYTE_LEN], chain_secret1[MAX_KEY_BYTE_LEN]; - uint8_t chain_secret2[MAX_KEY_BYTE_LEN]; - uint32_t alength, blength, llength, clength, rlength, kmlength; - uint32_t k1length, k2length, r, j; + uint8_t label[MAX_LABEL_BYTE_LEN], labelA[MAX_LABEL_BYTE_LEN], labelB[MAX_LABEL_BYTE_LEN]; + uint8_t chain_secret1[MAX_KEY_BYTE_LEN], chain_secret2[MAX_KEY_BYTE_LEN]; + uint32_t alength, blength, llengthA, llengthB, clength, rlength, kmlength; + uint32_t k1length, k2length, r; const EVP_MD *md_type; for (r = 0; r < TEST_VECTOR_CNT; r++) { @@ -627,78 +1661,354 @@ int test_hkex_cascade() ascii_hex_strings_to_uint8(k1, &k1length, 1, strk1[r]); k2length = sizeof(k2); ascii_hex_strings_to_uint8(k2, &k2length, 1, strk2[r]); - for (j = 0; j < HASH_FUNCTIONS_CNT; j++) { - md_type = (*evp_hash[r][j])(); - /* MAi = LAi || PAi - NOTE: for test vector purposes ONLY not a suggested message format - */ - alength = sizeof(MA); - ascii_hex_strings_to_uint8(MA, &alength, 2, strLA1[r], strPA1[r]); - /* MBi = LBi || PBi - NOTE: for test vector purposes ONLY not a suggested message format - */ - blength = sizeof(MB); - ascii_hex_strings_to_uint8(MB, &blength, 2, strLB1[r], strPB1[r]); - /* labeli = LAi || LBi */ - llength = sizeof(label); - ascii_hex_strings_to_uint8(label, &llength, 2, strLA1[r], strLB1[r]); - rlength = key_length[r]; - clength = EVP_MD_size(md_type); - if (hkex_cascade(md_type, chain_secret1, clength, round_secret, rlength, NULL, 0, k1, k1length, MA, alength, - MB, blength, (uint8_t *)CASCADE_CONTEXT_TEST_VECTOR, - (uint32_t)strlen(CASCADE_CONTEXT_TEST_VECTOR), label, llength)) { - return FAILURE; - } - printf("LA1 = %s\n", strLA1[r]); - printf("PA1 = %s\n", strPA1[r]); - printf("LB1 = %s\n", strLB1[r]); - printf("PB1 = %s\n", strPB1[r]); - printf("previous_chain_secret = psk = \n"); - printf("k1 = %s\n", strk1[r]); - printf("context = %s\n", CASCADE_CONTEXT_TEST_VECTOR); - printf("label = LA1 || LB1\n"); - printf("MA = LA1 || PA1\n"); - printf("MB = LB1 || PB1\n\n"); - - print_array("chain_secret1 = ", chain_secret1, clength); - print_array("key_material1 = ", round_secret, rlength); - /* MA = LA2 || PA2 - NOTE: for test vector purposes ONLY not a suggested message format - */ - alength = sizeof(MA); - ascii_hex_strings_to_uint8(MA, &alength, 2, strLA2[r], strPA2[r]); - /* MB = LB1 || PB1 - NOTE: for test vector purposes ONLY not a suggested message format - */ - blength = sizeof(MB); - ascii_hex_strings_to_uint8(MB, &blength, 2, strLB2[r], strPB2[r]); - /* label = LA2 || LB2 */ - llength = sizeof(label); - ascii_hex_strings_to_uint8(label, &llength, 2, strLA2[r], strLB2[r]); - if (hkex_cascade(md_type, chain_secret2, clength, round_secret, rlength, chain_secret1, clength, k2, - k2length, MA, alength, MB, blength, (uint8_t *)CASCADE_CONTEXT_TEST_VECTOR, - (uint32_t)strlen(CASCADE_CONTEXT_TEST_VECTOR), label, llength)) { - return FAILURE; - } - printf("LA2 = %s\n", strLA2[r]); - printf("PA2 = %s\n", strPA2[r]); - printf("LB2 = %s\n", strLB2[r]); - printf("PB2 = %s\n", strPB2[r]); - print_array("previous_chain_secret = ", chain_secret1, clength); - printf("k2 = %s\n", strk1[r]); - printf("context = %s\n", CASCADE_CONTEXT_TEST_VECTOR); - printf("label = LA2 || LB2\n"); - printf("MA2 = LA2 || PA2\n"); - printf("MB2 = LB2 || PB2\n\n"); - - print_array("chain_secret2 = ", chain_secret1, clength); - print_array("key_material2 = ", round_secret, rlength); - kmlength = sizeof(km); - ascii_hex_strings_to_uint8(km, &kmlength, 1, strkmcas[j + HASH_FUNCTIONS_CNT * r]); - if (memcmp(km, round_secret, key_length[r]) != 0) { - printf("Test vector %d failed\n", j + r * HASH_FUNCTIONS_CNT); - return FAILURE; - } + md_type = (*evp_hash[r])(); + + printf("\nCasKDF as HKDF with %s, ECDH with %s, and %s \n\n", EVP_MD_name(md_type), OBJ_nid2sn(curves[r]), kems[r]); + printf("CID %s \n", cids_cascade_hkdf[r]); + + /* MA = cid || len(LA1) || LA1 || len(PA1) || PA1 + NOTE: for test vector purposes ONLY not a suggested message format + */ + alength = sizeof(MA); + message_formatting_function(MA, &alength, 3, cids_cascade_hkdf[r], strLA1[r], strPA1[r]); + + /* MB = cid || len(LB1) || LB1 || len(PB1) || PB1 + NOTE: for test vector purposes ONLY not a suggested message format + */ + blength = sizeof(MB); + message_formatting_function(MB, &blength, 3, cids_cascade_hkdf[r], strLB1[r], strPB1[r]); + + /* label = LA1 ^ LB1 */ + llengthA = sizeof(labelA); + ascii_hex_strings_to_uint8(labelA, &llengthA, 1, strLA1[r]); + llengthB = sizeof(labelB); + ascii_hex_strings_to_uint8(labelB, &llengthB, 1, strLB1[r]); + if (llengthA != llengthB) { + return FAILURE; + } + for (int i = 0; i < llengthA; i++) { + label[i] = labelA[i] ^ labelB[i]; + } + + rlength = key_length[r]; + clength = EVP_MD_size(md_type); + const uint8_t chain_secret0[] = {}; // OpenSSL3.x does not allow NULL pointer HMAC input + if (hkex_cascade_hkdf(md_type, chain_secret1, clength, round_secret, rlength, chain_secret0, 0, k1, k1length, MA, alength, + MB, blength, (uint8_t *)INFO_TEST_VECTOR, + (uint32_t)strlen(INFO_TEST_VECTOR), label, llengthA)) { + return FAILURE; + } + + printf("LA1 = %s\n", strLA1[r]); + printf("PA1 = %s\n", strPA1[r]); + printf("LB1 = %s\n", strLB1[r]); + printf("PB1 = %s\n", strPB1[r]); + printf("previous_chain_secret = psk = \n"); + printf("k1 = %s\n", strk1[r]); + printf("info1 = \"%s\"\n", INFO_TEST_VECTOR); + printf("label1 = LA1 ^ LB1\n"); + printf("MA1 = cid || len(LA1) || LA1 || len(PA1) || PA1\n"); + printf("MB1 = cid || len(LB1) || LB1 || len(PB1) || PB1\n"); + + print_array("chain_secret1 = ", chain_secret1, clength); + print_array("key_material1 = ", round_secret, rlength); + + /* MA = cid || len(LA2) || LA2 || len(PA2) || PA2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + alength = sizeof(MA); + message_formatting_function(MA, &alength, 3, cids_cascade_hkdf[r], strLA2[r], strPA2[r]); + + /* MB = cid || len(LB2) || LB2 || len(PB2) || PB2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + blength = sizeof(MB); + message_formatting_function(MB, &blength, 3, cids_cascade_hkdf[r], strLB2[r], strPB2[r]); + + /* label = LA2 ^ LB2 */ + llengthA = sizeof(labelA); + ascii_hex_strings_to_uint8(labelA, &llengthA, 1, strLA2[r]); + llengthB = sizeof(labelB); + ascii_hex_strings_to_uint8(labelB, &llengthB, 1, strLB2[r]); + if (llengthA != llengthB) { + return FAILURE; + } + for (int i = 0; i < llengthA; i++) { + label[i] = labelA[i] ^ labelB[i]; + } + + if (hkex_cascade_hkdf(md_type, chain_secret2, clength, round_secret, rlength, chain_secret1, clength, k2, + k2length, MA, alength, MB, blength, (uint8_t *)INFO_TEST_VECTOR, + (uint32_t)strlen(INFO_TEST_VECTOR), label, llengthA)) { + return FAILURE; + } + printf("LA2 = %s\n", strLA2[r]); + printf("PA2 = %s\n", strPA2[r]); + printf("LB2 = %s\n", strLB2[r]); + printf("PB2 = %s\n", strPB2[r]); + print_array("previous_chain_secret = ", chain_secret1, clength); + printf("k2 = %s\n", strk2[r]); + printf("info2 = \"%s\"\n", INFO_TEST_VECTOR); + printf("label2 = LA2 ^ LB2\n"); + printf("MA2 = cid || len(LA2) || LA2 || len(PA2) || PA2\n"); + printf("MB2 = cid || len(LB2) || LB2 || len(PB2) || PB2\n\n"); + + print_array("chain_secret2 = ", chain_secret2, clength); + print_array("key_material2 = ", round_secret, rlength); + + kmlength = sizeof(km); + ascii_hex_strings_to_uint8(km, &kmlength, 1, strkmcas_hkdf[r]); + if (memcmp(km, round_secret, key_length[r]) != 0) { + printf("Test vector %u failed\n", r); + return FAILURE; + } + } + return SUCCESS; +} +/* Testing harness for the cascade KDF (HMAC) using two rounds */ +int test_hkex_cascade_hmac() +{ + uint8_t k1[MAX_KEY_BYTE_LEN], k2[MAX_KEY_BYTE_LEN]; + uint8_t km[MAX_KEY_BYTE_LEN], round_secret[MAX_KEY_BYTE_LEN]; + uint8_t MA[MAX_MSG_BYTE_LEN], MB[MAX_MSG_BYTE_LEN]; + uint8_t label[MAX_LABEL_BYTE_LEN], labelA[MAX_LABEL_BYTE_LEN], labelB[MAX_LABEL_BYTE_LEN]; + uint8_t chain_secret1[MAX_KEY_BYTE_LEN], chain_secret2[MAX_KEY_BYTE_LEN]; + uint32_t alength, blength, llengthA, llengthB, clength, rlength, kmlength; + uint32_t k1length, k2length, r; + const EVP_MD *md_type; + + for (r = 0; r < TEST_VECTOR_CNT; r++) { + k1length = sizeof(k1); + ascii_hex_strings_to_uint8(k1, &k1length, 1, strk1[r]); + k2length = sizeof(k2); + ascii_hex_strings_to_uint8(k2, &k2length, 1, strk2[r]); + md_type = (*evp_hash[r])(); + + printf("\nCasKDF as HMAC/HMAC with %s, ECDH with %s, and %s \n\n", EVP_MD_name(md_type), OBJ_nid2sn(curves[r]), kems[r]); + printf("CID %s \n", cids_cascade_hmac[r]); + + /* MA = cid || len(LA1) || LA1 || len(PA1) || PA1 + NOTE: for test vector purposes ONLY not a suggested message format + */ + alength = sizeof(MA); + message_formatting_function(MA, &alength, 3, cids_cascade_hmac[r], strLA1[r], strPA1[r]); + + /* MB = cid || len(LB1) || LB1 || len(PB1) || PB1 + NOTE: for test vector purposes ONLY not a suggested message format + */ + blength = sizeof(MB); + message_formatting_function(MB, &blength, 3, cids_cascade_hmac[r], strLB1[r], strPB1[r]); + + /* label = LA1 ^ LB1 */ + llengthA = sizeof(labelA); + ascii_hex_strings_to_uint8(labelA, &llengthA, 1, strLA1[r]); + llengthB = sizeof(labelB); + ascii_hex_strings_to_uint8(labelB, &llengthB, 1, strLB1[r]); + if (llengthA != llengthB) { + return FAILURE; + } + for (int i = 0; i < llengthA; i++) { + label[i] = labelA[i] ^ labelB[i]; + } + + rlength = key_length[r]; + clength = EVP_MD_size(md_type); + const uint8_t chain_secret0[] = {}; // OpenSSL3.x does not allow NULL pointer HMAC input + if (hkex_cascade_hmac(md_type, chain_secret1, clength, round_secret, rlength, chain_secret0, 0, k1, k1length, MA, alength, + MB, blength, (uint8_t *)INFO_TEST_VECTOR, + (uint32_t)strlen(INFO_TEST_VECTOR), label, llengthA)) { + return FAILURE; + } + + printf("LA1 = %s\n", strLA1[r]); + printf("PA1 = %s\n", strPA1[r]); + printf("LB1 = %s\n", strLB1[r]); + printf("PB1 = %s\n", strPB1[r]); + printf("previous_chain_secret = psk = \n"); + printf("k1 = %s\n", strk1[r]); + printf("info1 = \"%s\"\n", INFO_TEST_VECTOR); + printf("label1 = LA1 ^ LB1\n"); + printf("MA1 = cid || len(LA1) || LA1 || len(PA1) || PA1\n"); + printf("MB1 = cid || len(LB1) || LB1 || len(PB1) || PB1\n"); + + print_array("chain_secret1 = ", chain_secret1, clength); + print_array("key_material1 = ", round_secret, rlength); + + /* MA = cid || len(LA2) || LA2 || len(PA2) || PA2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + alength = sizeof(MA); + message_formatting_function(MA, &alength, 3, cids_cascade_hmac[r], strLA2[r], strPA2[r]); + + /* MB = cid || len(LB2) || LB2 || len(PB2) || PB2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + blength = sizeof(MB); + message_formatting_function(MB, &blength, 3, cids_cascade_hmac[r], strLB2[r], strPB2[r]); + + /* label = LA2 ^ LB2 */ + llengthA = sizeof(labelA); + ascii_hex_strings_to_uint8(labelA, &llengthA, 1, strLA2[r]); + llengthB = sizeof(labelB); + ascii_hex_strings_to_uint8(labelB, &llengthB, 1, strLB2[r]); + if (llengthA != llengthB) { + return FAILURE; + } + for (int i = 0; i < llengthA; i++) { + label[i] = labelA[i] ^ labelB[i]; + } + + if (hkex_cascade_hmac(md_type, chain_secret2, clength, round_secret, rlength, chain_secret1, clength, k2, + k2length, MA, alength, MB, blength, (uint8_t *)INFO_TEST_VECTOR, + (uint32_t)strlen(INFO_TEST_VECTOR), label, llengthA)) { + return FAILURE; + } + printf("LA2 = %s\n", strLA2[r]); + printf("PA2 = %s\n", strPA2[r]); + printf("LB2 = %s\n", strLB2[r]); + printf("PB2 = %s\n", strPB2[r]); + print_array("previous_chain_secret = ", chain_secret1, clength); + printf("k2 = %s\n", strk2[r]); + printf("info2 = \"%s\"\n", INFO_TEST_VECTOR); + printf("label2 = LA2 ^ LB2\n"); + printf("MA2 = cid || len(LA2) || LA2 || len(PA2) || PA2\n"); + printf("MB2 = cid || len(LB2) || LB2 || len(PB2) || PB2\n"); + + print_array("chain_secret2 = ", chain_secret2, clength); + print_array("key_material2 = ", round_secret, rlength); + + kmlength = sizeof(km); + ascii_hex_strings_to_uint8(km, &kmlength, 1, strkmcas_hmac[r]); + if (memcmp(km, round_secret, key_length[r]) != 0) { + printf("Test vector %u failed\n", r); + return FAILURE; + } + } + return SUCCESS; +} +/* Testing harness for the cascade KDF (KMAC) using two rounds */ +int test_hkex_cascade_kmac() +{ + uint8_t k1[MAX_KEY_BYTE_LEN], k2[MAX_KEY_BYTE_LEN]; + uint8_t km[MAX_KEY_BYTE_LEN], round_secret[MAX_KEY_BYTE_LEN]; + uint8_t MA[MAX_MSG_BYTE_LEN], MB[MAX_MSG_BYTE_LEN]; + uint8_t label[MAX_LABEL_BYTE_LEN], labelA[MAX_LABEL_BYTE_LEN], labelB[MAX_LABEL_BYTE_LEN]; + uint8_t chain_secret0[MAX_KEY_BYTE_LEN], chain_secret1[MAX_KEY_BYTE_LEN], chain_secret2[MAX_KEY_BYTE_LEN]; + uint32_t alength, blength, llengthA, llengthB, cs0length, clength, rlength, kmlength; + uint32_t k1length, k2length, r; + + for (r = 0; r < TEST_VECTOR_CNT; r++) { + printf("\nKDF as %s, ECDH with %s, and %s \n\n", kmac[r], OBJ_nid2sn(curves[r]), kems[r]); + printf("CID %s \n", cids_cascade_kmac[r]); + + k1length = sizeof(k1); + ascii_hex_strings_to_uint8(k1, &k1length, 1, strk1[r]); + k2length = sizeof(k2); + ascii_hex_strings_to_uint8(k2, &k2length, 1, strk2[r]); + + /* MA = cid || len(LA1) || LA1 || len(PA1) || PA1 + NOTE: for test vector purposes ONLY not a suggested message format + */ + alength = sizeof(MA); + message_formatting_function(MA, &alength, 3, cids_cascade_kmac[r], strLA1[r], strPA1[r]); + + /* MB = cid || len(LB1) || LB1 || len(PB1) || PB1 + NOTE: for test vector purposes ONLY not a suggested message format + */ + blength = sizeof(MB); + message_formatting_function(MB, &blength, 3, cids_cascade_kmac[r], strLB1[r], strPB1[r]); + + /* label = LA1 ^ LB1 */ + llengthA = sizeof(labelA); + ascii_hex_strings_to_uint8(labelA, &llengthA, 1, strLA1[r]); + llengthB = sizeof(labelB); + ascii_hex_strings_to_uint8(labelB, &llengthB, 1, strLB1[r]); + if (llengthA != llengthB) { + return FAILURE; + } + for (int i = 0; i < llengthA; i++) { + label[i] = labelA[i] ^ labelB[i]; + } + + rlength = key_length[r]; + clength = KMAC128_OUT_BYTE_LENGTH; + if (memcmp(kmac[r], SN_kmac256, strlen(SN_kmac256)) == 0) { + clength = KMAC256_OUT_BYTE_LENGTH; + } + + // OpenSSL3.x does not allow KMAC secret length < 4B + cs0length = sizeof(strPSK); + ascii_hex_strings_to_uint8(chain_secret0, &cs0length, 1, strPSK); + cs0length = clength; + if (hkex_cascade_kmac(kmac[r], chain_secret1, clength, round_secret, rlength, chain_secret0, cs0length, k1, k1length, MA, alength, + MB, blength, (uint8_t *)INFO_TEST_VECTOR, + (uint32_t)strlen(INFO_TEST_VECTOR), label, llengthA)) { + return FAILURE; + } + + printf("LA1 = %s\n", strLA1[r]); + printf("PA1 = %s\n", strPA1[r]); + printf("LB1 = %s\n", strLB1[r]); + printf("PB1 = %s\n", strPB1[r]); + printf("previous_chain_secret = psk = \n"); + printf("k1 = %s\n", strk1[r]); + printf("info1 = \"%s\"\n", INFO_TEST_VECTOR); + printf("label1 = LA1 ^ LB1\n"); + printf("MA1 = cid || len(LA1) || LA1 || len(PA1) || PA1\n"); + printf("MB1 = cid || len(LB1) || LB1 || len(PB1) || PB1\n\n"); + + print_array("chain_secret1 = ", chain_secret1, clength); + print_array("key_material1 = ", round_secret, rlength); + + /* MA2 = cid || len(LA2) || LA2 || len(PA2) || PA2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + alength = sizeof(MA); + message_formatting_function(MA, &alength, 3, cids_cascade_kmac[r], strLA2[r], strPA2[r]); + + /* MB2 = cid || len(LB2) || LB2 || len(PB2) || PB2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + blength = sizeof(MB); + message_formatting_function(MB, &blength, 3, cids_cascade_kmac[r], strLB2[r], strPB2[r]); + + /* label = LA2 ^ LB2 */ + llengthA = sizeof(labelA); + ascii_hex_strings_to_uint8(labelA, &llengthA, 1, strLA2[r]); + llengthB = sizeof(labelB); + ascii_hex_strings_to_uint8(labelB, &llengthB, 1, strLB2[r]); + if (llengthA != llengthB) { + return FAILURE; + } + for (int i = 0; i < llengthA; i++) { + label[i] = labelA[i] ^ labelB[i]; + } + + if (hkex_cascade_kmac(kmac[r], chain_secret2, clength, round_secret, rlength, chain_secret1, clength, k2, + k2length, MA, alength, MB, blength, (uint8_t *)INFO_TEST_VECTOR, + (uint32_t)strlen(INFO_TEST_VECTOR), label, llengthA)) { + return FAILURE; + } + + printf("LA2 = %s\n", strLA2[r]); + printf("PA2 = %s\n", strPA2[r]); + printf("LB2 = %s\n", strLB2[r]); + printf("PB2 = %s\n", strPB2[r]); + print_array("previous_chain_secret = ", chain_secret1, clength); + printf("k2 = %s\n", strk2[r]); + printf("info2 = \"%s\"\n", INFO_TEST_VECTOR); + printf("label2 = LA2 ^ LB2\n"); + printf("MA2 = cid || len(LA2) || LA2 || len(PA2) || PA2\n"); + printf("MB2 = cid || len(LB2) || LB2 || len(PB2) || PB2\n\n"); + + print_array("chain_secret2 = ", chain_secret2, clength); + print_array("key_material2 = ", round_secret, rlength); + + kmlength = sizeof(km); + ascii_hex_strings_to_uint8(km, &kmlength, 1, strkmcas_kmac[r]); + if (memcmp(km, round_secret, key_length[r]) != 0) { + printf("Test vector %u failed\n", r); + return FAILURE; } } return SUCCESS; @@ -706,10 +2016,22 @@ int test_hkex_cascade() int main(void) { - if (test_hkex_concatenate()) { + if (test_hkex_concatenate_hkdf()) { + return FAILURE; + } + if (test_hkex_concatenate_hmac()) { + return FAILURE; + } + if (test_hkex_concatenate_kmac()) { + return FAILURE; + } + if (test_hkex_cascade_hkdf()) { + return FAILURE; + } + if (test_hkex_cascade_hmac()) { return FAILURE; } - if (test_hkex_cascade()) { + if (test_hkex_cascade_kmac()) { return FAILURE; } printf("All tests passed\n"); diff --git a/qshkex.c b/qshkex.c index 1ea0ea2..4604399 100644 --- a/qshkex.c +++ b/qshkex.c @@ -15,6 +15,7 @@ */ #include "qshkex.h" +#include /* Memory helper functions to handle null values */ static inline void *my_memcpy(void *dst, const void *src, size_t byte_len) @@ -24,9 +25,50 @@ static inline void *my_memcpy(void *dst, const void *src, size_t byte_len) } return memcpy(dst, src, byte_len); } +/* Implements the kdf concatenate-based formatting function, see Section 7.2.2 */ +/* Input: const uint8_t * arg1, arg2, arg3 */ +/* Input: const uint32_t a1length, a2length, a3length */ +/* Output: uint8_t *kdf_context, uint32_t *clength */ +/* Functionality: kdf_context = arg1 || a1length || arg2 || a2length || arg3 || a3length */ +int cb_f(uint8_t *kdf_context, uint32_t *clength, const uint8_t *arg1, + const uint32_t a1length, const uint8_t *arg2, const uint32_t a2length, const uint8_t *arg3, + const uint32_t a3length) +{ + int rval = FAILURE; + uint32_t length; -/* Implements the kdf context formatting function f, see Section 7.2 */ -int f_function(const EVP_MD *md_type, uint8_t *kdf_context, uint32_t *clength, const uint8_t *arg1, + do { + if ((kdf_context == NULL) || (clength == NULL)) { + break; + } + if (((a1length) && (arg1 == NULL)) || ((a2length) && (arg2 == NULL)) || ((a3length) && (arg3 == NULL))) { + break; + } + + length = htonl(a1length); + my_memcpy(kdf_context, &length, sizeof(uint32_t)); + my_memcpy(kdf_context + sizeof(uint32_t), arg1, a1length); + + length = htonl(a2length); + my_memcpy(kdf_context + sizeof(uint32_t) + a1length, &length, sizeof(uint32_t)); + my_memcpy(kdf_context + 2 * sizeof(uint32_t) + a1length, arg2, a2length); + + length = htonl(a3length); + my_memcpy(kdf_context + 2 * sizeof(uint32_t) + a1length + a2length, &length, sizeof(uint32_t)); + my_memcpy(kdf_context + 3 * sizeof(uint32_t) + a1length + a2length, arg3, a3length); + + *clength = a1length + a2length + a3length + 3 * sizeof(uint32_t); + rval = SUCCESS; + } while (0); + return rval; +} +/* Implements the kdf concatenate-and-hash-based formatting function, see Section 7.2.3 */ +/* Input: const uint8_t * arg1, arg2, arg3 */ +/* Input: const uint32_t a1length, a2length, a3length */ +/* Input: const EVP_MD *md_type */ +/* Output: uint8_t *kdf_context, uint32_t *clength */ +/* Functionality: kdf_context = hash(arg1 || a1length || arg2 || a2length || arg3 || a3length) */ +int cahb_f(const EVP_MD *md_type, uint8_t *kdf_context, uint32_t *clength, const uint8_t *arg1, const uint32_t a1length, const uint8_t *arg2, const uint32_t a2length, const uint8_t *arg3, const uint32_t a3length) { @@ -41,6 +83,7 @@ int f_function(const EVP_MD *md_type, uint8_t *kdf_context, uint32_t *clength, c if (((a1length) && (arg1 == NULL)) || ((a2length) && (arg2 == NULL)) || ((a3length) && (arg3 == NULL))) { break; } + if ((mdctx = EVP_MD_CTX_new()) == NULL) { break; } @@ -78,7 +121,160 @@ int f_function(const EVP_MD *md_type, uint8_t *kdf_context, uint32_t *clength, c } return rval; } -/* Implements the HMAC prf function from Section 7.3.2 */ +/* Implements the HMAC KDF function from Section 7.4.2 */ +/* Input: const EVP_MD *md_type */ +/* Input: const uint8_t *secret, *label, *context */ +/* Input: const uint32_t slength, llength, clength */ +/* Output: uint8_t *key_material, uint32_t *klength */ +/* Functionality: key_material = HMAC(secret, label, context, length) */ +int kdf_hkdf(const EVP_MD *md_type, uint8_t *key_material, uint32_t *klength, const uint8_t *secret, const uint32_t slength, + const uint8_t *label, const uint32_t llength, const uint8_t *context, const uint32_t clength) +{ + int rval = FAILURE; + EVP_PKEY_CTX *pctx = NULL; + size_t keylen; + + do { + if ((md_type == NULL) || (key_material == NULL) || (klength == NULL) || (secret == NULL)) { + break; + } + if (((llength) && (label == NULL)) || ((clength) && (context == NULL))) { + break; + } + if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL)) == NULL) { + break; + } + if (EVP_PKEY_derive_init(pctx) != 1) { + break; + } + if (EVP_PKEY_CTX_set_hkdf_md(pctx, md_type) != 1) { + break; + } + if (EVP_PKEY_CTX_set1_hkdf_salt(pctx, label, (int)llength) != 1) { + break; + } + if (EVP_PKEY_CTX_set1_hkdf_key(pctx, secret, (int)slength) != 1) { + break; + } + if (EVP_PKEY_CTX_add1_hkdf_info(pctx, context, (int)clength) != 1) { + break; + } + keylen = *klength; + if (EVP_PKEY_derive(pctx, key_material, &keylen) != 1) { + break; + } + *klength = (uint32_t)keylen; + rval = SUCCESS; + } while (0); + if (pctx) { + EVP_PKEY_CTX_free(pctx); + } + return rval; +} +/* Implements the HMAC KDF function from Section 7.4.2 */ +/* Input: const EVP_MD *md_type */ +/* Input: const uint8_t *secret, *label, *context */ +/* Input: const uint32_t slength, llength, clength */ +/* Output: uint8_t *key_material, uint32_t *klength */ +/* Functionality: key_material = HMAC(secret, label, context, length) */ +int kdf_hmac(const EVP_MD *md_type, uint8_t *key_material, uint32_t *klength, const uint8_t *secret, const uint32_t slength, + const uint8_t *label, const uint32_t llength, const uint8_t *context, const uint32_t clength) +{ + int rval = FAILURE; + size_t keylen; + EVP_KDF *kdf = NULL; + EVP_KDF_CTX *kctx = NULL; + OSSL_PARAM params[6], *p = params; + + do { + if ((key_material == NULL) || (klength == NULL) || (secret == NULL)) { + break; + } + if (((llength) && (label == NULL)) || ((clength) && (context == NULL))) { + break; + } + kdf = EVP_KDF_fetch(NULL, "SSKDF", NULL); + kctx = EVP_KDF_CTX_new(kdf); + + *p++ = OSSL_PARAM_construct_utf8_string("mac", (char *)"HMAC", strlen("HMAC")); + *p++ = OSSL_PARAM_construct_utf8_string("digest", (char *) EVP_MD_name(md_type), 0); + + *p++ = OSSL_PARAM_construct_octet_string("secret", (void *)secret, slength); + *p++ = OSSL_PARAM_construct_octet_string("salt", (void *)label, llength); + *p++ = OSSL_PARAM_construct_octet_string("info", (void *)context, clength); + *p = OSSL_PARAM_construct_end(); + + keylen = *klength; + if (EVP_KDF_derive(kctx, key_material, keylen, params) <= 0) { + break; + } + + *klength = keylen; + rval = SUCCESS; + } while (0); + if (kdf) { + EVP_KDF_free(kdf); + } + if (kctx) { + EVP_KDF_CTX_free(kctx); + } + return rval; +} +/* Implements the KMAC KDF function from Section 7.4.3 */ +/* Input: const char *kmac */ +/* Input: const uint8_t *secret, *label, *context */ +/* Input: const uint32_t slength, llength, clength */ +/* Output: uint8_t *key_material, uint32_t *klength */ +/* Functionality: key_material = KMAC#(label, counter || secret || context, length, "KDF") */ +/* Functionality: key_material = SSKDF_kmac(secret, label, context, length) */ +int kdf_kmac(const char *kmac, uint8_t *key_material, uint32_t *klength, const uint8_t *secret, const uint32_t slength, + const uint8_t *label, const uint32_t llength, const uint8_t *context, const uint32_t clength) +{ + int rval = FAILURE; + size_t keylen; + EVP_KDF *kdf = NULL; + EVP_KDF_CTX *kctx = NULL; + OSSL_PARAM params[5], *p = params; + + do { + if ((key_material == NULL) || (klength == NULL) || (secret == NULL)) { + break; + } + if (((llength) && (label == NULL)) || ((clength) && (context == NULL))) { + break; + } + kdf = EVP_KDF_fetch(NULL, "SSKDF", NULL); + kctx = EVP_KDF_CTX_new(kdf); + + *p++ = OSSL_PARAM_construct_utf8_string("mac", (char *)kmac, strlen(kmac)); + *p++ = OSSL_PARAM_construct_octet_string("secret", (void *)secret, slength); + *p++ = OSSL_PARAM_construct_octet_string("salt", (void *)label, llength); + *p++ = OSSL_PARAM_construct_octet_string("info", (void *)context, clength); + *p = OSSL_PARAM_construct_end(); + + keylen = *klength; + if (EVP_KDF_derive(kctx, key_material, keylen, params) <= 0) { + break; + } + + *klength = keylen; + rval = SUCCESS; + } while (0); + if (kdf) { + EVP_KDF_free(kdf); + } + if (kctx) { + EVP_KDF_CTX_free(kctx); + } + return rval; +} +/* Implements the HMAC prf function from Section 7.3.2 */ +/* Input: const EVP_MD *md_type */ +/* Input: const uint8_t *secret, *ki, *MAi, *MBi */ +/* Input: const uint8_t slength, const uint32_t kilength, mailength, mbilength */ +/* Output: uint8_t *output, uint32_t *olength */ +/* Functionality: context = cahb_f(ki, MAi, MBi) */ +/* Functionality: output = HMAC(secret, context) */ int prf_hmac(const EVP_MD *md_type, uint8_t *output, uint32_t *olength, const uint8_t *secret, const uint8_t slength, const uint8_t *ki, const uint32_t kilength, const uint8_t *MAi, const uint32_t mailength, const uint8_t *MBi, const uint32_t mbilength) @@ -87,8 +283,10 @@ int prf_hmac(const EVP_MD *md_type, uint8_t *output, uint32_t *olength, const ui uint32_t clength = MAX_DIGEST_BYTE_LEN; uint8_t context[MAX_DIGEST_BYTE_LEN]; size_t outlen = MAX_DIGEST_BYTE_LEN; - EVP_MD_CTX *mdctx = NULL; - EVP_PKEY * pkey = NULL; + + EVP_MAC_CTX *ctx = NULL; + EVP_MAC *mac = NULL; + OSSL_PARAM params[2], *p = params; do { if ((md_type == NULL) || (output == NULL) || (olength == NULL)) { @@ -100,86 +298,150 @@ int prf_hmac(const EVP_MD *md_type, uint8_t *output, uint32_t *olength, const ui if (((mailength) && (MAi == NULL)) || ((mbilength) && (MBi == NULL))) { break; } - if (f_function(md_type, context, &clength, ki, kilength, MAi, mailength, MBi, mbilength)) { + if (cahb_f(md_type, context, &clength, ki, kilength, MAi, mailength, MBi, mbilength)) { break; } - if ((mdctx = EVP_MD_CTX_new()) == NULL) { + // Use EVP_MAC struct to allow zero length secret |slength| + if ((mac = EVP_MAC_fetch(NULL, "HMAC", NULL)) == NULL) { break; } - if ((pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, secret, slength)) == NULL) { + if ((ctx = EVP_MAC_CTX_new(mac)) == NULL) { break; } - if (EVP_DigestSignInit(mdctx, NULL, md_type, NULL, pkey) != 1) { + *p++ = OSSL_PARAM_construct_utf8_string("digest", (char *) EVP_MD_name(md_type), 0); + *p = OSSL_PARAM_construct_end(); + if (!EVP_MAC_init(ctx, secret, slength, params)) { break; } - if (EVP_DigestSignUpdate(mdctx, context, clength) != 1) { + if (!EVP_MAC_update(ctx, context, clength)) { break; } outlen = *olength; - if (EVP_DigestSignFinal(mdctx, output, &outlen) != 1) { + if (!EVP_MAC_final(ctx, output, (size_t*) olength, outlen)) { break; } - *olength = (uint32_t)outlen; rval = SUCCESS; } while (0); - if (mdctx) { - EVP_MD_CTX_free(mdctx); + if (mac) { + EVP_MAC_free(mac); } - if (pkey) { - EVP_PKEY_free(pkey); + if (ctx) { + EVP_MAC_CTX_free(ctx); } return rval; } -/* Implements the HMAC KDF function from Section 7.4.2 */ -int kdf(const EVP_MD *md_type, uint8_t *key_material, uint32_t *klength, const uint8_t *secret, const uint32_t slength, - const uint8_t *label, const uint32_t llength, const uint8_t *context, const uint32_t clength) +/* Implements the KMAC PRF function from Section 7.3.3 */ +/* Input: const char *kmac */ +/* Input: const uint8_t *secret, *ki, *MAi, *MBi */ +/* Input: const uint8_t slength, const uint32_t kilength, mailength, mbilength */ +/* Output: uint8_t *output, uint32_t *olength */ +/* Functionality: context = cb_f(ki, MAi, MBi) */ +/* Functionality: output = KMAC#(secret, context, 256/512, NULL) */ +int prf_kmac(const char *kmac, uint8_t *output, uint32_t *olength, const uint8_t *secret, const uint8_t slength, + const uint8_t *ki, const uint32_t kilength, const uint8_t *MAi, const uint32_t mailength, + const uint8_t *MBi, const uint32_t mbilength) { - int rval = FAILURE; - EVP_PKEY_CTX *pctx = NULL; - size_t keylen; + int rval = FAILURE; + uint32_t clength = MAX_DIGEST_BYTE_LEN; + uint8_t context[MAX_BUFFER_SIZE]; + size_t outlen = MAX_DIGEST_BYTE_LEN; + EVP_MAC_CTX *ctx = NULL; + EVP_MAC *mac = NULL; + OSSL_PARAM params[5], *p = params; do { - if ((md_type == NULL) || (key_material == NULL) || (klength == NULL) || (secret == NULL)) { + if ((kmac == NULL) || (output == NULL) || (olength == NULL)) { break; } - if (((llength) && (label == NULL)) || ((clength) && (context == NULL))) { + if (((slength) && (secret == NULL)) || ((kilength) && (ki == NULL))) { break; } - if ((pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL)) == NULL) { + if (((mailength) && (MAi == NULL)) || ((mbilength) && (MBi == NULL))) { break; } - if (EVP_PKEY_derive_init(pctx) != 1) { + if (cb_f(context, &clength, ki, kilength, MAi, mailength, MBi, mbilength)) { break; } - if (EVP_PKEY_CTX_set_hkdf_md(pctx, md_type) != 1) { + mac = EVP_MAC_fetch(NULL, kmac, NULL); + if (!(ctx = EVP_MAC_CTX_new(mac))) { break; } - if (EVP_PKEY_CTX_set1_hkdf_salt(pctx, label, (int)llength) != 1) { + outlen = *olength; + *p++ = OSSL_PARAM_construct_int("size", (int *)olength); + *p = OSSL_PARAM_construct_end(); + if (!EVP_MAC_init(ctx, secret, slength, params)) { break; } - if (EVP_PKEY_CTX_set1_hkdf_key(pctx, secret, (int)slength) != 1) { + if (!EVP_MAC_update(ctx, context, clength)){ break; } - if (EVP_PKEY_CTX_add1_hkdf_info(pctx, context, (int)clength) != 1) { + if (!EVP_MAC_final(ctx, output, (size_t*)olength, outlen)){ break; } - keylen = *klength; - if (EVP_PKEY_derive(pctx, key_material, &keylen) != 1) { + rval = SUCCESS; + } while (0); + if (mac) { + EVP_MAC_free(mac); + } + if (ctx) { + EVP_MAC_CTX_free(ctx); + } + return rval; +} +/* Implements the function Concatenation HKDF KDF from Section 8.2 */ +/* Input: const EVP_MD *md_type */ +/* Input: uint8_t *psk, *k1, *k2, *MA, *MB, *info, *label */ +/* Input: const uint32_t klength, plength, k1length, k2length, malength, mblength, clength, llength */ +/* Output: uint8_t *key_material */ +int hkex_concat_hkdf(const EVP_MD *md_type, uint8_t *key_material, const uint32_t klength, const uint8_t *psk, + const uint32_t plength, const uint8_t *k1, const uint32_t k1length, const uint8_t *k2, + const uint32_t k2length, const uint8_t *MA, const uint32_t malength, const uint8_t *MB, + const uint32_t mblength, const uint8_t *info, const uint32_t ilength, const uint8_t *label, + const uint32_t llength) +{ + int rval = FAILURE; + uint8_t secrets[MAX_SECRETS_BYTE_LEN]; + uint8_t kdf_context[MAX_DIGEST_BYTE_LEN]; + uint32_t kmlength, slength, kdfclength; + uint64_t total_size; + do { + if ((md_type == NULL) || (key_material == NULL) || (k1 == NULL) || (k2 == NULL) || (MA == NULL) || + (MB == NULL)) { + break; + } + if (((llength) && (label == NULL)) || ((ilength) && (info == NULL)) || ((plength) && (psk == NULL))) { + break; + } + total_size = plength + k1length + k2length; + if (total_size > MAX_SECRETS_BYTE_LEN) { + break; + } + kdfclength = MAX_DIGEST_BYTE_LEN; + if (cahb_f(md_type, kdf_context, &kdfclength, info, ilength, MA, malength, MB, mblength)) { + break; + } + + my_memcpy(secrets, psk, plength); + my_memcpy(secrets + plength, k1, k1length); + my_memcpy(secrets + plength + k1length, k2, k2length); + slength = plength + k1length + k2length; + kmlength = klength; + if (kdf_hkdf(md_type, key_material, &kmlength, secrets, slength, label, llength, kdf_context, kdfclength)) { break; } - *klength = (uint32_t)keylen; rval = SUCCESS; } while (0); - if (pctx) { - EVP_PKEY_CTX_free(pctx); - } return rval; } -/* Implements the function Concatenation KDF from Section 8.2 */ -int hkex_concat(const EVP_MD *md_type, uint8_t *key_material, const uint32_t klength, const uint8_t *psk, +/* Implements the function Concatenation HMAC KDF from Section 8.2 */ +/* Input: const EVP_MD *md_type */ +/* Input: uint8_t *psk, *k1, *k2, *MA, *MB, *info, *label */ +/* Input: const uint32_t klength, plength, k1length, k2length, malength, mblength, clength, llength */ +/* Output: uint8_t *key_material */ +int hkex_concat_hmac(const EVP_MD *md_type, uint8_t *key_material, const uint32_t klength, const uint8_t *psk, const uint32_t plength, const uint8_t *k1, const uint32_t k1length, const uint8_t *k2, const uint32_t k2length, const uint8_t *MA, const uint32_t malength, const uint8_t *MB, - const uint32_t mblength, const uint8_t *context, const uint32_t clength, const uint8_t *label, + const uint32_t mblength, const uint8_t *info, const uint32_t ilength, const uint8_t *label, const uint32_t llength) { int rval = FAILURE; @@ -192,7 +454,7 @@ int hkex_concat(const EVP_MD *md_type, uint8_t *key_material, const uint32_t kle (MB == NULL)) { break; } - if (((llength) && (label == NULL)) || ((clength) && (context == NULL)) || ((plength) && (psk == NULL))) { + if (((llength) && (label == NULL)) || ((ilength) && (info == NULL)) || ((plength) && (psk == NULL))) { break; } total_size = plength + k1length + k2length; @@ -200,26 +462,74 @@ int hkex_concat(const EVP_MD *md_type, uint8_t *key_material, const uint32_t kle break; } kdfclength = MAX_DIGEST_BYTE_LEN; - if (f_function(md_type, kdf_context, &kdfclength, context, clength, MA, malength, MB, mblength)) { + if (cahb_f(md_type, kdf_context, &kdfclength, info, ilength, MA, malength, MB, mblength)) { break; } + my_memcpy(secrets, psk, plength); my_memcpy(secrets + plength, k1, k1length); my_memcpy(secrets + plength + k1length, k2, k2length); slength = plength + k1length + k2length; kmlength = klength; - if (kdf(md_type, key_material, &kmlength, secrets, slength, label, llength, kdf_context, kdfclength)) { + if (kdf_hmac(md_type, key_material, &kmlength, secrets, slength, label, llength, kdf_context, kdfclength)) { break; } - rval = SUCCESS; + rval = SUCCESS; } while (0); return rval; } -/* Implements the one round of the function Cascading KDF from Section 8.3 */ -int hkex_cascade(const EVP_MD *md_type, uint8_t *chain_secret, const uint32_t cslength, uint8_t *key_material, +/* Implements the function Concatenation KMAC KDF from Section 8.2 */ +/* Input: const char *kmac */ +/* Input: uint8_t *psk, *k1, *k2, *MA, *MB, *info, *label */ +/* Input: const uint32_t klength, plength, k1length, k2length, malength, mblength, ilength, llength */ +/* Output: uint8_t *key_material */ +int hkex_concat_kmac(const char *kmac, uint8_t *key_material, const uint32_t klength, const uint8_t *psk, + const uint32_t plength, const uint8_t *k1, const uint32_t k1length, const uint8_t *k2, + const uint32_t k2length, const uint8_t *MA, const uint32_t malength, const uint8_t *MB, + const uint32_t mblength, const uint8_t *info, const uint32_t ilength, const uint8_t *label, + const uint32_t llength) +{ + int rval = FAILURE; + uint8_t secrets[MAX_SECRETS_BYTE_LEN]; + uint8_t kdf_context[MAX_BUFFER_SIZE]; + uint32_t kmlength, slength, kdfclength; + uint64_t total_size; + do { + if ((key_material == NULL) || (k1 == NULL) || (k2 == NULL) || (MA == NULL) || + (MB == NULL)) { + break; + } + if (((llength) && (label == NULL)) || ((ilength) && (info == NULL)) || ((plength) && (psk == NULL))) { + break; + } + total_size = plength + k1length + k2length; + if (total_size > MAX_SECRETS_BYTE_LEN) { + break; + } + if (cb_f(kdf_context, &kdfclength, info, ilength, MA, malength, MB, mblength)) { + break; + } + my_memcpy(secrets, psk, plength); + my_memcpy(secrets + plength, k1, k1length); + my_memcpy(secrets + plength + k1length, k2, k2length); + slength = plength + k1length + k2length; + kmlength = klength; + if (kdf_kmac(kmac, key_material, &kmlength, secrets, slength, label, llength, kdf_context, kdfclength)) { + break; + } + rval = SUCCESS; + } while (0); + return rval; +} +/* Implements the one round of the function Cascading HMAC KDF from Section 8.3 */ +/* Input: const EVP_MD *md_type */ +/* Input: uint8_t *previous_chain_secret, *ki, *MAi, *MBi, infoi, *labeli */ +/* Input: const uint32_t cslength, klength, pcslength, kilength, mailength, mbilength, iilength, lilength */ +/* Output: uint8_t *chain_secret, *key_material */ +int hkex_cascade_hkdf(const EVP_MD *md_type, uint8_t *chain_secret, const uint32_t cslength, uint8_t *key_material, const uint32_t klength, const uint8_t *previous_chain_secret, const uint32_t pcslength, const uint8_t *ki, const uint32_t kilength, const uint8_t *MAi, const uint32_t mailength, - const uint8_t *MBi, const uint32_t mbilength, const uint8_t *contexti, const uint32_t cilength, + const uint8_t *MBi, const uint32_t mbilength, const uint8_t *infoi, const uint32_t iilength, const uint8_t *labeli, const uint32_t lilength) { int rval = FAILURE; @@ -233,7 +543,7 @@ int hkex_cascade(const EVP_MD *md_type, uint8_t *chain_secret, const uint32_t cs (MBi == NULL)) { break; } - if (((pcslength) && (previous_chain_secret == NULL)) || ((cilength) && (contexti == NULL)) || + if (((pcslength) && (previous_chain_secret == NULL)) || ((iilength) && (infoi == NULL)) || ((lilength) && (labeli == NULL))) { break; } @@ -249,7 +559,7 @@ int hkex_cascade(const EVP_MD *md_type, uint8_t *chain_secret, const uint32_t cs break; } olength = (uint32_t)osize; - if (kdf(md_type, output, &olength, rsecret, rlength, labeli, lilength, contexti, cilength)) { + if (kdf_hkdf(md_type, output, &olength, rsecret, rlength, labeli, lilength, infoi, iilength)) { break; } if (olength != (uint32_t)osize) { @@ -258,7 +568,111 @@ int hkex_cascade(const EVP_MD *md_type, uint8_t *chain_secret, const uint32_t cs my_memcpy(chain_secret, output, cslength); my_memcpy(key_material, output + cslength, klength); OPENSSL_cleanse(output, sizeof(output)); - rval = SUCCESS; + rval = SUCCESS; } while (0); return rval; } +/* Implements the one round of the function Cascading HMAC KDF from Section 8.3 */ +/* Input: const EVP_MD *md_type */ +/* Input: uint8_t *previous_chain_secret, *ki, *MAi, *MBi, infoi, *labeli */ +/* Input: const uint32_t cslength, klength, pcslength, kilength, mailength, mbilength, iilength, lilength */ +/* Output: uint8_t *chain_secret, *key_material */ +int hkex_cascade_hmac(const EVP_MD *md_type, uint8_t *chain_secret, const uint32_t cslength, uint8_t *key_material, + const uint32_t klength, const uint8_t *previous_chain_secret, const uint32_t pcslength, + const uint8_t *ki, const uint32_t kilength, const uint8_t *MAi, const uint32_t mailength, + const uint8_t *MBi, const uint32_t mbilength, const uint8_t *infoi, const uint32_t iilength, + const uint8_t *labeli, const uint32_t lilength) +{ + int rval = FAILURE; + uint8_t rsecret[MAX_DIGEST_BYTE_LEN]; + uint8_t output[MAX_KEY_MATERIAL_BYTE_LEN + MAX_DIGEST_BYTE_LEN]; + uint32_t olength, rlength = MAX_DIGEST_BYTE_LEN; + uint64_t osize; + + do { + if ((md_type == NULL) || (chain_secret == NULL) || (key_material == NULL) || (ki == NULL) || (MAi == NULL) || + (MBi == NULL)) { + break; + } + if (((pcslength) && (previous_chain_secret == NULL)) || ((iilength) && (infoi == NULL)) || + ((lilength) && (labeli == NULL))) { + break; + } + if ((cslength > MAX_DIGEST_BYTE_LEN) || (klength > MAX_KEY_MATERIAL_BYTE_LEN)) { + break; + } + osize = cslength + klength; + if (osize > sizeof(output)) { + break; + } + if (prf_hmac(md_type, rsecret, &rlength, previous_chain_secret, pcslength, ki, kilength, MAi, mailength, MBi, + mbilength)) { + break; + } + olength = (uint32_t)osize; + if (kdf_hmac(md_type, output, &olength, rsecret, rlength, labeli, lilength, infoi, iilength)) { + break; + } + if (olength != (uint32_t)osize) { + break; + } + my_memcpy(chain_secret, output, cslength); + my_memcpy(key_material, output + cslength, klength); + OPENSSL_cleanse(output, sizeof(output)); + rval = SUCCESS; + } while (0); + return rval; +} +/* Implements the function Cascade KMAC KDF from Section 8.3 */ +/* Input: const char *kmac */ +/* Input: uint8_t *previous_chain_secret, *ki, *MAi, *MBi, infoi, *labeli */ +/* Input: const uint32_t cslength, klength, pcslength, kilength, mailength, mbilength, iilength, lilength */ +/* Output: uint8_t *chain_secret, *key_material */ +int hkex_cascade_kmac(const char *kmac, uint8_t *chain_secret, const uint32_t cslength, uint8_t *key_material, + const uint32_t klength, const uint8_t *previous_chain_secret, const uint32_t pcslength, + const uint8_t *ki, const uint32_t kilength, const uint8_t *MAi, const uint32_t mailength, + const uint8_t *MBi, const uint32_t mbilength, const uint8_t *infoi, const uint32_t iilength, + const uint8_t *labeli, const uint32_t lilength) +{ + int rval = FAILURE; + uint8_t rsecret[MAX_DIGEST_BYTE_LEN]; + uint8_t output[MAX_KEY_MATERIAL_BYTE_LEN + MAX_DIGEST_BYTE_LEN]; + uint32_t olength; + uint32_t rlength; + uint64_t osize; + + do { + if ((kmac == NULL) || (chain_secret == NULL) || (key_material == NULL) || (ki == NULL) || (MAi == NULL) || + (MBi == NULL)) { + break; + } + if (((pcslength) && (previous_chain_secret == NULL)) || ((iilength) && (infoi == NULL)) || + ((lilength) && (labeli == NULL))) { + break; + } + if ((cslength > MAX_DIGEST_BYTE_LEN) || (klength > MAX_KEY_MATERIAL_BYTE_LEN)) { + break; + } + osize = cslength + klength; + if (osize > sizeof(output)) { + break; + } + rlength = cslength; + if (prf_kmac(kmac, rsecret, &rlength, previous_chain_secret, pcslength, ki, kilength, MAi, mailength, MBi, + mbilength)) { + break; + } + olength = (uint32_t)osize; + if (kdf_kmac(kmac, output, &olength, rsecret, rlength, labeli, lilength, infoi, iilength)) { + break; + } + if (olength != (uint32_t)osize) { + break; + } + my_memcpy(chain_secret, output, cslength); + my_memcpy(key_material, output + cslength, klength); + OPENSSL_cleanse(output, sizeof(output)); + rval = SUCCESS; + } while (0); + return rval; +} \ No newline at end of file diff --git a/qshkex.h b/qshkex.h index cc531d0..04651ff 100644 --- a/qshkex.h +++ b/qshkex.h @@ -26,18 +26,51 @@ #define MAX_SECRETS_BYTE_LEN 256 #define MAX_KEY_MATERIAL_BYTE_LEN 128 +#define MAX_BUFFER_SIZE 4096 +#define MAX_LABEL_BYTE_LEN 64 +#define MAX_KEY_BYTE_LEN 128 +#define MAX_LABEL_LEN 32 +#define KMAC128_OUT_BYTE_LENGTH 32 +#define KMAC256_OUT_BYTE_LENGTH 48 +#define MAX_MSG_BYTE_LEN 8192 + void print_array(const char *label, const uint8_t *array, const uint32_t alength); +void ascii_hex_strings_to_uint8(uint8_t *array, uint32_t *alength, const uint32_t scount, ...); + +int hkex_concat_hkdf(const EVP_MD *md_type, uint8_t *key_material, const uint32_t klength, const uint8_t *psk, + const uint32_t plength, const uint8_t *k1, const uint32_t k1length, const uint8_t *k2, + const uint32_t k2length, const uint8_t *MA, const uint32_t malength, const uint8_t *MB, + const uint32_t mblength, const uint8_t *info, const uint32_t ilength, const uint8_t *label, + const uint32_t llength); -int hkex_concat(const EVP_MD *md_type, uint8_t *key_material, const uint32_t klength, const uint8_t *psk, +int hkex_concat_hmac(const EVP_MD *md_type, uint8_t *key_material, const uint32_t klength, const uint8_t *psk, const uint32_t plength, const uint8_t *k1, const uint32_t k1length, const uint8_t *k2, const uint32_t k2length, const uint8_t *MA, const uint32_t malength, const uint8_t *MB, - const uint32_t mblength, const uint8_t *context, const uint32_t clength, const uint8_t *label, + const uint32_t mblength, const uint8_t *info, const uint32_t ilength, const uint8_t *label, const uint32_t llength); -int hkex_cascade(const EVP_MD *md_type, uint8_t *chain_secret, const uint32_t cslength, uint8_t *key_material, - const uint32_t klength, const uint8_t *previous_chain_secret, const uint32_t pcslength, - const uint8_t *ki, const uint32_t kilength, const uint8_t *MAi, const uint32_t mailength, - const uint8_t *MBi, const uint32_t mbilength, const uint8_t *contexti, const uint32_t cilength, - const uint8_t *labeli, const uint32_t lilength); +int hkex_concat_kmac(const char *kmac, uint8_t *key_material, const uint32_t klength, const uint8_t *psk, + const uint32_t plength, const uint8_t *k1, const uint32_t k1length, const uint8_t *k2, + const uint32_t k2length, const uint8_t *MA, const uint32_t malength, const uint8_t *MB, + const uint32_t mblength, const uint8_t *info, const uint32_t ilength, const uint8_t *label, + const uint32_t llength); + +int hkex_cascade_hkdf(const EVP_MD *md_type, uint8_t *chain_secret, const uint32_t cslength, uint8_t *key_material, + const uint32_t klength, const uint8_t *previous_chain_secret, const uint32_t pcslength, + const uint8_t *ki, const uint32_t kilength, const uint8_t *MAi, const uint32_t mailength, + const uint8_t *MBi, const uint32_t mbilength, const uint8_t *infoi, const uint32_t iilength, + const uint8_t *labeli, const uint32_t lilength); + +int hkex_cascade_hmac(const EVP_MD *md_type, uint8_t *chain_secret, const uint32_t cslength, uint8_t *key_material, + const uint32_t klength, const uint8_t *previous_chain_secret, const uint32_t pcslength, + const uint8_t *ki, const uint32_t kilength, const uint8_t *MAi, const uint32_t mailength, + const uint8_t *MBi, const uint32_t mbilength, const uint8_t *infoi, const uint32_t iilength, + const uint8_t *labeli, const uint32_t lilength); + +int hkex_cascade_kmac(const char *kmac, uint8_t *chain_secret, const uint32_t cslength, uint8_t *key_material, + const uint32_t klength, const uint8_t *previous_chain_secret, const uint32_t pcslength, + const uint8_t *ki, const uint32_t kilength, const uint8_t *MAi, const uint32_t mailength, + const uint8_t *MBi, const uint32_t mbilength, const uint8_t *infoi, const uint32_t iilength, + const uint8_t *labeli, const uint32_t lilength); #endif /*_QS_H_KEX_H_*/ -- GitLab From e6c75026d431410bf606bfcbecb521a63546c6d7 Mon Sep 17 00:00:00 2001 From: manastasova Date: Wed, 21 May 2025 13:41:37 -0700 Subject: [PATCH 2/6] Indentation fixes --- main.c | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/main.c b/main.c index 5879b21..a5083bd 100644 --- a/main.c +++ b/main.c @@ -48,18 +48,18 @@ const char *cids_concatenate_hkdf[TEST_VECTOR_CNT] = { "5531" // HMACwSHA384, ECDH with BP-P384, MLKEM1024, CatKDF }; const char *cids_concatenate_kmac[TEST_VECTOR_CNT] = { - "7111", // KMAC128, ECDH with P256, MLKEM512, CatKDF - "7711", // KMAC128, ECDH with Curve25519, MLKEM512, CatKDF - "7411", // KMAC128, ECDH with BP-P256, MLKEM512, CatKDF - "7121", // KMAC128, ECDH with P256, MLKEM768, CatKDF - "7721", // KMAC128, ECDH with Curve25519, MLKEM768, CatKDF - "7421", // KMAC128, ECDH with BP-P256, MLKEM768, CatKDF - "8221", // KMAC256, ECDH with P384, MLKEM768, CatKDF - "8821", // KMAC256, ECDH with Curve448, MLKEM768, CatKDF - "8521", // KMAC256, ECDH with BP-P384, MLKEM768, CatKDF - "8231", // KMAC256, ECDH with P384, MLKEM1024, CatKDF - "8831", // KMAC256, ECDH with Curve448, MLKEM1024, CatKDF - "8531" // KMAC256, ECDH with BP-P384, MLKEM1024, CatKDF + "7111", // KMAC128, ECDH with P256, MLKEM512, CatKDF + "7711", // KMAC128, ECDH with Curve25519, MLKEM512, CatKDF + "7411", // KMAC128, ECDH with BP-P256, MLKEM512, CatKDF + "7121", // KMAC128, ECDH with P256, MLKEM768, CatKDF + "7721", // KMAC128, ECDH with Curve25519, MLKEM768, CatKDF + "7421", // KMAC128, ECDH with BP-P256, MLKEM768, CatKDF + "8221", // KMAC256, ECDH with P384, MLKEM768, CatKDF + "8821", // KMAC256, ECDH with Curve448, MLKEM768, CatKDF + "8521", // KMAC256, ECDH with BP-P384, MLKEM768, CatKDF + "8231", // KMAC256, ECDH with P384, MLKEM1024, CatKDF + "8831", // KMAC256, ECDH with Curve448, MLKEM1024, CatKDF + "8531" // KMAC256, ECDH with BP-P384, MLKEM1024, CatKDF }; const char *cids_cascade_hkdf[TEST_VECTOR_CNT] = { @@ -91,18 +91,18 @@ const char *cids_cascade_hmac[TEST_VECTOR_CNT] = { "5532" // HMACwSHA384, ECDH with BP-P384, MLKEM1024, CasKDF }; const char *cids_cascade_kmac[TEST_VECTOR_CNT] = { - "7112", // KMAC128, ECDH with P256, MLKEM512, CasKDF - "7712", // KMAC128, ECDH with Curve25519, MLKEM512, CasKDF - "7412", // KMAC128, ECDH with BP-P256, MLKEM512, CasKDF - "7122", // KMAC128, ECDH with P256, MLKEM768, CasKDF - "7722", // KMAC128, ECDH with Curve25519, MLKEM768, CasKDF - "7422", // KMAC128, ECDH with BP-P256, MLKEM768, CasKDF - "8222", // KMAC256, ECDH with P384, MLKEM768, CasKDF - "8822", // KMAC256, ECDH with Curve448, MLKEM768, CasKDF - "8522", // KMAC256, ECDH with BP-P384, MLKEM768, CasKDF - "8232", // KMAC256, ECDH with P384, MLKEM1024, CasKDF - "8832", // KMAC256, ECDH with Curve448, MLKEM1024, CasKDF - "8532" // KMAC256, ECDH with BP-P384, MLKEM1024, CasKDF + "7112", // KMAC128, ECDH with P256, MLKEM512, CasKDF + "7712", // KMAC128, ECDH with Curve25519, MLKEM512, CasKDF + "7412", // KMAC128, ECDH with BP-P256, MLKEM512, CasKDF + "7122", // KMAC128, ECDH with P256, MLKEM768, CasKDF + "7722", // KMAC128, ECDH with Curve25519, MLKEM768, CasKDF + "7422", // KMAC128, ECDH with BP-P256, MLKEM768, CasKDF + "8222", // KMAC256, ECDH with P384, MLKEM768, CasKDF + "8822", // KMAC256, ECDH with Curve448, MLKEM768, CasKDF + "8522", // KMAC256, ECDH with BP-P384, MLKEM768, CasKDF + "8232", // KMAC256, ECDH with P384, MLKEM1024, CasKDF + "8832", // KMAC256, ECDH with Curve448, MLKEM1024, CasKDF + "8532" // KMAC256, ECDH with BP-P384, MLKEM1024, CasKDF }; const EVP_MD *(*evp_hash[TEST_VECTOR_CNT])(void) = { -- GitLab From fdc84ad3af7e42deb90076f1e2d21ca33df0c0b6 Mon Sep 17 00:00:00 2001 From: manastasova Date: Wed, 21 May 2025 16:34:46 -0700 Subject: [PATCH 3/6] Add all tests for derandomized qhkex --- Makefile | 136 +++++++++ crypto.c | 210 ++++++++++++++ crypto.h | 35 +++ main.c | 823 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- qshkex.c | 2 +- qshkex.h | 1 + 6 files changed, 1188 insertions(+), 19 deletions(-) create mode 100644 Makefile create mode 100644 crypto.c create mode 100644 crypto.h diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..862d2fa --- /dev/null +++ b/Makefile @@ -0,0 +1,136 @@ +# Makefile for ETSI TS 103 744 + +# Detect the operating system +UNAME_S := $(shell uname -s) + +# Compiler and flags +CC := gcc +CFLAGS := -Wall +LDFLAGS := -lcrypto -loqs + +# Directories +WORKSPACE := $(shell pwd)/quantumsafe +BUILD_DIR := $(WORKSPACE)/build +LIB_DIR := $(BUILD_DIR)/lib +SRC_DIR := $(shell pwd) +OBJ_DIR := $(shell pwd)/obj +BIN_DIR := $(shell pwd)/bin + +# Source and object files +SRCS := $(wildcard $(SRC_DIR)/*.c) +OBJS := $(SRCS:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o) + +# Target executable +TARGET := $(BIN_DIR)/etsi-hkex-test + +# Dependencies +DEPS := openssl liboqs oqs-provider + +# Phony targets +.PHONY: all update install setup openssl liboqs oqs-provider test-oqs update-ldconfig compile update-ldconfig clean +# + +# Default target +all: update install setup openssl liboqs oqs-provider test-oqs compile run +# all: update install setup openssl liboqs oqs-provider test-oqs compile + + +# Update and install necessary packages (OS-specific) +update: +ifeq ($(UNAME_S),Linux) + sudo apt update + sudo apt -y install git build-essential perl cmake autoconf libtool zlib1g-dev +else ifeq ($(UNAME_S),Darwin) + brew update + brew install git cmake autoconf automake libtool +endif + +# Setup workspace and build directory +setup: + mkdir -p $(LIB_DIR) + +# Clone and build OpenSSL +openssl: + @if [ ! -d $(WORKSPACE)/openssl ]; then \ + echo "Cloning and building OpenSSL..."; \ + cd $(WORKSPACE) && \ + git clone -b openssl-3.2 https://github.com/openssl/openssl && \ + cd openssl && \ + ./Configure \ + --prefix=$(BUILD_DIR) \ + no-ssl no-tls1 no-tls1_1 no-afalgeng \ + no-shared threads -lm && \ + make && \ + echo "OpenSSL cloned and built successfully."; \ + else \ + echo "OpenSSL directory already exists. Skipping clone and build."; \ + fi + +# Clone and build liboqs +liboqs: + @if [ ! -d $(WORKSPACE)/liboqs ]; then \ + echo "Cloning and building liboqs..."; \ + cd $(WORKSPACE) && \ + git clone https://github.com/open-quantum-safe/liboqs && \ + cd liboqs && \ + git checkout 0.13.0-release && \ + mkdir build && cd build && \ + cmake \ + -DBUILD_SHARED_LIBS=ON \ + -DOQS_USE_OPENSSL=OFF \ + -DCMAKE_BUILD_TYPE=Release \ + -DOQS_BUILD_ONLY_LIB=ON \ + -DOQS_DIST_BUILD=ON \ + .. && \ + make && \ + echo "liboqs cloned and built successfully."; \ + else \ + echo "liboqs directory already exists. Skipping clone and build."; \ + fi + +# Clone and build oqs-provider +oqs-provider: + @if [ ! -d $(WORKSPACE)/oqs-provider ]; then \ + echo "Cloning and building oqs-provider..." ; \ + cd $(WORKSPACE) && \ + git clone https://github.com/open-quantum-safe/oqs-provider && \ + cd oqs-provider && \ + git checkout 0.7.0-release && \ + liboqs_DIR=$(BUILD_DIR) cmake \ + -DOPENSSL_ROOT_DIR=$(WORKSPACE)/openssl/ \ + -DCMAKE_BUILD_TYPE=Release \ + -S . \ + -B $(BUILD_DIR) && \ + sudo cmake --build $(BUILD_DIR) ; \ + echo "oqs-provider cloned, built, and configured successfully."; \ + else \ + echo "oqs-provider directory already exists. Skipping clone and build."; \ + fi + +# Test OQS provider +test-oqs: + @echo "Testing OQS provider..." + @export OPENSSL_MODULES=$(BUILD_DIR)/lib && openssl list -kem-algorithms -provider oqsprovider + +# Compile the project +compile: + @echo "Compiling the project..." + gcc -Wall -o etsi-hkex-test main.c crypto.c qshkex.c -lcrypto -loqs \ + -I$(WORKSPACE)/liboqs/build/include/ \ + -L$(BUILD_DIR)/lib + @echo "Compilation completed. Executable: etsi-hkex-test" + + +# Run the compiled program +run: compile + @echo "Running etsi-hkex-test..." +ifeq ($(UNAME_S),Linux) + @export OPENSSL_MODULES=$(BUILD_DIR)/lib && ./etsi-hkex-test +else ifeq ($(UNAME_S),Darwin) + @DYLD_LIBRARY_PATH=$(BUILD_DIR)/lib:$$DYLD_LIBRARY_PATH ./etsi-hkex-test +endif + +# Clean up +clean: + rm -rf $(WORKSPACE) + rm -f etsi-hkex-test diff --git a/crypto.c b/crypto.c new file mode 100644 index 0000000..f89f587 --- /dev/null +++ b/crypto.c @@ -0,0 +1,210 @@ +/* + This file implements ETSI TC CYBER QSC Quantum-safe Hybrid Key Exchanges + (Version 1.1.1) + + This is not intended for production use. It is intended to be a reference + implementation for test vectors for the specification. + + It uses OpenSSL version 3.4.0 libcrypto. + + gcc -Wall -o etsi-hkex-test main.c crypto.c qshkex.c -lcrypto -loqs + ./etsi-hkex-test + + Copyright 2020 ETSI. All rights reserved + SPDX-License-Identifier: BSD-3-Clause +*/ + +#include "crypto.h" +#include "qshkex.h" + +#include +#include +#include +#include + +#include +#include + +// Custom deterministic RNG function +void deterministic_randombytes(unsigned char *random_array, size_t bytes_to_generate) +{ + uint32_t out_len = SEED_LEN_BYTES; + ascii_hex_strings_to_uint8(random_array, &out_len, 1, deterministic_seed[current_seed_index]); + if (out_len != bytes_to_generate) { + return; + } + current_seed_index++; +} + +int test_qhkex_derand_ecdh(const int curve, const char *priv_dataA, const char *peerB, uint8_t *pubA, size_t *PA1length, uint8_t *pubB, size_t *PB1length, uint8_t *ss, uint32_t *ss_len) +{ + int rval = FAILURE; + BIGNUM *privA = NULL, *x = NULL; + EC_POINT *peer_pointB = NULL, *shared_secret_point = NULL, *pub_keyA = NULL; + EC_GROUP *groupA = NULL; + EVP_PKEY_CTX *ctxA = NULL; + EVP_PKEY *pkeyA = NULL, *pkeyB = NULL; + size_t field_len, ss_lenA; + uint8_t shared_secretA[X448_KEY_LEN_BYTES]; + uint8_t hex_private_keyA[X448_KEY_LEN_BYTES]; + uint8_t pubA_cpy[MAX_KEY_BYTE_LEN], pubB_cpy[MAX_KEY_BYTE_LEN]; + uint8_t hex_exp_shared[MAX_KEY_BYTE_LEN]; + + do { + if (curve == EVP_PKEY_X25519 || curve == EVP_PKEY_X448) { + field_len = X25519_KEY_LEN_BYTES; + if (curve == EVP_PKEY_X448) { + field_len = X448_KEY_LEN_BYTES; + } + for (int i = 0; i < field_len; i++) { + sscanf(&priv_dataA[i * 2], "%2hhx", &hex_private_keyA[i]); + } + if (!(pkeyA = EVP_PKEY_new_raw_private_key(curve, NULL, hex_private_keyA, field_len))) { + break; + } + if (EVP_PKEY_get_raw_public_key(pkeyA, pubA, &field_len) <= 0) { + break; + } + *PA1length = field_len; + for (int i = 0; i < field_len; i++) { + sscanf(&peerB[i * 2], "%2hhx", &pubB[i]); + } + if(!(pkeyB = EVP_PKEY_new_raw_public_key(curve, NULL, pubB, field_len))) { + break; + } + *PB1length = field_len; + if (!(ctxA = EVP_PKEY_CTX_new(pkeyA, NULL))) { + break; + } + if (EVP_PKEY_derive_init(ctxA) <= 0) { + break; + } + if (EVP_PKEY_derive_set_peer(ctxA, pkeyB) <= 0) { + break; + } + ss_lenA = field_len; + if (EVP_PKEY_derive(ctxA, shared_secretA, &ss_lenA) <= 0) { + break; + } + memcpy(ss, shared_secretA, ss_lenA); + *ss_len = ss_lenA; + ascii_hex_strings_to_uint8(hex_exp_shared, (uint32_t *)&field_len, 1, strk1[current_seed_index/2]); + if (memcmp(ss, hex_exp_shared, field_len) != 0) { + break; + } + rval = SUCCESS; + } else { + if (BN_hex2bn(&privA, priv_dataA) <= 0) { + break; + } + if (!(groupA = EC_GROUP_new_by_curve_name(curve))) { + break; + } + if (!(pub_keyA = EC_POINT_new(groupA))) { + break; + } + if (!EC_POINT_mul(groupA, pub_keyA, privA, NULL, NULL, NULL)) { + break; + } + if (!EC_POINT_point2oct(groupA, pub_keyA, POINT_CONVERSION_UNCOMPRESSED, pubA_cpy, MAX_KEY_BUF_BYTES, NULL)) { + break; + } + if (!(peer_pointB = EC_POINT_hex2point(groupA, peerB, NULL, NULL))) { + break; + } + if (!EC_POINT_point2oct(groupA, peer_pointB, POINT_CONVERSION_UNCOMPRESSED, pubB_cpy, MAX_KEY_BUF_BYTES, NULL)) { + break; + } + if (!(shared_secret_point = EC_POINT_new(groupA))) { + break; + } + if (!EC_POINT_mul(groupA, shared_secret_point, NULL, peer_pointB, privA, NULL)) { + break; + } + if (!(x = BN_new())) { + break; + } + if (!EC_POINT_get_affine_coordinates(groupA, shared_secret_point, x, NULL, NULL)) { + break; + } + if (!(field_len = EC_GROUP_get_degree(groupA)/8)) { + break; + } + memcpy(pubA, pubA_cpy + 1, field_len*2); + *PA1length = field_len*2; + memcpy(pubB, pubB_cpy + 1, field_len*2); + *PB1length = field_len*2; + BN_bn2bin(x, ss); + *ss_len = field_len; + ascii_hex_strings_to_uint8(hex_exp_shared, (uint32_t *)&field_len, 1, strk1[current_seed_index/2]); + if (memcmp(ss, hex_exp_shared, field_len) != 0) { + break; + } + rval = SUCCESS; + } + } while (0); + if (privA) { + BN_free(privA); + } + if (x) { + BN_free(x); + } + if (peer_pointB) { + EC_POINT_free(peer_pointB); + } + if (shared_secret_point) { + EC_POINT_free(shared_secret_point); + } + if (pub_keyA) { + EC_POINT_free(pub_keyA); + } + if (groupA) { + EC_GROUP_free(groupA); + } + if (ctxA) { + EVP_PKEY_CTX_free(ctxA); + } + if (pkeyA) { + EVP_PKEY_free(pkeyA); + } + if (pkeyB) { + EVP_PKEY_free(pkeyB); + } + return rval; +} + +int test_qhkex_derand_mlkem(const char * alg_name, uint8_t *pubA, size_t *PA2length, uint8_t *ctB, size_t *CTB2length, uint8_t *ss, uint32_t *ss_len) +{ + int rval = FAILURE; + OQS_KEM *kem; + uint8_t sk[OQS_KEM_ml_kem_1024_length_secret_key], sharedB[OQS_KEM_ml_kem_1024_length_shared_secret], hex_exp_shared[OQS_KEM_ml_kem_1024_length_shared_secret]; + + do { + OQS_randombytes_custom_algorithm(deterministic_randombytes); + if (!(kem = OQS_KEM_new(alg_name))) { + break; + } + if (OQS_KEM_keypair(kem, pubA, sk) != OQS_SUCCESS) { + break; + } + *PA2length = kem->length_public_key; + if (OQS_KEM_encaps(kem, ctB, ss, pubA) != OQS_SUCCESS) { + break; + } + *CTB2length = kem->length_ciphertext; + if (OQS_KEM_decaps(kem, sharedB, ctB, sk) != OQS_SUCCESS) { + break; + } + *ss_len = OQS_KEM_ml_kem_1024_length_shared_secret; + ascii_hex_strings_to_uint8(hex_exp_shared, ss_len, 1, strk2[current_seed_index/2 - 1]); + if (memcmp(ss, sharedB, kem->length_shared_secret) != 0 || + memcmp(ss, hex_exp_shared, kem->length_shared_secret) != 0) { + break; + } + rval = SUCCESS; + } while (0); + if (kem) { + OQS_KEM_free(kem); + } + return rval; +} \ No newline at end of file diff --git a/crypto.h b/crypto.h new file mode 100644 index 0000000..b2c6938 --- /dev/null +++ b/crypto.h @@ -0,0 +1,35 @@ +/* + Header file for a reference implementation of + ETSI TC CYBER QSC Quantum-safe Hybrid Key Exchanges (Version 1.1.1) + + This is not intended for production use. It is intended to be a reference + implementation for test vectors for the specification. + + Copyright 2020 ETSI. All rights reserved + SPDX-License-Identifier: BSD-3-Clause +*/ + +#ifndef _QS_H_CRYPTO_KEX_H_ +#define _QS_H_CRYPTO_KEX_H_ + +#include +#include +#include +#include "qshkex.h" + +#define SEED_LEN_BYTES 64 +#define X25519_KEY_LEN_BYTES 32 +#define X448_KEY_LEN_BYTES 56 +#define MAX_KEY_BUF_BYTES 128 + +extern int current_seed_index; +extern const char *deterministic_seed[]; +extern const char *strk1[]; +extern const char *strk2[]; + +int test_qhkex_derand_ecdh(const int curve, const char *priv_dataA, const char *peerB, + uint8_t *pubA, size_t *PA1length, uint8_t *pubB, size_t *PB1length, + uint8_t *ss, uint32_t *ss_len); +int test_qhkex_derand_mlkem(const char * alg_name, uint8_t *pubA, size_t *PA2length, + uint8_t *ctB, size_t *CTB2length, uint8_t *ss, uint32_t *ss_len); +#endif /*_QS_H_CRYPTO_KEX_H_*/ diff --git a/main.c b/main.c index a5083bd..da8fbc3 100644 --- a/main.c +++ b/main.c @@ -15,6 +15,7 @@ */ #include "qshkex.h" +#include "crypto.h" #define TEST_VECTOR_CNT 12 #define INFO_TEST_VECTOR "ETSI_QSHKE_TEST_VECTORS_V_1_2" @@ -175,6 +176,8 @@ const char *kems_derand[TEST_VECTOR_CNT] = { "ML-KEM-1024", "ML-KEM-1024"}; +int current_seed_index; + const uint32_t key_length[TEST_VECTOR_CNT] = {16, 16, 16, 16, 16, 16, 24, 24, 24, 24, 24, 24}; // 64 bytes @@ -1569,8 +1572,6 @@ int test_hkex_concatenate_hmac() } return SUCCESS; } - - /* Testing harness for concatenation KDF (KMAC) with two exchanges */ int test_hkex_concatenate_kmac() { @@ -2014,26 +2015,812 @@ int test_hkex_cascade_kmac() return SUCCESS; } -int main(void) +/* Testing harness for concatenation KDF (HKDF) with derandomized ECC and PQ algorithms */ +int test_hkex_concatenate_hkdf_derand() { - if (test_hkex_concatenate_hkdf()) { - return FAILURE; - } - if (test_hkex_concatenate_hmac()) { - return FAILURE; - } - if (test_hkex_concatenate_kmac()) { - return FAILURE; - } - if (test_hkex_cascade_hkdf()) { - return FAILURE; + uint8_t PA_ECC[MAX_KEY_BYTE_LEN], PB_ECC[MAX_KEY_BYTE_LEN]; + uint8_t PA_PQ[MAX_MSG_BYTE_LEN], CTB_PQ[MAX_MSG_BYTE_LEN]; + size_t length; + size_t PA_ECC_length, PB_ECC_length, PA_PQ_length, CTB_PQ_length; + uint8_t k1[MAX_KEY_BYTE_LEN], k2[MAX_KEY_BYTE_LEN]; + uint8_t km[MAX_KEY_BYTE_LEN], key_material[MAX_KEY_BYTE_LEN]; + uint8_t MA[MAX_MSG_BYTE_LEN], MB[MAX_MSG_BYTE_LEN]; + uint8_t label[MAX_LABEL_BYTE_LEN], labelA[MAX_LABEL_BYTE_LEN], labelB[MAX_LABEL_BYTE_LEN]; + uint32_t alength, blength, llengthA, llengthB, klength, kmlength, k1length, k2length, r; + const EVP_MD *md_type; + current_seed_index = 0; + + for (r = 0; r < TEST_VECTOR_CNT; r++) { + md_type = (*evp_hash[r])(); + + printf("\nDerandomized CatKDF as HKDF/HMAC with %s, ECDH with %s, and %s \n\n", EVP_MD_name(md_type), OBJ_nid2sn(curves[r]), kems[r]); + printf("CID %s \n", cids_concatenate_hkdf[r]); + + if (test_qhkex_derand_ecdh(curves[r], strSA_ECC[r], strPB_ECC[r], PA_ECC, &PA_ECC_length, PB_ECC, &PB_ECC_length, k1, &k1length)) { + return FAILURE; + } + + if (test_qhkex_derand_mlkem(kems_derand[r], PA_PQ, &PA_PQ_length, CTB_PQ, &CTB_PQ_length, k2, &k2length)) { + return FAILURE; + } + + /* MA = cid || len(LA1) || LA1 || len(PA1) || PA1 || len(PA2) || PA2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + alength = sizeof(MA); + message_formatting_function(MA, &alength, 2, cids_concatenate_hkdf[r], strLA1[r]); + length = htonl(PA_ECC_length*2); + my_memcpy(MA + alength, &length, sizeof(uint32_t)); + alength += sizeof(uint32_t); + my_memcpy(MA + alength, PA_ECC, PA_ECC_length); + alength += PA_ECC_length; + length = htonl(PA_PQ_length*2); + my_memcpy(MA + alength, &length, sizeof(uint32_t)); + alength += sizeof(uint32_t); + my_memcpy(MA + alength, PA_PQ, PA_PQ_length); + alength += PA_PQ_length; + + /* MB = cid || len(LB1) || LB1 || len(PB1) || PB1 || len(PB2) || PB2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + blength = sizeof(MB); + message_formatting_function(MB, &blength, 2, cids_concatenate_hkdf[r], strLB1[r]); + length = htonl(PB_ECC_length*2); + my_memcpy(MB + blength, &length, sizeof(uint32_t)); + blength += sizeof(uint32_t); + my_memcpy(MB + blength, PB_ECC, PB_ECC_length); + blength += PB_ECC_length; + length = htonl(CTB_PQ_length*2); + my_memcpy(MB + blength, &length, sizeof(uint32_t)); + blength += sizeof(uint32_t); + my_memcpy(MB + blength, CTB_PQ, CTB_PQ_length); + blength += CTB_PQ_length; + + /* label = LA ^ LB */ + llengthA = sizeof(labelA); + ascii_hex_strings_to_uint8(labelA, &llengthA, 1, strLA1[r]); + llengthB = sizeof(labelB); + ascii_hex_strings_to_uint8(labelB, &llengthB, 1, strLB1[r]); + if (llengthA != llengthB) { + return FAILURE; + } + for (int i = 0; i < llengthA; i++) { + label[i] = labelA[i] ^ labelB[i]; + } + + klength = key_length[r]; + if (hkex_concat_hkdf(md_type, key_material, klength, NULL, 0, k1, k1length, k2, k2length, MA, alength, MB, + blength, (uint8_t *)INFO_TEST_VECTOR, + (uint32_t)strlen(INFO_TEST_VECTOR), label, llengthA)) { + return FAILURE; + } + printf("LA = %s\n", strLA1[r]); + print_array("PA1 = ", PA_ECC , PA_ECC_length); + print_array("PA2 = ", PA_PQ, PA_PQ_length); + printf("LB = %s\n", strLB1[r]); + print_array("PB1 = ", PB_ECC, PB_ECC_length); + print_array("PB2 = ", CTB_PQ, CTB_PQ_length); + print_array("k1 = ", k1, k1length); + print_array("k2 = ", k2, k2length); + printf("info = \"%s\"\n", INFO_TEST_VECTOR); + print_array("label = LA ^ LB = ", label, llengthA); + printf("MA = cid || len(LA)|| LA || len(PA1) || PA1 || len(PA2) || PA2\n"); + printf("MB = cid || len(LB)|| LB || len(PB1) || PB1 || len(PB2) || PB2\n\n"); + + print_array("key material = ", key_material, klength); + + kmlength = sizeof(km); + ascii_hex_strings_to_uint8(km, &kmlength, 1, strkmcat_hkdf[r]); + if (memcmp(km, key_material, key_length[r]) != 0) { + printf("Test vector %u failed\n", r); + return FAILURE; + } } - if (test_hkex_cascade_hmac()) { - return FAILURE; + return SUCCESS; +} +/* Testing harness for concatenation KDF (HMAC) with derandomized ECC and PQ algorithms */ +int test_hkex_concatenate_hmac_derand() +{ + uint8_t PA_ECC[MAX_KEY_BYTE_LEN], PB_ECC[MAX_KEY_BYTE_LEN]; + uint8_t PA_PQ[MAX_MSG_BYTE_LEN], CTB_PQ[MAX_MSG_BYTE_LEN]; + size_t length; + size_t PA_ECC_length, PB_ECC_length, PA_PQ_length, CTB_PQ_length; + uint8_t k1[MAX_KEY_BYTE_LEN], k2[MAX_KEY_BYTE_LEN]; + uint8_t km[MAX_KEY_BYTE_LEN], key_material[MAX_KEY_BYTE_LEN]; + uint8_t MA[MAX_MSG_BYTE_LEN], MB[MAX_MSG_BYTE_LEN]; + uint8_t label[MAX_LABEL_BYTE_LEN], labelA[MAX_LABEL_BYTE_LEN], labelB[MAX_LABEL_BYTE_LEN]; + uint32_t alength, blength, llengthA, llengthB, klength, kmlength, k1length; + uint32_t k2length, r; + const EVP_MD *md_type; + current_seed_index = 0; + + for (r = 0; r < TEST_VECTOR_CNT; r++) { + md_type = (*evp_hash[r])(); + + printf("\nDerandomized CatKDF as HMAC with %s, ECDH with %s, and %s \n\n", EVP_MD_name(md_type), OBJ_nid2sn(curves[r]), kems[r]); + printf("CID %s \n", cids_concatenate_hmac[r]); + + if (test_qhkex_derand_ecdh(curves[r], strSA_ECC[r], strPB_ECC[r], PA_ECC, &PA_ECC_length, PB_ECC, &PB_ECC_length, k1, &k1length)) { + return FAILURE; + } + + if (test_qhkex_derand_mlkem(kems_derand[r], PA_PQ, &PA_PQ_length, CTB_PQ, &CTB_PQ_length, k2, &k2length)) { + return FAILURE; + } + + /* MA = cid || len(LA1) || LA1 || len(PA1) || PA1 || len(PA2) || PA2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + alength = sizeof(MA); + message_formatting_function(MA, &alength, 2, cids_concatenate_hmac[r], strLA1[r]); + length = htonl(PA_ECC_length*2); + my_memcpy(MA + alength, &length, sizeof(uint32_t)); + alength += sizeof(uint32_t); + my_memcpy(MA + alength, PA_ECC, PA_ECC_length); + alength += PA_ECC_length; + length = htonl(PA_PQ_length*2); + my_memcpy(MA + alength, &length, sizeof(uint32_t)); + alength += sizeof(uint32_t); + my_memcpy(MA + alength, PA_PQ, PA_PQ_length); + alength += PA_PQ_length; + + /* MA = cid || len(LB1) || LB1 || len(PB1) || PB1 || len(PB2) || PB2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + blength = sizeof(MB); + message_formatting_function(MB, &blength, 2, cids_concatenate_hmac[r], strLB1[r]); + length = htonl(PB_ECC_length*2); + my_memcpy(MB + blength, &length, sizeof(uint32_t)); + blength += sizeof(uint32_t); + my_memcpy(MB + blength, PB_ECC, PB_ECC_length); + blength += PB_ECC_length; + length = htonl(CTB_PQ_length*2); + my_memcpy(MB + blength, &length, sizeof(uint32_t)); + blength += sizeof(uint32_t); + my_memcpy(MB + blength, CTB_PQ, CTB_PQ_length); + blength += CTB_PQ_length; + + /* label = LA ^ LB */ + llengthA = sizeof(labelA); + ascii_hex_strings_to_uint8(labelA, &llengthA, 1, strLA1[r]); + llengthB = sizeof(labelB); + ascii_hex_strings_to_uint8(labelB, &llengthB, 1, strLB1[r]); + if (llengthA != llengthB) { + return FAILURE; + } + for (int i = 0; i < llengthA; i++) { + label[i] = labelA[i] ^ labelB[i]; + } + + klength = key_length[r]; + if (hkex_concat_hmac(md_type, key_material, klength, NULL, 0, k1, k1length, k2, k2length, MA, alength, MB, + blength, (uint8_t *)INFO_TEST_VECTOR, + (uint32_t)strlen(INFO_TEST_VECTOR), label, llengthA)) { + return FAILURE; + } + printf("LA = %s\n", strLA1[r]); + print_array("PA1 = ", PA_ECC , PA_ECC_length); + print_array("PA2 = ", PA_PQ, PA_PQ_length); + printf("LB = %s\n", strLB1[r]); + print_array("PB1 = ", PB_ECC, PB_ECC_length); + print_array("PB2 = ", CTB_PQ, CTB_PQ_length); + print_array("k1 = ", k1, k1length); + print_array("k2 = ", k2, k2length); + printf("info = \"%s\"\n", INFO_TEST_VECTOR); + print_array("label = LA ^ LB = ", label, llengthA); + printf("MA = cid || len(LA)|| LA || len(PA1) || PA1 || len(PA2) || PA2\n"); + printf("MB = cid || len(LB)|| LB || len(PB1) || PB1 || len(PB2) || PB2\n\n"); + + print_array("key material = ", key_material, klength); + + kmlength = sizeof(km); + ascii_hex_strings_to_uint8(km, &kmlength, 1, strkmcat_hmac[r]); + if (memcmp(km, key_material, key_length[r]) != 0) { + printf("Test vector %u failed\n", r); + return FAILURE; + } } - if (test_hkex_cascade_kmac()) { - return FAILURE; + return SUCCESS; +} +/* Testing harness for concatenation KDF (KMAC) with derandomized ECC and PQ algorithms */ +int test_hkex_concatenate_kmac_derand() +{ + uint8_t PA_ECC[MAX_KEY_BYTE_LEN], PB_ECC[MAX_KEY_BYTE_LEN]; + uint8_t PA_PQ[MAX_MSG_BYTE_LEN], CTB_PQ[MAX_MSG_BYTE_LEN]; + size_t length; + size_t PA_ECC_length, PB_ECC_length, PA_PQ_length, CTB_PQ_length; + uint8_t k1[MAX_KEY_BYTE_LEN], k2[MAX_KEY_BYTE_LEN]; + uint8_t km[MAX_KEY_BYTE_LEN], key_material[MAX_KEY_BYTE_LEN]; + uint8_t MA[MAX_MSG_BYTE_LEN], MB[MAX_MSG_BYTE_LEN]; + uint8_t label[MAX_LABEL_BYTE_LEN], labelA[MAX_LABEL_BYTE_LEN], labelB[MAX_LABEL_BYTE_LEN]; + uint32_t alength, blength, llengthA, llengthB, klength, kmlength, k1length; + uint32_t k2length, r; + current_seed_index = 0; + + for (r = 0; r < TEST_VECTOR_CNT; r++) { + printf("\nDerandomized CatKDF as %s, ECDH with %s, and %s \n\n", kmac[r], OBJ_nid2sn(curves[r]), kems[r]); + printf("CID %s \n", cids_concatenate_kmac[r]); + + if (test_qhkex_derand_ecdh(curves[r], strSA_ECC[r], strPB_ECC[r], PA_ECC, &PA_ECC_length, PB_ECC, &PB_ECC_length, k1, &k1length)) { + return FAILURE; + } + + if (test_qhkex_derand_mlkem(kems_derand[r], PA_PQ, &PA_PQ_length, CTB_PQ, &CTB_PQ_length, k2, &k2length)) { + return FAILURE; + } + + /* MA = cid || len(LA1) || LA1 || len(PA1) || PA1 || len(PA2) || PA2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + alength = sizeof(MA); + message_formatting_function(MA, &alength, 2, cids_concatenate_kmac[r], strLA1[r]); + length = htonl(PA_ECC_length*2); + my_memcpy(MA + alength, &length, sizeof(uint32_t)); + alength += sizeof(uint32_t); + my_memcpy(MA + alength, PA_ECC, PA_ECC_length); + alength += PA_ECC_length; + length = htonl(PA_PQ_length*2); + my_memcpy(MA + alength, &length, sizeof(uint32_t)); + alength += sizeof(uint32_t); + my_memcpy(MA + alength, PA_PQ, PA_PQ_length); + alength += PA_PQ_length; + + /* MA = cid || len(LB1) || LB1 || len(PB1) || PB1 || len(PB2) || PB2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + blength = sizeof(MB); + message_formatting_function(MB, &blength, 2, cids_concatenate_kmac[r], strLB1[r]); + length = htonl(PB_ECC_length*2); + my_memcpy(MB + blength, &length, sizeof(uint32_t)); + blength += sizeof(uint32_t); + my_memcpy(MB + blength, PB_ECC, PB_ECC_length); + blength += PB_ECC_length; + length = htonl(CTB_PQ_length*2); + my_memcpy(MB + blength, &length, sizeof(uint32_t)); + blength += sizeof(uint32_t); + my_memcpy(MB + blength, CTB_PQ, CTB_PQ_length); + blength += CTB_PQ_length; + + /* label = LA ^ LB */ + llengthA = sizeof(labelA); + ascii_hex_strings_to_uint8(labelA, &llengthA, 1, strLA1[r]); + llengthB = sizeof(labelB); + ascii_hex_strings_to_uint8(labelB, &llengthB, 1, strLB1[r]); + if (llengthA != llengthB) { + return FAILURE; + } + for (int i = 0; i < llengthA; i++) { + label[i] = labelA[i] ^ labelB[i]; + } + + klength = key_length[r]; + if (hkex_concat_kmac(kmac[r], key_material, klength, NULL, 0, k1, k1length, k2, k2length, MA, alength, MB, + blength, (uint8_t *)INFO_TEST_VECTOR, + (uint32_t)strlen(INFO_TEST_VECTOR), label, llengthA)) { + return FAILURE; + } + printf("LA = %s\n", strLA1[r]); + print_array("PA1 = ", PA_ECC , PA_ECC_length); + print_array("PA2 = ", PA_PQ, PA_PQ_length); + printf("LB = %s\n", strLB1[r]); + print_array("PB1 = ", PB_ECC, PB_ECC_length); + print_array("PB2 = ", CTB_PQ, CTB_PQ_length); + print_array("k1 = ", k1, k1length); + print_array("k2 = ", k2, k2length); + printf("info = \"%s\"\n", INFO_TEST_VECTOR); + print_array("label = LA ^ LB = ", label, llengthA); + printf("MA = cid || len(LA)|| LA || len(PA1) || PA1 || len(PA2) || PA2\n"); + printf("MB = cid || len(LB)|| LB || len(PB1) || PB1 || len(PB2) || PB2\n\n"); + + print_array("key material = ", key_material, klength); + + kmlength = sizeof(km); + ascii_hex_strings_to_uint8(km, &kmlength, 1, strkmcat_kmac[r]); + if (memcmp(km, key_material, key_length[r]) != 0) { + printf("Test vector %u failed\n", r); + return FAILURE; + } } + return SUCCESS; +} + +/* Testing harness for the cascade KDF (HKDF) with derandomized ECC and PQ algorithms */ +int test_hkex_cascade_hkdf_derand() +{ + uint8_t PA_ECC[MAX_KEY_BYTE_LEN], PB_ECC[MAX_KEY_BYTE_LEN]; + uint8_t PA_PQ[MAX_MSG_BYTE_LEN], CTB_PQ[MAX_MSG_BYTE_LEN]; + size_t length; + size_t PA_ECC_length, PB_ECC_length, PA_PQ_length, CTB_PQ_length; + uint8_t k1[MAX_KEY_BYTE_LEN], k2[MAX_KEY_BYTE_LEN]; + uint8_t km[MAX_KEY_BYTE_LEN], round_secret[MAX_KEY_BYTE_LEN]; + uint8_t MA[MAX_MSG_BYTE_LEN], MB[MAX_MSG_BYTE_LEN]; + uint8_t label[MAX_LABEL_BYTE_LEN], labelA[MAX_LABEL_BYTE_LEN], labelB[MAX_LABEL_BYTE_LEN]; + uint8_t chain_secret1[MAX_KEY_BYTE_LEN], chain_secret2[MAX_KEY_BYTE_LEN]; + uint32_t alength, blength, llengthA, llengthB, clength, rlength, kmlength; + uint32_t k1length, k2length, r; + const EVP_MD *md_type; + current_seed_index = 0; + + for (r = 0; r < TEST_VECTOR_CNT; r++) { + md_type = (*evp_hash[r])(); + + printf("\nDerandomized CasKDF as HKDF with %s, ECDH with %s, and %s \n\n", EVP_MD_name(md_type), OBJ_nid2sn(curves[r]), kems[r]); + printf("CID %s \n", cids_cascade_hkdf[r]); + + if (test_qhkex_derand_ecdh(curves[r], strSA_ECC[r], strPB_ECC[r], PA_ECC, &PA_ECC_length, PB_ECC, &PB_ECC_length, k1, &k1length)) { + return FAILURE; + } + + if (test_qhkex_derand_mlkem(kems_derand[r], PA_PQ, &PA_PQ_length, CTB_PQ, &CTB_PQ_length, k2, &k2length)) { + return FAILURE; + } + + /* MA = cid || len(LA1) || LA1 || len(PA1) || PA1 + NOTE: for test vector purposes ONLY not a suggested message format + */ + alength = sizeof(MA); + message_formatting_function(MA, &alength, 2, cids_cascade_hkdf[r], strLA1[r]); + length = htonl(PA_ECC_length*2); + my_memcpy(MA + alength, &length, sizeof(uint32_t)); + alength += sizeof(uint32_t); + my_memcpy(MA + alength, PA_ECC, PA_ECC_length); + alength += PA_ECC_length; + + /* MB = cid || len(LB1) || LB1 || len(PB1) || PB1 + NOTE: for test vector purposes ONLY not a suggested message format + */ + blength = sizeof(MB); + message_formatting_function(MB, &blength, 2, cids_cascade_hkdf[r], strLB1[r]); + length = htonl(PB_ECC_length*2); + my_memcpy(MB + blength, &length, sizeof(uint32_t)); + blength += sizeof(uint32_t); + my_memcpy(MB + blength, PB_ECC, PB_ECC_length); + blength += PB_ECC_length; + + /* label = LA1 ^ LB1 */ + llengthA = sizeof(labelA); + ascii_hex_strings_to_uint8(labelA, &llengthA, 1, strLA1[r]); + llengthB = sizeof(labelB); + ascii_hex_strings_to_uint8(labelB, &llengthB, 1, strLB1[r]); + if (llengthA != llengthB) { + return FAILURE; + } + for (int i = 0; i < llengthA; i++) { + label[i] = labelA[i] ^ labelB[i]; + } + + rlength = key_length[r]; + clength = EVP_MD_size(md_type); + const uint8_t chain_secret0[] = {}; // OpenSSL3.x does not allow NULL pointer HMAC input + if (hkex_cascade_hkdf(md_type, chain_secret1, clength, round_secret, rlength, chain_secret0, 0, k1, k1length, MA, alength, + MB, blength, (uint8_t *)INFO_TEST_VECTOR, + (uint32_t)strlen(INFO_TEST_VECTOR), label, llengthA)) { + return FAILURE; + } + + printf("LA1 = %s\n", strLA1[r]); + print_array("PA1 = ", PA_ECC, PA_ECC_length); + printf("LB1 = %s\n", strLB1[r]); + print_array("PB1 = ", PB_ECC, PB_ECC_length); + printf("previous_chain_secret = psk = \n"); + print_array("k1 = ", k1, k1length); + printf("info1 = \"%s\"\n", INFO_TEST_VECTOR); + printf("label1 = LA1 ^ LB1\n"); + printf("MA1 = cid || len(LA1) || LA1 || len(PA1) || PA1\n"); + printf("MB1 = cid || len(LB1) || LB1 || len(PB1) || PB1\n"); + + print_array("chain_secret1 = ", chain_secret1, clength); + print_array("key_material1 = ", round_secret, rlength); + + /* MA = cid || len(LA2) || LA2 || len(PA2) || PA2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + alength = sizeof(MA); + message_formatting_function(MA, &alength, 2, cids_cascade_hkdf[r], strLA2[r]); + length = htonl(PA_PQ_length*2); + my_memcpy(MA + alength, &length, sizeof(uint32_t)); + alength += sizeof(uint32_t); + my_memcpy(MA + alength, PA_PQ, PA_PQ_length); + alength += PA_PQ_length; + + /* MB = cid || len(LB2) || LB2 || len(PB2) || PB2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + blength = sizeof(MB); + message_formatting_function(MB, &blength, 2, cids_cascade_hkdf[r], strLB2[r]); + length = htonl(CTB_PQ_length*2); + my_memcpy(MB + blength, &length, sizeof(uint32_t)); + blength += sizeof(uint32_t); + my_memcpy(MB + blength, CTB_PQ, CTB_PQ_length); + blength += CTB_PQ_length; + + /* label = LA2 ^ LB2 */ + llengthA = sizeof(labelA); + ascii_hex_strings_to_uint8(labelA, &llengthA, 1, strLA2[r]); + llengthB = sizeof(labelB); + ascii_hex_strings_to_uint8(labelB, &llengthB, 1, strLB2[r]); + if (llengthA != llengthB) { + return FAILURE; + } + for (int i = 0; i < llengthA; i++) { + label[i] = labelA[i] ^ labelB[i]; + } + + if (hkex_cascade_hkdf(md_type, chain_secret2, clength, round_secret, rlength, chain_secret1, clength, k2, + k2length, MA, alength, MB, blength, (uint8_t *)INFO_TEST_VECTOR, + (uint32_t)strlen(INFO_TEST_VECTOR), label, llengthA)) { + return FAILURE; + } + printf("LA2 = %s\n", strLA2[r]); + print_array("PA2 = ", PA_PQ, PA_PQ_length); + printf("LB2 = %s\n", strLB2[r]); + print_array("PB2 = ", CTB_PQ, CTB_PQ_length); + print_array("previous_chain_secret = ", chain_secret1, clength); + print_array("k2 = ", k2, k2length); + printf("info2 = \"%s\"\n", INFO_TEST_VECTOR); + printf("label2 = LA2 ^ LB2\n"); + printf("MA2 = cid || len(LA2) || LA2 || len(PA2) || PA2\n"); + printf("MB2 = cid || len(LB2) || LB2 || len(PB2) || PB2\n\n"); + + print_array("chain_secret2 = ", chain_secret2, clength); + print_array("key_material2 = ", round_secret, rlength); + + kmlength = sizeof(km); + ascii_hex_strings_to_uint8(km, &kmlength, 1, strkmcas_hkdf[r]); + if (memcmp(km, round_secret, key_length[r]) != 0) { + printf("Test vector %u failed\n", r); + return FAILURE; + } + } + return SUCCESS; +} +/* Testing harness for the cascade KDF (HMAC) with derandomized ECC and PQ algorithms */ +int test_hkex_cascade_hmac_derand() +{ + uint8_t PA_ECC[MAX_KEY_BYTE_LEN], PB_ECC[MAX_KEY_BYTE_LEN]; + uint8_t PA_PQ[MAX_MSG_BYTE_LEN], CTB_PQ[MAX_MSG_BYTE_LEN]; + size_t length; + size_t PA_ECC_length, PB_ECC_length, PA_PQ_length, CTB_PQ_length; + uint8_t k1[MAX_KEY_BYTE_LEN], k2[MAX_KEY_BYTE_LEN]; + uint8_t km[MAX_KEY_BYTE_LEN], round_secret[MAX_KEY_BYTE_LEN]; + uint8_t MA[MAX_MSG_BYTE_LEN], MB[MAX_MSG_BYTE_LEN]; + uint8_t label[MAX_LABEL_BYTE_LEN], labelA[MAX_LABEL_BYTE_LEN], labelB[MAX_LABEL_BYTE_LEN]; + uint8_t chain_secret1[MAX_KEY_BYTE_LEN], chain_secret2[MAX_KEY_BYTE_LEN]; + uint32_t alength, blength, llengthA, llengthB, clength, rlength, kmlength; + uint32_t k1length, k2length, r; + const EVP_MD *md_type; + current_seed_index = 0; + + for (r = 0; r < TEST_VECTOR_CNT; r++) { + md_type = (*evp_hash[r])(); + + printf("\nDerandomized CasKDF as HMAC/HMAC with %s, ECDH with %s, and %s \n\n", EVP_MD_name(md_type), OBJ_nid2sn(curves[r]), kems[r]); + printf("CID %s \n", cids_cascade_hmac[r]); + + if (test_qhkex_derand_ecdh(curves[r], strSA_ECC[r], strPB_ECC[r], PA_ECC, &PA_ECC_length, PB_ECC, &PB_ECC_length, k1, &k1length)) { + return FAILURE; + } + + if (test_qhkex_derand_mlkem(kems_derand[r], PA_PQ, &PA_PQ_length, CTB_PQ, &CTB_PQ_length, k2, &k2length)) { + return FAILURE; + } + + /* MA = cid || len(LA1) || LA1 || len(PA1) || PA1 + NOTE: for test vector purposes ONLY not a suggested message format + */ + alength = sizeof(MA); + message_formatting_function(MA, &alength, 2, cids_cascade_hmac[r], strLA1[r]); + length = htonl(PA_ECC_length*2); + my_memcpy(MA + alength, &length, sizeof(uint32_t)); + alength += sizeof(uint32_t); + my_memcpy(MA + alength, PA_ECC, PA_ECC_length); + alength += PA_ECC_length; + + /* MB = cid || len(LB1) || LB1 || len(PB1) || PB1 + NOTE: for test vector purposes ONLY not a suggested message format + */ + blength = sizeof(MB); + message_formatting_function(MB, &blength, 2, cids_cascade_hmac[r], strLB1[r]); + length = htonl(PB_ECC_length*2); + my_memcpy(MB + blength, &length, sizeof(uint32_t)); + blength += sizeof(uint32_t); + my_memcpy(MB + blength, PB_ECC, PB_ECC_length); + blength += PB_ECC_length; + + /* label = LA1 ^ LB1 */ + llengthA = sizeof(labelA); + ascii_hex_strings_to_uint8(labelA, &llengthA, 1, strLA1[r]); + llengthB = sizeof(labelB); + ascii_hex_strings_to_uint8(labelB, &llengthB, 1, strLB1[r]); + if (llengthA != llengthB) { + return FAILURE; + } + for (int i = 0; i < llengthA; i++) { + label[i] = labelA[i] ^ labelB[i]; + } + + rlength = key_length[r]; + clength = EVP_MD_size(md_type); + const uint8_t chain_secret0[] = {}; // OpenSSL3.x does not allow NULL pointer HMAC input + if (hkex_cascade_hmac(md_type, chain_secret1, clength, round_secret, rlength, chain_secret0, 0, k1, k1length, MA, alength, + MB, blength, (uint8_t *)INFO_TEST_VECTOR, + (uint32_t)strlen(INFO_TEST_VECTOR), label, llengthA)) { + return FAILURE; + } + + printf("LA1 = %s\n", strLA1[r]); + print_array("PA1 = ", PA_ECC, PA_ECC_length); + printf("LB1 = %s\n", strLB1[r]); + print_array("PB1 = ", PB_ECC, PB_ECC_length); + printf("previous_chain_secret = psk = \n"); + print_array("k1 = ", k1, k1length); + printf("info1 = \"%s\"\n", INFO_TEST_VECTOR); + printf("label1 = LA1 ^ LB1\n"); + printf("MA1 = cid || len(LA1) || LA1 || len(PA1) || PA1\n"); + printf("MB1 = cid || len(LB1) || LB1 || len(PB1) || PB1\n"); + + print_array("chain_secret1 = ", chain_secret1, clength); + print_array("key_material1 = ", round_secret, rlength); + + /* MA = cid || len(LA2) || LA2 || len(PA2) || PA2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + alength = sizeof(MA); + message_formatting_function(MA, &alength, 2, cids_cascade_hmac[r], strLA2[r]); + length = htonl(PA_PQ_length*2); + my_memcpy(MA + alength, &length, sizeof(uint32_t)); + alength += sizeof(uint32_t); + my_memcpy(MA + alength, PA_PQ, PA_PQ_length); + alength += PA_PQ_length; + /* MB = cid || len(LB2) || LB2 || len(PB2) || PB2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + blength = sizeof(MB); + message_formatting_function(MB, &blength, 2, cids_cascade_hmac[r], strLB2[r]); + length = htonl(CTB_PQ_length*2); + my_memcpy(MB + blength, &length, sizeof(uint32_t)); + blength += sizeof(uint32_t); + my_memcpy(MB + blength, CTB_PQ, CTB_PQ_length); + blength += CTB_PQ_length; + + /* label = LA2 ^ LB2 */ + llengthA = sizeof(labelA); + ascii_hex_strings_to_uint8(labelA, &llengthA, 1, strLA2[r]); + llengthB = sizeof(labelB); + ascii_hex_strings_to_uint8(labelB, &llengthB, 1, strLB2[r]); + if (llengthA != llengthB) { + return FAILURE; + } + for (int i = 0; i < llengthA; i++) { + label[i] = labelA[i] ^ labelB[i]; + } + + if (hkex_cascade_hmac(md_type, chain_secret2, clength, round_secret, rlength, chain_secret1, clength, k2, + k2length, MA, alength, MB, blength, (uint8_t *)INFO_TEST_VECTOR, + (uint32_t)strlen(INFO_TEST_VECTOR), label, llengthA)) { + return FAILURE; + } + printf("LA2 = %s\n", strLA2[r]); + print_array("PA2 = ", PA_PQ, PA_PQ_length); + printf("LB2 = %s\n", strLB2[r]); + print_array("PB2 = ", CTB_PQ, CTB_PQ_length); + print_array("previous_chain_secret = ", chain_secret1, clength); + print_array("k2 = ", k2, k2length); + printf("info2 = \"%s\"\n", INFO_TEST_VECTOR); + printf("label2 = LA2 ^ LB2\n"); + printf("MA2 = cid || len(LA2) || LA2 || len(PA2) || PA2\n"); + printf("MB2 = cid || len(LB2) || LB2 || len(PB2) || PB2\n"); + + print_array("chain_secret2 = ", chain_secret2, clength); + print_array("key_material2 = ", round_secret, rlength); + + kmlength = sizeof(km); + ascii_hex_strings_to_uint8(km, &kmlength, 1, strkmcas_hmac[r]); + if (memcmp(km, round_secret, key_length[r]) != 0) { + printf("Test vector %u failed\n", r); + return FAILURE; + } + } + return SUCCESS; +} +/* Testing harness for the cascade KDF (KMAC) with derandomized ECC and PQ algorithms */ +int test_hkex_cascade_kmac_derand() +{ + uint8_t PA_ECC[MAX_KEY_BYTE_LEN], PB_ECC[MAX_KEY_BYTE_LEN]; + uint8_t PA_PQ[MAX_MSG_BYTE_LEN], CTB_PQ[MAX_MSG_BYTE_LEN]; + size_t length; + size_t PA_ECC_length, PB_ECC_length, PA_PQ_length, CTB_PQ_length; + uint8_t k1[MAX_KEY_BYTE_LEN], k2[MAX_KEY_BYTE_LEN]; + uint8_t km[MAX_KEY_BYTE_LEN], round_secret[MAX_KEY_BYTE_LEN]; + uint8_t MA[MAX_MSG_BYTE_LEN], MB[MAX_MSG_BYTE_LEN]; + uint8_t label[MAX_LABEL_BYTE_LEN], labelA[MAX_LABEL_BYTE_LEN], labelB[MAX_LABEL_BYTE_LEN]; + uint8_t chain_secret0[MAX_KEY_BYTE_LEN], chain_secret1[MAX_KEY_BYTE_LEN], chain_secret2[MAX_KEY_BYTE_LEN]; + uint32_t alength, blength, llengthA, llengthB, cs0length, clength, rlength, kmlength; + uint32_t k1length, k2length, r; + current_seed_index = 0; + + for (r = 0; r < TEST_VECTOR_CNT; r++) { + printf("\nDerandomized KDF as %s, ECDH with %s, and %s \n\n", kmac[r], OBJ_nid2sn(curves[r]), kems[r]); + printf("CID %s \n", cids_cascade_kmac[r]); + + if (test_qhkex_derand_ecdh(curves[r], strSA_ECC[r], strPB_ECC[r], PA_ECC, &PA_ECC_length, PB_ECC, &PB_ECC_length, k1, &k1length)) { + return FAILURE; + } + + if (test_qhkex_derand_mlkem(kems_derand[r], PA_PQ, &PA_PQ_length, CTB_PQ, &CTB_PQ_length, k2, &k2length)) { + return FAILURE; + } + + /* MA = cid || len(LA1) || LA1 || len(PA1) || PA1 + NOTE: for test vector purposes ONLY not a suggested message format + */ + alength = sizeof(MA); + message_formatting_function(MA, &alength, 2, cids_cascade_kmac[r], strLA1[r]); + length = htonl(PA_ECC_length*2); + my_memcpy(MA + alength, &length, sizeof(uint32_t)); + alength += sizeof(uint32_t); + my_memcpy(MA + alength, PA_ECC, PA_ECC_length); + alength += PA_ECC_length; + + /* MB = cid || len(LB1) || LB1 || len(PB1) || PB1 + NOTE: for test vector purposes ONLY not a suggested message format + */ + blength = sizeof(MB); + message_formatting_function(MB, &blength, 2, cids_cascade_kmac[r], strLB1[r]); + length = htonl(PB_ECC_length*2); + my_memcpy(MB + blength, &length, sizeof(uint32_t)); + blength += sizeof(uint32_t); + my_memcpy(MB + blength, PB_ECC, PB_ECC_length); + blength += PB_ECC_length; + + /* label = LA1 ^ LB1 */ + llengthA = sizeof(labelA); + ascii_hex_strings_to_uint8(labelA, &llengthA, 1, strLA1[r]); + llengthB = sizeof(labelB); + ascii_hex_strings_to_uint8(labelB, &llengthB, 1, strLB1[r]); + if (llengthA != llengthB) { + return FAILURE; + } + for (int i = 0; i < llengthA; i++) { + label[i] = labelA[i] ^ labelB[i]; + } + + rlength = key_length[r]; + clength = KMAC128_OUT_BYTE_LENGTH; + if (memcmp(kmac[r], SN_kmac256, strlen(SN_kmac256)) == 0) { + clength = KMAC256_OUT_BYTE_LENGTH; + } + + // OpenSSL3.x does not allow KMAC secret length < 4B + cs0length = sizeof(strPSK); + ascii_hex_strings_to_uint8(chain_secret0, &cs0length, 1, strPSK); + cs0length = clength; + if (hkex_cascade_kmac(kmac[r], chain_secret1, clength, round_secret, rlength, chain_secret0, cs0length, k1, k1length, MA, alength, + MB, blength, (uint8_t *)INFO_TEST_VECTOR, + (uint32_t)strlen(INFO_TEST_VECTOR), label, llengthA)) { + return FAILURE; + } + printf("LA1 = %s\n", strLA1[r]); + print_array("PA1 = ", PA_ECC, PA_ECC_length); + printf("LB1 = %s\n", strLB1[r]); + print_array("PB1 = ", PB_ECC, PB_ECC_length); + printf("previous_chain_secret = psk = \n"); + print_array("k1 = ", k1, k1length); + printf("info1 = \"%s\"\n", INFO_TEST_VECTOR); + printf("label1 = LA1 ^ LB1\n"); + printf("MA1 = cid || len(LA1) || LA1 || len(PA1) || PA1\n"); + printf("MB1 = cid || len(LB1) || LB1 || len(PB1) || PB1\n"); + + print_array("chain_secret1 = ", chain_secret1, clength); + print_array("key_material1 = ", round_secret, rlength); + + /* MA = cid || len(LA2) || LA2 || len(PA2) || PA2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + alength = sizeof(MA); + message_formatting_function(MA, &alength, 2, cids_cascade_kmac[r], strLA2[r]); + length = htonl(PA_PQ_length*2); + my_memcpy(MA + alength, &length, sizeof(uint32_t)); + alength += sizeof(uint32_t); + my_memcpy(MA + alength, PA_PQ, PA_PQ_length); + alength += PA_PQ_length; + + /* MB = cid || len(LB2) || LB2 || len(PB2) || PB2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + blength = sizeof(MB); + message_formatting_function(MB, &blength, 2, cids_cascade_kmac[r], strLB2[r]); + length = htonl(CTB_PQ_length*2); + my_memcpy(MB + blength, &length, sizeof(uint32_t)); + blength += sizeof(uint32_t); + my_memcpy(MB + blength, CTB_PQ, CTB_PQ_length); + blength += CTB_PQ_length; + + /* label = LA2 ^ LB2 */ + llengthA = sizeof(labelA); + ascii_hex_strings_to_uint8(labelA, &llengthA, 1, strLA2[r]); + llengthB = sizeof(labelB); + ascii_hex_strings_to_uint8(labelB, &llengthB, 1, strLB2[r]); + if (llengthA != llengthB) { + return FAILURE; + } + for (int i = 0; i < llengthA; i++) { + label[i] = labelA[i] ^ labelB[i]; + } + + if (hkex_cascade_kmac(kmac[r], chain_secret2, clength, round_secret, rlength, chain_secret1, clength, k2, + k2length, MA, alength, MB, blength, (uint8_t *)INFO_TEST_VECTOR, + (uint32_t)strlen(INFO_TEST_VECTOR), label, llengthA)) { + return FAILURE; + } + + printf("LA2 = %s\n", strLA2[r]); + print_array("PA2 = ", PA_PQ, PA_PQ_length); + printf("LB2 = %s\n", strLB2[r]); + print_array("PB2 = ", CTB_PQ, CTB_PQ_length); + print_array("previous_chain_secret = ", chain_secret1, clength); + print_array("k2 = ", k2, k2length); + printf("info2 = \"%s\"\n", INFO_TEST_VECTOR); + printf("label2 = LA2 ^ LB2\n"); + printf("MA2 = cid || len(LA2) || LA2 || len(PA2) || PA2\n"); + printf("MB2 = cid || len(LB2) || LB2 || len(PB2) || PB2\n"); + + print_array("chain_secret2 = ", chain_secret2, clength); + print_array("key_material2 = ", round_secret, rlength); + + kmlength = sizeof(km); + ascii_hex_strings_to_uint8(km, &kmlength, 1, strkmcas_kmac[r]); + if (memcmp(km, round_secret, key_length[r]) != 0) { + printf("Test vector %u failed\n", r); + return FAILURE; + } + } + return SUCCESS; +} + +int main(void) +{ + if (test_hkex_concatenate_hkdf()) { + return FAILURE; + } + if (test_hkex_concatenate_hmac()) { + return FAILURE; + } + if (test_hkex_concatenate_kmac()) { + return FAILURE; + } + if (test_hkex_cascade_hkdf()) { + return FAILURE; + } + if (test_hkex_cascade_hmac()) { + return FAILURE; + } + if (test_hkex_cascade_kmac()) { + return FAILURE; + } + + // Derandomized CatKDF + if (test_hkex_concatenate_hkdf_derand()) { + return FAILURE; + } + if (test_hkex_concatenate_hmac_derand()) { + return FAILURE; + } + if (test_hkex_concatenate_kmac_derand()) { + return FAILURE; + } + + // Derandomized CasKDF + if (test_hkex_cascade_hkdf_derand()) { + return FAILURE; + } + if (test_hkex_cascade_hmac_derand()) { + return FAILURE; + } + if (test_hkex_cascade_kmac_derand()) { + return FAILURE; + } + printf("All tests passed\n"); return SUCCESS; } diff --git a/qshkex.c b/qshkex.c index 4604399..90f1794 100644 --- a/qshkex.c +++ b/qshkex.c @@ -18,7 +18,7 @@ #include /* Memory helper functions to handle null values */ -static inline void *my_memcpy(void *dst, const void *src, size_t byte_len) +void *my_memcpy(void *dst, const void *src, size_t byte_len) { if (src == NULL || dst == NULL) { return dst; diff --git a/qshkex.h b/qshkex.h index 04651ff..cd6cc94 100644 --- a/qshkex.h +++ b/qshkex.h @@ -36,6 +36,7 @@ void print_array(const char *label, const uint8_t *array, const uint32_t alength); void ascii_hex_strings_to_uint8(uint8_t *array, uint32_t *alength, const uint32_t scount, ...); +void *my_memcpy(void *dst, const void *src, size_t byte_len); int hkex_concat_hkdf(const EVP_MD *md_type, uint8_t *key_material, const uint32_t klength, const uint8_t *psk, const uint32_t plength, const uint8_t *k1, const uint32_t k1length, const uint8_t *k2, -- GitLab From 026e1ed67c7feb01b0f0262f999c6d5e6e821002 Mon Sep 17 00:00:00 2001 From: manastasova Date: Wed, 21 May 2025 16:53:40 -0700 Subject: [PATCH 4/6] Add all tests for randomized qhkex --- crypto.c | 212 ++++++++++++++++ crypto.h | 4 + main.c | 736 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 952 insertions(+) diff --git a/crypto.c b/crypto.c index f89f587..6708ae3 100644 --- a/crypto.c +++ b/crypto.c @@ -207,4 +207,216 @@ int test_qhkex_derand_mlkem(const char * alg_name, uint8_t *pubA, size_t *PA2len OQS_KEM_free(kem); } return rval; +} + +int test_qhkex_rand_ecdh(int curve, uint8_t *pubA, size_t *PA1length, uint8_t *pubB, size_t *PB1length, uint8_t *ss, uint32_t *ss_len) +{ + int rval = FAILURE; + EVP_PKEY_CTX *ctxA = NULL, *ctxB = NULL; + EVP_PKEY *pkeyA = NULL, *pkeyB = NULL; + uint8_t ssB[MAX_KEY_BYTE_LEN]; + size_t secret_lenA = 0, secret_lenB = 0; + size_t pubA_len = 0, pubB_len = 0; + + do { + // Create entity A keys + if (curve == EVP_PKEY_X25519 || curve == EVP_PKEY_X448) { + if (!(ctxA = EVP_PKEY_CTX_new_id(curve, NULL))) { + break; + } + } else { + if (!(ctxA = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL))) { + break; + } + } + if (EVP_PKEY_keygen_init(ctxA) <= 0) { + break; + } + if (curve != EVP_PKEY_X25519 || curve != EVP_PKEY_X448) { + if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctxA, curve) <= 0) { + break; + } + } + if (EVP_PKEY_keygen(ctxA, &pkeyA) <= 0) { + break; + } + if (curve != EVP_PKEY_X25519 || curve != EVP_PKEY_X448) { + if (EVP_PKEY_get_octet_string_param(pkeyA, "pub", pubA, MAX_KEY_BYTE_LEN, &pubA_len) <=0 ) { + break; + } + } else { + if (EVP_PKEY_get_raw_public_key(pkeyA, pubA, &pubA_len) <= 0) { + break; + } + } + *PA1length = pubA_len; + + // Create entity B keys + if (curve == EVP_PKEY_X25519 || curve == EVP_PKEY_X448) { + if (!(ctxB = EVP_PKEY_CTX_new_id(curve, NULL))) { + break; + } + } else { + if (!(ctxB = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL))) { + break; + } + } + if (EVP_PKEY_keygen_init(ctxB) <= 0) { + break; + } + if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctxB, curve) <= 0) { + break; + } + if (EVP_PKEY_keygen(ctxB, &pkeyB) <= 0) { + break; + } + if (curve != EVP_PKEY_X25519 || curve != EVP_PKEY_X448) { + if (EVP_PKEY_get_octet_string_param(pkeyB, "pub", pubB, MAX_KEY_BYTE_LEN, &pubB_len) <= 0) { + break; + } + } else { + if (EVP_PKEY_get_raw_public_key(pkeyB, pubB, &pubB_len) <= 0) { + break; + } + } + *PB1length = pubB_len; + + // Derive entity A shared secret + ctxA = EVP_PKEY_CTX_new(pkeyA, NULL); + if (!ctxA) { + break; + } + if (EVP_PKEY_derive_init(ctxA) <= 0) { + break; + } + if (EVP_PKEY_derive_set_peer(ctxA, pkeyB) <= 0) { + break; + } + if (EVP_PKEY_derive(ctxA, NULL, &secret_lenA) <= 0) { + break; + } + if (EVP_PKEY_derive(ctxA, ss, &secret_lenA) <= 0) { + break; + } + + // Derive entity B shared secret + ctxB = EVP_PKEY_CTX_new(pkeyB, NULL); + if (!ctxB) { + break; + } + if (EVP_PKEY_derive_init(ctxB) <= 0) { + break; + } + if (EVP_PKEY_derive_set_peer(ctxB, pkeyA) <= 0) { + break; + } + if (EVP_PKEY_derive(ctxB, NULL, &secret_lenB) <= 0) { + break; + } + if (EVP_PKEY_derive(ctxB, ssB, &secret_lenB) <= 0) { + break; + } + // Check if entities shared secrets match + if (memcmp(ss, ssB, secret_lenB) != 0 || (secret_lenA != secret_lenB)) { + break; + } + *ss_len = secret_lenA; + rval = SUCCESS; + } while (0); + if (ctxA) { + EVP_PKEY_CTX_free(ctxA); + } + if (ctxB) { + EVP_PKEY_CTX_free(ctxB); + } + if (pkeyA) { + EVP_PKEY_free(pkeyA); + } + if (pkeyB) { + EVP_PKEY_free(pkeyB); + } + return rval; +} + +int test_qhkex_rand_mlkem(const char * kem, uint8_t *pubA, size_t *PA2length, uint8_t *ctB, size_t *CTB2length, uint8_t *ss, uint32_t *ss_len) +{ + int rval = FAILURE; + size_t pubA_len = OQS_KEM_ml_kem_1024_length_public_key; + size_t ss_out_len = OQS_KEM_ml_kem_1024_length_shared_secret; + size_t ciphertext_len = OQS_KEM_ml_kem_1024_length_ciphertext; + uint8_t shared_secretB[OQS_KEM_ml_kem_1024_length_shared_secret]; + EVP_PKEY_CTX *pkey_ctx = NULL, *encaps_ctx = NULL, *decaps_ctx = NULL; + EVP_PKEY *keypair = NULL; + OSSL_PROVIDER *oqs_provider = NULL; + OSSL_LIB_CTX *libctx = NULL; + + do { + if (!(libctx = OSSL_LIB_CTX_new())) { + break; + } + if (!(oqs_provider = OSSL_PROVIDER_load(libctx, "oqsprovider"))) { + break; + } + if (!(pkey_ctx = EVP_PKEY_CTX_new_from_name(libctx, kem, NULL))) { + break; + } + if (EVP_PKEY_keygen_init(pkey_ctx) <= 0) { + break; + } + if (EVP_PKEY_keygen(pkey_ctx, &keypair) <= 0) { + break; + } + if (EVP_PKEY_get_octet_string_param(keypair, "pub", pubA, OQS_KEM_ml_kem_1024_length_public_key, &pubA_len) <= 0) { + break; + } + *PA2length = pubA_len; + + if (!(encaps_ctx = EVP_PKEY_CTX_new(keypair, NULL))) { + break; + } + if (EVP_PKEY_encapsulate_init(encaps_ctx, NULL) <= 0) { + break; + } + if (EVP_PKEY_encapsulate(encaps_ctx, NULL, &ciphertext_len, NULL, &ss_out_len) <= 0) { + break; + } + *CTB2length = ciphertext_len; + + if (EVP_PKEY_encapsulate(encaps_ctx, ctB, &ciphertext_len, ss, &ss_out_len) <= 0) { + break; + } + if (!(decaps_ctx = EVP_PKEY_CTX_new(keypair, NULL))) { + break; + } + if (EVP_PKEY_decapsulate_init(decaps_ctx, NULL) <= 0) { + break; + } + if (EVP_PKEY_decapsulate(decaps_ctx, shared_secretB, &ss_out_len, ctB, ciphertext_len) <= 0) { + break; + } + if (memcmp(ss, shared_secretB, ss_out_len) != 0) { + break; + } + *ss_len = ss_out_len; + rval = SUCCESS; + } while (0); + if (pkey_ctx) { + EVP_PKEY_CTX_free(pkey_ctx); + } + if (encaps_ctx) { + EVP_PKEY_CTX_free(encaps_ctx); + } + if (decaps_ctx) { + EVP_PKEY_CTX_free(decaps_ctx); + } + if (keypair) { + EVP_PKEY_free(keypair); + } + if (oqs_provider) { + OSSL_PROVIDER_unload(oqs_provider); + } + if (libctx) { + OSSL_LIB_CTX_free(libctx); + } + return rval; } \ No newline at end of file diff --git a/crypto.h b/crypto.h index b2c6938..5941d91 100644 --- a/crypto.h +++ b/crypto.h @@ -32,4 +32,8 @@ int test_qhkex_derand_ecdh(const int curve, const char *priv_dataA, const char * uint8_t *ss, uint32_t *ss_len); int test_qhkex_derand_mlkem(const char * alg_name, uint8_t *pubA, size_t *PA2length, uint8_t *ctB, size_t *CTB2length, uint8_t *ss, uint32_t *ss_len); +int test_qhkex_rand_ecdh(int curve, uint8_t *pubA, size_t *PA1length, + uint8_t *pubB, size_t *PB1length, uint8_t *ss, uint32_t *ss_len); +int test_qhkex_rand_mlkem(const char * kem, uint8_t *pubA, size_t *PA2length, + uint8_t *ctB, size_t *CTB2length, uint8_t *ss, uint32_t *ss_len); #endif /*_QS_H_CRYPTO_KEX_H_*/ diff --git a/main.c b/main.c index da8fbc3..e2ef4ce 100644 --- a/main.c +++ b/main.c @@ -2778,6 +2778,720 @@ int test_hkex_cascade_kmac_derand() return SUCCESS; } +/* Testing harness for concatenation KDF (HKDF) with randomized ECC and PQ algorithms */ +int test_hkex_concatenate_hkdf_rand() +{ + uint8_t PA_ECC[MAX_KEY_BYTE_LEN], PB_ECC[MAX_KEY_BYTE_LEN]; + uint8_t PA_PQ[MAX_MSG_BYTE_LEN], CTB_PQ[MAX_MSG_BYTE_LEN]; + size_t length; + size_t PA_ECC_length, PB_ECC_length, PA_PQ_length, CTB_PQ_length; + uint8_t k1[MAX_KEY_BYTE_LEN], k2[MAX_KEY_BYTE_LEN]; + uint8_t key_material[MAX_KEY_BYTE_LEN]; + uint8_t MA[MAX_MSG_BYTE_LEN], MB[MAX_MSG_BYTE_LEN]; + uint8_t label[MAX_LABEL_BYTE_LEN], labelA[MAX_LABEL_BYTE_LEN], labelB[MAX_LABEL_BYTE_LEN]; + uint32_t alength, blength, llengthA, llengthB, klength, k1length, k2length, r; + const EVP_MD *md_type; + + for (r = 0; r < TEST_VECTOR_CNT; r++) { + md_type = (*evp_hash[r])(); + + printf("\nRandomized CatKDF as HKDF/HMAC with %s, ECDH with %s, and %s \n\n", EVP_MD_name(md_type), OBJ_nid2sn(curves[r]), kems[r]); + printf("CID %s \n", cids_concatenate_hkdf[r]); + + if (test_qhkex_rand_ecdh(curves[r], PA_ECC, &PA_ECC_length, PB_ECC, &PB_ECC_length, k1, &k1length)) { + return FAILURE; + } + + if (test_qhkex_rand_mlkem(kems[r], PA_PQ, &PA_PQ_length, CTB_PQ, &CTB_PQ_length, k2, &k2length)) { + return FAILURE; + } + + /* MA = cid || len(LA1) || LA1 || len(PA1) || PA1 || len(PA2) || PA2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + alength = sizeof(MA); + message_formatting_function(MA, &alength, 2, cids_concatenate_hkdf[r], strLA1[r]); + length = htonl(PA_ECC_length*2); + my_memcpy(MA + alength, &length, sizeof(uint32_t)); + alength += sizeof(uint32_t); + my_memcpy(MA + alength, PA_ECC, PA_ECC_length); + alength += PA_ECC_length; + length = htonl(PA_PQ_length*2); + my_memcpy(MA + alength, &length, sizeof(uint32_t)); + alength += sizeof(uint32_t); + my_memcpy(MA + alength, PA_PQ, PA_PQ_length); + alength += PA_PQ_length; + + /* MB = cid || len(LB1) || LB1 || len(PB1) || PB1 || len(PB2) || PB2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + blength = sizeof(MB); + message_formatting_function(MB, &blength, 2, cids_concatenate_hkdf[r], strLB1[r]); + length = htonl(PB_ECC_length*2); + my_memcpy(MB + blength, &length, sizeof(uint32_t)); + blength += sizeof(uint32_t); + my_memcpy(MB + blength, PB_ECC, PB_ECC_length); + blength += PB_ECC_length; + length = htonl(CTB_PQ_length*2); + my_memcpy(MB + blength, &length, sizeof(uint32_t)); + blength += sizeof(uint32_t); + my_memcpy(MB + blength, CTB_PQ, CTB_PQ_length); + blength += CTB_PQ_length; + + /* label = LA ^ LB */ + llengthA = sizeof(labelA); + ascii_hex_strings_to_uint8(labelA, &llengthA, 1, strLA1[r]); + llengthB = sizeof(labelB); + ascii_hex_strings_to_uint8(labelB, &llengthB, 1, strLB1[r]); + if (llengthA != llengthB) { + return FAILURE; + } + for (int i = 0; i < llengthA; i++) { + label[i] = labelA[i] ^ labelB[i]; + } + + klength = key_length[r]; + if (hkex_concat_hkdf(md_type, key_material, klength, NULL, 0, k1, k1length, k2, k2length, MA, alength, MB, + blength, (uint8_t *)INFO_TEST_VECTOR, + (uint32_t)strlen(INFO_TEST_VECTOR), label, llengthA)) { + return FAILURE; + } + printf("LA = %s\n", strLA1[r]); + print_array("PA1 = ", PA_ECC , PA_ECC_length); + print_array("PA2 = ", PA_PQ, PA_PQ_length); + printf("LB = %s\n", strLB1[r]); + print_array("PB1 = ", PB_ECC, PB_ECC_length); + print_array("PB2 = ", CTB_PQ, CTB_PQ_length); + print_array("k1 = ", k1, k1length); + print_array("k2 = ", k2, k2length); + printf("info = \"%s\"\n", INFO_TEST_VECTOR); + print_array("label = LA ^ LB = ", label, llengthA); + printf("MA = cid || len(LA)|| LA || len(PA1) || PA1 || len(PA2) || PA2\n"); + printf("MB = cid || len(LB)|| LB || len(PB1) || PB1 || len(PB2) || PB2\n\n"); + + print_array("key material = ", key_material, klength); + } + return SUCCESS; +} +/* Testing harness for concatenation KDF (HMAC) with randomized ECC and PQ algorithms */ +int test_hkex_concatenate_hmac_rand() +{ + uint8_t PA_ECC[MAX_KEY_BYTE_LEN], PB_ECC[MAX_KEY_BYTE_LEN]; + uint8_t PA_PQ[MAX_MSG_BYTE_LEN], CTB_PQ[MAX_MSG_BYTE_LEN]; + size_t length; + size_t PA_ECC_length, PB_ECC_length, PA_PQ_length, CTB_PQ_length; + uint8_t k1[MAX_KEY_BYTE_LEN], k2[MAX_KEY_BYTE_LEN]; + uint8_t key_material[MAX_KEY_BYTE_LEN]; + uint8_t MA[MAX_MSG_BYTE_LEN], MB[MAX_MSG_BYTE_LEN]; + uint8_t label[MAX_LABEL_BYTE_LEN], labelA[MAX_LABEL_BYTE_LEN], labelB[MAX_LABEL_BYTE_LEN]; + uint32_t alength, blength, llengthA, llengthB, klength, k1length; + uint32_t k2length, r; + const EVP_MD *md_type; + + for (r = 0; r < TEST_VECTOR_CNT; r++) { + md_type = (*evp_hash[r])(); + + printf("\nRandomized CatKDF as HMAC with %s, ECDH with %s, and %s \n\n", EVP_MD_name(md_type), OBJ_nid2sn(curves[r]), kems[r]); + printf("CID %s \n", cids_concatenate_hmac[r]); + + if (test_qhkex_rand_ecdh(curves[r], PA_ECC, &PA_ECC_length, PB_ECC, &PB_ECC_length, k1, &k1length)) { + return FAILURE; + } + + if (test_qhkex_rand_mlkem(kems[r], PA_PQ, &PA_PQ_length, CTB_PQ, &CTB_PQ_length, k2, &k2length)) { + return FAILURE; + } + + /* MA = cid || len(LA1) || LA1 || len(PA1) || PA1 || len(PA2) || PA2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + alength = sizeof(MA); + message_formatting_function(MA, &alength, 2, cids_concatenate_hmac[r], strLA1[r]); + length = htonl(PA_ECC_length*2); + my_memcpy(MA + alength, &length, sizeof(uint32_t)); + alength += sizeof(uint32_t); + my_memcpy(MA + alength, PA_ECC, PA_ECC_length); + alength += PA_ECC_length; + length = htonl(PA_PQ_length*2); + my_memcpy(MA + alength, &length, sizeof(uint32_t)); + alength += sizeof(uint32_t); + my_memcpy(MA + alength, PA_PQ, PA_PQ_length); + alength += PA_PQ_length; + + /* MA = cid || len(LB1) || LB1 || len(PB1) || PB1 || len(PB2) || PB2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + blength = sizeof(MB); + message_formatting_function(MB, &blength, 2, cids_concatenate_hmac[r], strLB1[r]); + length = htonl(PB_ECC_length*2); + my_memcpy(MB + blength, &length, sizeof(uint32_t)); + blength += sizeof(uint32_t); + my_memcpy(MB + blength, PB_ECC, PB_ECC_length); + blength += PB_ECC_length; + length = htonl(CTB_PQ_length*2); + my_memcpy(MB + blength, &length, sizeof(uint32_t)); + blength += sizeof(uint32_t); + my_memcpy(MB + blength, CTB_PQ, CTB_PQ_length); + blength += CTB_PQ_length; + + /* label = LA ^ LB */ + llengthA = sizeof(labelA); + ascii_hex_strings_to_uint8(labelA, &llengthA, 1, strLA1[r]); + llengthB = sizeof(labelB); + ascii_hex_strings_to_uint8(labelB, &llengthB, 1, strLB1[r]); + if (llengthA != llengthB) { + return FAILURE; + } + for (int i = 0; i < llengthA; i++) { + label[i] = labelA[i] ^ labelB[i]; + } + + klength = key_length[r]; + if (hkex_concat_hmac(md_type, key_material, klength, NULL, 0, k1, k1length, k2, k2length, MA, alength, MB, + blength, (uint8_t *)INFO_TEST_VECTOR, + (uint32_t)strlen(INFO_TEST_VECTOR), label, llengthA)) { + return FAILURE; + } + printf("LA = %s\n", strLA1[r]); + print_array("PA1 = ", PA_ECC , PA_ECC_length); + print_array("PA2 = ", PA_PQ, PA_PQ_length); + printf("LB = %s\n", strLB1[r]); + print_array("PB1 = ", PB_ECC, PB_ECC_length); + print_array("PB2 = ", CTB_PQ, CTB_PQ_length); + print_array("k1 = ", k1, k1length); + print_array("k2 = ", k2, k2length); + printf("info = \"%s\"\n", INFO_TEST_VECTOR); + print_array("label = LA ^ LB = ", label, llengthA); + printf("MA = cid || len(LA)|| LA || len(PA1) || PA1 || len(PA2) || PA2\n"); + printf("MB = cid || len(LB)|| LB || len(PB1) || PB1 || len(PB2) || PB2\n\n"); + + print_array("key material = ", key_material, klength); + } + return SUCCESS; +} +/* Testing harness for concatenation KDF (KMAC) with randomized ECC and PQ algorithms */ +int test_hkex_concatenate_kmac_rand() +{ + uint8_t PA_ECC[MAX_KEY_BYTE_LEN], PB_ECC[MAX_KEY_BYTE_LEN]; + uint8_t PA_PQ[MAX_MSG_BYTE_LEN], CTB_PQ[MAX_MSG_BYTE_LEN]; + size_t length; + size_t PA_ECC_length, PB_ECC_length, PA_PQ_length, CTB_PQ_length; + uint8_t k1[MAX_KEY_BYTE_LEN], k2[MAX_KEY_BYTE_LEN]; + uint8_t key_material[MAX_KEY_BYTE_LEN]; + uint8_t MA[MAX_MSG_BYTE_LEN], MB[MAX_MSG_BYTE_LEN]; + uint8_t label[MAX_LABEL_BYTE_LEN], labelA[MAX_LABEL_BYTE_LEN], labelB[MAX_LABEL_BYTE_LEN]; + uint32_t alength, blength, llengthA, llengthB, klength, k1length; + uint32_t k2length, r; + + for (r = 0; r < TEST_VECTOR_CNT; r++) { + printf("\nRandomized CatKDF as %s, ECDH with %s, and %s \n\n", kmac[r], OBJ_nid2sn(curves[r]), kems[r]); + printf("CID %s \n", cids_concatenate_kmac[r]); + + if (test_qhkex_rand_ecdh(curves[r], PA_ECC, &PA_ECC_length, PB_ECC, &PB_ECC_length, k1, &k1length)) { + return FAILURE; + } + if (test_qhkex_rand_mlkem(kems[r], PA_PQ, &PA_PQ_length, CTB_PQ, &CTB_PQ_length, k2, &k2length)) { + return FAILURE; + } + + /* MA = cid || len(LA1) || LA1 || len(PA1) || PA1 || len(PA2) || PA2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + alength = sizeof(MA); + message_formatting_function(MA, &alength, 2, cids_concatenate_kmac[r], strLA1[r]); + length = htonl(PA_ECC_length*2); + my_memcpy(MA + alength, &length, sizeof(uint32_t)); + alength += sizeof(uint32_t); + my_memcpy(MA + alength, PA_ECC, PA_ECC_length); + alength += PA_ECC_length; + length = htonl(PA_PQ_length*2); + my_memcpy(MA + alength, &length, sizeof(uint32_t)); + alength += sizeof(uint32_t); + my_memcpy(MA + alength, PA_PQ, PA_PQ_length); + alength += PA_PQ_length; + + /* MA = cid || len(LB1) || LB1 || len(PB1) || PB1 || len(PB2) || PB2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + blength = sizeof(MB); + message_formatting_function(MB, &blength, 2, cids_concatenate_kmac[r], strLB1[r]); + length = htonl(PB_ECC_length*2); + my_memcpy(MB + blength, &length, sizeof(uint32_t)); + blength += sizeof(uint32_t); + my_memcpy(MB + blength, PB_ECC, PB_ECC_length); + blength += PB_ECC_length; + length = htonl(CTB_PQ_length*2); + my_memcpy(MB + blength, &length, sizeof(uint32_t)); + blength += sizeof(uint32_t); + my_memcpy(MB + blength, CTB_PQ, CTB_PQ_length); + blength += CTB_PQ_length; + + /* label = LA ^ LB */ + llengthA = sizeof(labelA); + ascii_hex_strings_to_uint8(labelA, &llengthA, 1, strLA1[r]); + llengthB = sizeof(labelB); + ascii_hex_strings_to_uint8(labelB, &llengthB, 1, strLB1[r]); + if (llengthA != llengthB) { + return FAILURE; + } + for (int i = 0; i < llengthA; i++) { + label[i] = labelA[i] ^ labelB[i]; + } + + klength = key_length[r]; + if (hkex_concat_kmac(kmac[r], key_material, klength, NULL, 0, k1, k1length, k2, k2length, MA, alength, MB, + blength, (uint8_t *)INFO_TEST_VECTOR, + (uint32_t)strlen(INFO_TEST_VECTOR), label, llengthA)) { + return FAILURE; + } + printf("LA = %s\n", strLA1[r]); + print_array("PA1 = ", PA_ECC , PA_ECC_length); + print_array("PA2 = ", PA_PQ, PA_PQ_length); + printf("LB = %s\n", strLB1[r]); + print_array("PB1 = ", PB_ECC, PB_ECC_length); + print_array("PB2 = ", CTB_PQ, CTB_PQ_length); + print_array("k1 = ", k1, k1length); + print_array("k2 = ", k2, k2length); + printf("info = \"%s\"\n", INFO_TEST_VECTOR); + print_array("label = LA ^ LB = ", label, llengthA); + printf("MA = cid || len(LA)|| LA || len(PA1) || PA1 || len(PA2) || PA2\n"); + printf("MB = cid || len(LB)|| LB || len(PB1) || PB1 || len(PB2) || PB2\n\n"); + + print_array("key material = ", key_material, klength); + } + return SUCCESS; +} + +/* Testing harness for the cascade KDF (HKDF) with randomized ECC and PQ algorithms */ +int test_hkex_cascade_hkdf_rand() +{ + uint8_t PA_ECC[MAX_KEY_BYTE_LEN], PB_ECC[MAX_KEY_BYTE_LEN]; + uint8_t PA_PQ[MAX_MSG_BYTE_LEN], CTB_PQ[MAX_MSG_BYTE_LEN]; + size_t length; + size_t PA_ECC_length, PB_ECC_length, PA_PQ_length, CTB_PQ_length; + uint8_t k1[MAX_KEY_BYTE_LEN], k2[MAX_KEY_BYTE_LEN]; + uint8_t round_secret[MAX_KEY_BYTE_LEN]; + uint8_t MA[MAX_MSG_BYTE_LEN], MB[MAX_MSG_BYTE_LEN]; + uint8_t label[MAX_LABEL_BYTE_LEN], labelA[MAX_LABEL_BYTE_LEN], labelB[MAX_LABEL_BYTE_LEN]; + uint8_t chain_secret1[MAX_KEY_BYTE_LEN], chain_secret2[MAX_KEY_BYTE_LEN]; + uint32_t alength, blength, llengthA, llengthB, clength, rlength; + uint32_t k1length, k2length, r; + const EVP_MD *md_type; + + for (r = 0; r < TEST_VECTOR_CNT; r++) { + md_type = (*evp_hash[r])(); + + printf("\nRandomized CasKDF as HKDF with %s, ECDH with %s, and %s \n\n", EVP_MD_name(md_type), OBJ_nid2sn(curves[r]), kems[r]); + printf("CID %s \n", cids_cascade_hkdf[r]); + + if (test_qhkex_rand_ecdh(curves[r], PA_ECC, &PA_ECC_length, PB_ECC, &PB_ECC_length, k1, &k1length)) { + return FAILURE; + } + + if (test_qhkex_rand_mlkem(kems[r], PA_PQ, &PA_PQ_length, CTB_PQ, &CTB_PQ_length, k2, &k2length)) { + return FAILURE; + } + + /* MA = cid || len(LA1) || LA1 || len(PA1) || PA1 + NOTE: for test vector purposes ONLY not a suggested message format + */ + alength = sizeof(MA); + message_formatting_function(MA, &alength, 2, cids_cascade_hkdf[r], strLA1[r]); + length = htonl(PA_ECC_length*2); + my_memcpy(MA + alength, &length, sizeof(uint32_t)); + alength += sizeof(uint32_t); + my_memcpy(MA + alength, PA_ECC, PA_ECC_length); + alength += PA_ECC_length; + + /* MB = cid || len(LB1) || LB1 || len(PB1) || PB1 + NOTE: for test vector purposes ONLY not a suggested message format + */ + blength = sizeof(MB); + message_formatting_function(MB, &blength, 2, cids_cascade_hkdf[r], strLB1[r]); + length = htonl(PB_ECC_length*2); + my_memcpy(MB + blength, &length, sizeof(uint32_t)); + blength += sizeof(uint32_t); + my_memcpy(MB + blength, PB_ECC, PB_ECC_length); + blength += PB_ECC_length; + + /* label = LA1 ^ LB1 */ + llengthA = sizeof(labelA); + ascii_hex_strings_to_uint8(labelA, &llengthA, 1, strLA1[r]); + llengthB = sizeof(labelB); + ascii_hex_strings_to_uint8(labelB, &llengthB, 1, strLB1[r]); + if (llengthA != llengthB) { + return FAILURE; + } + for (int i = 0; i < llengthA; i++) { + label[i] = labelA[i] ^ labelB[i]; + } + + rlength = key_length[r]; + clength = EVP_MD_size(md_type); + const uint8_t chain_secret0[] = {}; // OpenSSL3.x does not allow NULL pointer HMAC input + if (hkex_cascade_hkdf(md_type, chain_secret1, clength, round_secret, rlength, chain_secret0, 0, k1, k1length, MA, alength, + MB, blength, (uint8_t *)INFO_TEST_VECTOR, + (uint32_t)strlen(INFO_TEST_VECTOR), label, llengthA)) { + return FAILURE; + } + + printf("LA1 = %s\n", strLA1[r]); + print_array("PA1 = ", PA_ECC, PA_ECC_length); + printf("LB1 = %s\n", strLB1[r]); + print_array("PB1 = ", PB_ECC, PB_ECC_length); + printf("previous_chain_secret = psk = \n"); + print_array("k1 = ", k1, k1length); + printf("info1 = \"%s\"\n", INFO_TEST_VECTOR); + printf("label1 = LA1 ^ LB1\n"); + printf("MA1 = cid || len(LA1) || LA1 || len(PA1) || PA1\n"); + printf("MB1 = cid || len(LB1) || LB1 || len(PB1) || PB1\n"); + + print_array("chain_secret1 = ", chain_secret1, clength); + print_array("key_material1 = ", round_secret, rlength); + + /* MA = cid || len(LA2) || LA2 || len(PA2) || PA2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + alength = sizeof(MA); + message_formatting_function(MA, &alength, 2, cids_cascade_hkdf[r], strLA2[r]); + length = htonl(PA_PQ_length*2); + my_memcpy(MA + alength, &length, sizeof(uint32_t)); + alength += sizeof(uint32_t); + my_memcpy(MA + alength, PA_PQ, PA_PQ_length); + alength += PA_PQ_length; + + /* MB = cid || len(LB2) || LB2 || len(PB2) || PB2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + blength = sizeof(MB); + message_formatting_function(MB, &blength, 2, cids_cascade_hkdf[r], strLB2[r]); + length = htonl(CTB_PQ_length*2); + my_memcpy(MB + blength, &length, sizeof(uint32_t)); + blength += sizeof(uint32_t); + my_memcpy(MB + blength, CTB_PQ, CTB_PQ_length); + blength += CTB_PQ_length; + + /* label = LA2 ^ LB2 */ + llengthA = sizeof(labelA); + ascii_hex_strings_to_uint8(labelA, &llengthA, 1, strLA2[r]); + llengthB = sizeof(labelB); + ascii_hex_strings_to_uint8(labelB, &llengthB, 1, strLB2[r]); + if (llengthA != llengthB) { + return FAILURE; + } + for (int i = 0; i < llengthA; i++) { + label[i] = labelA[i] ^ labelB[i]; + } + + if (hkex_cascade_hkdf(md_type, chain_secret2, clength, round_secret, rlength, chain_secret1, clength, k2, + k2length, MA, alength, MB, blength, (uint8_t *)INFO_TEST_VECTOR, + (uint32_t)strlen(INFO_TEST_VECTOR), label, llengthA)) { + return FAILURE; + } + printf("LA2 = %s\n", strLA2[r]); + print_array("PA2 = ", PA_PQ, PA_PQ_length); + printf("LB2 = %s\n", strLB2[r]); + print_array("PB2 = ", CTB_PQ, CTB_PQ_length); + print_array("previous_chain_secret = ", chain_secret1, clength); + print_array("k2 = ", k2, k2length); + printf("info2 = \"%s\"\n", INFO_TEST_VECTOR); + printf("label2 = LA2 ^ LB2\n"); + printf("MA2 = cid || len(LA2) || LA2 || len(PA2) || PA2\n"); + printf("MB2 = cid || len(LB2) || LB2 || len(PB2) || PB2\n\n"); + + print_array("chain_secret2 = ", chain_secret2, clength); + print_array("key_material2 = ", round_secret, rlength); + } + return SUCCESS; +} +/* Testing harness for the cascade KDF (HMAC) with randomized ECC and PQ algorithms */ +int test_hkex_cascade_hmac_rand() +{ + uint8_t PA_ECC[MAX_KEY_BYTE_LEN], PB_ECC[MAX_KEY_BYTE_LEN]; + uint8_t PA_PQ[MAX_MSG_BYTE_LEN], CTB_PQ[MAX_MSG_BYTE_LEN]; + size_t length; + size_t PA_ECC_length, PB_ECC_length, PA_PQ_length, CTB_PQ_length; + uint8_t k1[MAX_KEY_BYTE_LEN], k2[MAX_KEY_BYTE_LEN]; + uint8_t round_secret[MAX_KEY_BYTE_LEN]; + uint8_t MA[MAX_MSG_BYTE_LEN], MB[MAX_MSG_BYTE_LEN]; + uint8_t label[MAX_LABEL_BYTE_LEN], labelA[MAX_LABEL_BYTE_LEN], labelB[MAX_LABEL_BYTE_LEN]; + uint8_t chain_secret1[MAX_KEY_BYTE_LEN], chain_secret2[MAX_KEY_BYTE_LEN]; + uint32_t alength, blength, llengthA, llengthB, clength, rlength; + uint32_t k1length, k2length, r; + const EVP_MD *md_type; + + for (r = 0; r < TEST_VECTOR_CNT; r++) { + md_type = (*evp_hash[r])(); + + printf("\nRandomized CasKDF as HMAC/HMAC with %s, ECDH with %s, and %s \n\n", EVP_MD_name(md_type), OBJ_nid2sn(curves[r]), kems[r]); + printf("CID %s \n", cids_cascade_hmac[r]); + + if (test_qhkex_rand_ecdh(curves[r], PA_ECC, &PA_ECC_length, PB_ECC, &PB_ECC_length, k1, &k1length)) { + return FAILURE; + } + + if (test_qhkex_rand_mlkem(kems[r], PA_PQ, &PA_PQ_length, CTB_PQ, &CTB_PQ_length, k2, &k2length)) { + return FAILURE; + } + + /* MA = cid || len(LA1) || LA1 || len(PA1) || PA1 + NOTE: for test vector purposes ONLY not a suggested message format + */ + alength = sizeof(MA); + message_formatting_function(MA, &alength, 2, cids_cascade_hmac[r], strLA1[r]); + length = htonl(PA_ECC_length*2); + my_memcpy(MA + alength, &length, sizeof(uint32_t)); + alength += sizeof(uint32_t); + my_memcpy(MA + alength, PA_ECC, PA_ECC_length); + alength += PA_ECC_length; + + /* MB = cid || len(LB1) || LB1 || len(PB1) || PB1 + NOTE: for test vector purposes ONLY not a suggested message format + */ + blength = sizeof(MB); + message_formatting_function(MB, &blength, 2, cids_cascade_hmac[r], strLB1[r]); + length = htonl(PB_ECC_length*2); + my_memcpy(MB + blength, &length, sizeof(uint32_t)); + blength += sizeof(uint32_t); + my_memcpy(MB + blength, PB_ECC, PB_ECC_length); + blength += PB_ECC_length; + + /* label = LA1 ^ LB1 */ + llengthA = sizeof(labelA); + ascii_hex_strings_to_uint8(labelA, &llengthA, 1, strLA1[r]); + llengthB = sizeof(labelB); + ascii_hex_strings_to_uint8(labelB, &llengthB, 1, strLB1[r]); + if (llengthA != llengthB) { + return FAILURE; + } + for (int i = 0; i < llengthA; i++) { + label[i] = labelA[i] ^ labelB[i]; + } + + rlength = key_length[r]; + clength = EVP_MD_size(md_type); + const uint8_t chain_secret0[] = {}; // OpenSSL3.x does not allow NULL pointer HMAC input + if (hkex_cascade_hmac(md_type, chain_secret1, clength, round_secret, rlength, chain_secret0, 0, k1, k1length, MA, alength, + MB, blength, (uint8_t *)INFO_TEST_VECTOR, + (uint32_t)strlen(INFO_TEST_VECTOR), label, llengthA)) { + return FAILURE; + } + + printf("LA1 = %s\n", strLA1[r]); + print_array("PA1 = ", PA_ECC, PA_ECC_length); + printf("LB1 = %s\n", strLB1[r]); + print_array("PB1 = ", PB_ECC, PB_ECC_length); + printf("previous_chain_secret = psk = \n"); + print_array("k1 = ", k1, k1length); + printf("info1 = \"%s\"\n", INFO_TEST_VECTOR); + printf("label1 = LA1 ^ LB1\n"); + printf("MA1 = cid || len(LA1) || LA1 || len(PA1) || PA1\n"); + printf("MB1 = cid || len(LB1) || LB1 || len(PB1) || PB1\n"); + + print_array("chain_secret1 = ", chain_secret1, clength); + print_array("key_material1 = ", round_secret, rlength); + + /* MA = cid || len(LA2) || LA2 || len(PA2) || PA2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + alength = sizeof(MA); + message_formatting_function(MA, &alength, 2, cids_cascade_hmac[r], strLA2[r]); + length = htonl(PA_PQ_length*2); + my_memcpy(MA + alength, &length, sizeof(uint32_t)); + alength += sizeof(uint32_t); + my_memcpy(MA + alength, PA_PQ, PA_PQ_length); + alength += PA_PQ_length; + /* MB = cid || len(LB2) || LB2 || len(PB2) || PB2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + blength = sizeof(MB); + message_formatting_function(MB, &blength, 2, cids_cascade_hmac[r], strLB2[r]); + length = htonl(CTB_PQ_length*2); + my_memcpy(MB + blength, &length, sizeof(uint32_t)); + blength += sizeof(uint32_t); + my_memcpy(MB + blength, CTB_PQ, CTB_PQ_length); + blength += CTB_PQ_length; + + /* label = LA2 ^ LB2 */ + llengthA = sizeof(labelA); + ascii_hex_strings_to_uint8(labelA, &llengthA, 1, strLA2[r]); + llengthB = sizeof(labelB); + ascii_hex_strings_to_uint8(labelB, &llengthB, 1, strLB2[r]); + if (llengthA != llengthB) { + return FAILURE; + } + for (int i = 0; i < llengthA; i++) { + label[i] = labelA[i] ^ labelB[i]; + } + + if (hkex_cascade_hmac(md_type, chain_secret2, clength, round_secret, rlength, chain_secret1, clength, k2, + k2length, MA, alength, MB, blength, (uint8_t *)INFO_TEST_VECTOR, + (uint32_t)strlen(INFO_TEST_VECTOR), label, llengthA)) { + return FAILURE; + } + printf("LA2 = %s\n", strLA2[r]); + print_array("PA2 = ", PA_PQ, PA_PQ_length); + printf("LB2 = %s\n", strLB2[r]); + print_array("PB2 = ", CTB_PQ, CTB_PQ_length); + print_array("previous_chain_secret = ", chain_secret1, clength); + print_array("k2 = ", k2, k2length); + printf("info2 = \"%s\"\n", INFO_TEST_VECTOR); + printf("label2 = LA2 ^ LB2\n"); + printf("MA2 = cid || len(LA2) || LA2 || len(PA2) || PA2\n"); + printf("MB2 = cid || len(LB2) || LB2 || len(PB2) || PB2\n"); + + print_array("chain_secret2 = ", chain_secret2, clength); + print_array("key_material2 = ", round_secret, rlength); + } + return SUCCESS; +} +/* Testing harness for the cascade KDF (KMAC) with randomized ECC and PQ algorithms */ +int test_hkex_cascade_kmac_rand() +{ + uint8_t PA_ECC[MAX_KEY_BYTE_LEN], PB_ECC[MAX_KEY_BYTE_LEN]; + uint8_t PA_PQ[MAX_MSG_BYTE_LEN], CTB_PQ[MAX_MSG_BYTE_LEN]; + size_t length; + size_t PA_ECC_length, PB_ECC_length, PA_PQ_length, CTB_PQ_length; + uint8_t k1[MAX_KEY_BYTE_LEN], k2[MAX_KEY_BYTE_LEN]; + uint8_t round_secret[MAX_KEY_BYTE_LEN]; + uint8_t MA[MAX_MSG_BYTE_LEN], MB[MAX_MSG_BYTE_LEN]; + uint8_t label[MAX_LABEL_BYTE_LEN], labelA[MAX_LABEL_BYTE_LEN], labelB[MAX_LABEL_BYTE_LEN]; + uint8_t chain_secret0[MAX_KEY_BYTE_LEN], chain_secret1[MAX_KEY_BYTE_LEN], chain_secret2[MAX_KEY_BYTE_LEN]; + uint32_t alength, blength, llengthA, llengthB, cs0length, clength, rlength; + uint32_t k1length, k2length, r; + + for (r = 0; r < TEST_VECTOR_CNT; r++) { + printf("\nRandomized KDF as %s, ECDH with %s, and %s \n\n", kmac[r], OBJ_nid2sn(curves[r]), kems[r]); + printf("CID %s \n", cids_cascade_kmac[r]); + + if (test_qhkex_rand_ecdh(curves[r], PA_ECC, &PA_ECC_length, PB_ECC, &PB_ECC_length, k1, &k1length)) { + return FAILURE; + } + + if (test_qhkex_rand_mlkem(kems[r], PA_PQ, &PA_PQ_length, CTB_PQ, &CTB_PQ_length, k2, &k2length)) { + return FAILURE; + } + + /* MA = cid || len(LA1) || LA1 || len(PA1) || PA1 + NOTE: for test vector purposes ONLY not a suggested message format + */ + alength = sizeof(MA); + message_formatting_function(MA, &alength, 2, cids_cascade_kmac[r], strLA1[r]); + length = htonl(PA_ECC_length*2); + my_memcpy(MA + alength, &length, sizeof(uint32_t)); + alength += sizeof(uint32_t); + my_memcpy(MA + alength, PA_ECC, PA_ECC_length); + alength += PA_ECC_length; + + /* MB = cid || len(LB1) || LB1 || len(PB1) || PB1 + NOTE: for test vector purposes ONLY not a suggested message format + */ + blength = sizeof(MB); + message_formatting_function(MB, &blength, 2, cids_cascade_kmac[r], strLB1[r]); + length = htonl(PB_ECC_length*2); + my_memcpy(MB + blength, &length, sizeof(uint32_t)); + blength += sizeof(uint32_t); + my_memcpy(MB + blength, PB_ECC, PB_ECC_length); + blength += PB_ECC_length; + + /* label = LA1 ^ LB1 */ + llengthA = sizeof(labelA); + ascii_hex_strings_to_uint8(labelA, &llengthA, 1, strLA1[r]); + llengthB = sizeof(labelB); + ascii_hex_strings_to_uint8(labelB, &llengthB, 1, strLB1[r]); + if (llengthA != llengthB) { + return FAILURE; + } + for (int i = 0; i < llengthA; i++) { + label[i] = labelA[i] ^ labelB[i]; + } + + rlength = key_length[r]; + clength = KMAC128_OUT_BYTE_LENGTH; + if (memcmp(kmac[r], SN_kmac256, strlen(SN_kmac256)) == 0) { + clength = KMAC256_OUT_BYTE_LENGTH; + } + + // OpenSSL3.x does not allow KMAC secret length < 4B + cs0length = sizeof(strPSK); + ascii_hex_strings_to_uint8(chain_secret0, &cs0length, 1, strPSK); + cs0length = clength; + if (hkex_cascade_kmac(kmac[r], chain_secret1, clength, round_secret, rlength, chain_secret0, cs0length, k1, k1length, MA, alength, + MB, blength, (uint8_t *)INFO_TEST_VECTOR, + (uint32_t)strlen(INFO_TEST_VECTOR), label, llengthA)) { + return FAILURE; + } + printf("LA1 = %s\n", strLA1[r]); + print_array("PA1 = ", PA_ECC, PA_ECC_length); + printf("LB1 = %s\n", strLB1[r]); + print_array("PB1 = ", PB_ECC, PB_ECC_length); + printf("previous_chain_secret = psk = \n"); + print_array("k1 = ", k1, k1length); + printf("info1 = \"%s\"\n", INFO_TEST_VECTOR); + printf("label1 = LA1 ^ LB1\n"); + printf("MA1 = cid || len(LA1) || LA1 || len(PA1) || PA1\n"); + printf("MB1 = cid || len(LB1) || LB1 || len(PB1) || PB1\n"); + + print_array("chain_secret1 = ", chain_secret1, clength); + print_array("key_material1 = ", round_secret, rlength); + + /* MA = cid || len(LA2) || LA2 || len(PA2) || PA2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + alength = sizeof(MA); + message_formatting_function(MA, &alength, 2, cids_cascade_kmac[r], strLA2[r]); + length = htonl(PA_PQ_length*2); + my_memcpy(MA + alength, &length, sizeof(uint32_t)); + alength += sizeof(uint32_t); + my_memcpy(MA + alength, PA_PQ, PA_PQ_length); + alength += PA_PQ_length; + + /* MB = cid || len(LB2) || LB2 || len(PB2) || PB2 + NOTE: for test vector purposes ONLY not a suggested message format + */ + blength = sizeof(MB); + message_formatting_function(MB, &blength, 2, cids_cascade_kmac[r], strLB2[r]); + length = htonl(CTB_PQ_length*2); + my_memcpy(MB + blength, &length, sizeof(uint32_t)); + blength += sizeof(uint32_t); + my_memcpy(MB + blength, CTB_PQ, CTB_PQ_length); + blength += CTB_PQ_length; + + /* label = LA2 ^ LB2 */ + llengthA = sizeof(labelA); + ascii_hex_strings_to_uint8(labelA, &llengthA, 1, strLA2[r]); + llengthB = sizeof(labelB); + ascii_hex_strings_to_uint8(labelB, &llengthB, 1, strLB2[r]); + if (llengthA != llengthB) { + return FAILURE; + } + for (int i = 0; i < llengthA; i++) { + label[i] = labelA[i] ^ labelB[i]; + } + + if (hkex_cascade_kmac(kmac[r], chain_secret2, clength, round_secret, rlength, chain_secret1, clength, k2, + k2length, MA, alength, MB, blength, (uint8_t *)INFO_TEST_VECTOR, + (uint32_t)strlen(INFO_TEST_VECTOR), label, llengthA)) { + return FAILURE; + } + + printf("LA2 = %s\n", strLA2[r]); + print_array("PA2 = ", PA_PQ, PA_PQ_length); + printf("LB2 = %s\n", strLB2[r]); + print_array("PB2 = ", CTB_PQ, CTB_PQ_length); + print_array("previous_chain_secret = ", chain_secret1, clength); + print_array("k2 = ", k2, k2length); + printf("info2 = \"%s\"\n", INFO_TEST_VECTOR); + printf("label2 = LA2 ^ LB2\n"); + printf("MA2 = cid || len(LA2) || LA2 || len(PA2) || PA2\n"); + printf("MB2 = cid || len(LB2) || LB2 || len(PB2) || PB2\n"); + + print_array("chain_secret2 = ", chain_secret2, clength); + print_array("key_material2 = ", round_secret, rlength); + } + return SUCCESS; +} + int main(void) { if (test_hkex_concatenate_hkdf()) { @@ -2821,6 +3535,28 @@ int main(void) return FAILURE; } + //Randomized CatKDF + if (test_hkex_concatenate_hkdf_rand()) { + return FAILURE; + } + if (test_hkex_concatenate_hmac_rand()) { + return FAILURE; + } + if (test_hkex_concatenate_kmac_rand()) { + return FAILURE; + } + + // Randomized CasKDF + if (test_hkex_cascade_hkdf_rand()) { + return FAILURE; + } + if (test_hkex_cascade_hmac_rand()) { + return FAILURE; + } + if (test_hkex_cascade_kmac_rand()) { + return FAILURE; + } + printf("All tests passed\n"); return SUCCESS; } -- GitLab From 56c394809c776c64371dec4634e19cce1748e132 Mon Sep 17 00:00:00 2001 From: manastasova Date: Wed, 21 May 2025 16:55:44 -0700 Subject: [PATCH 5/6] Update README file --- README.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index dbcc479..20eda17 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ## TS 103 744 Quantum-safe Hybrid Key Exchanges ## - Informative reference implementation as reported in Annex D of ETSI TS 103 744, + Informative reference implementation as reported in Annex C of ETSI TS 103 744, "CYBER; Quantum-safe Hybrid Key Exchanges. The code is not intended for production use. It is intended to be a reference implementation for test. @@ -14,14 +14,23 @@ This is not intended for production use. It is intended to be a reference implementation for test vectors for the specification. + git clone ssh://git.amazon.com/pkg/Etsi-hkex-test + git checkout ### Build instructions ### -This library requires OpenSSL version 3.x.x libcrypto. +This library requires OpenSSL version 3.2.4-dev libcrypto. - gcc -Wall -o etsi-hkex-test main.c qshkex.c -lcrypto - ./etsi-hkex-test + To clone and build dependencies (openssl, liboqs, and oqs-provider), run: + make + + To build and run etsi-hkex-test: + make run + + Or: + gcc -Wall -o etsi-hkex-test main.c crypto.c qshkex.c -lcrypto -loqs + ./etsi-hkex-test ### License ### The content of this repository and the files contained are released under the BSD-3-Clause license. -See the attached LICENSE file or visit https://forge.etsi.org/legal-matters. +See the attached LICENSE file or visit https://forge.etsi.org/legal-matters. \ No newline at end of file -- GitLab From 45b4076e7f96972b6caaed2f88af7fcb055bfa49 Mon Sep 17 00:00:00 2001 From: manastasova Date: Mon, 23 Jun 2025 08:08:11 -0700 Subject: [PATCH 6/6] Comments Updates --- qshkex.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/qshkex.c b/qshkex.c index 90f1794..97b3d4f 100644 --- a/qshkex.c +++ b/qshkex.c @@ -25,7 +25,7 @@ void *my_memcpy(void *dst, const void *src, size_t byte_len) } return memcpy(dst, src, byte_len); } -/* Implements the kdf concatenate-based formatting function, see Section 7.2.2 */ +/* Implements KDF concatenate-based formatting function, see Section 7.2.2 */ /* Input: const uint8_t * arg1, arg2, arg3 */ /* Input: const uint32_t a1length, a2length, a3length */ /* Output: uint8_t *kdf_context, uint32_t *clength */ @@ -62,7 +62,7 @@ int cb_f(uint8_t *kdf_context, uint32_t *clength, const uint8_t *arg1, } while (0); return rval; } -/* Implements the kdf concatenate-and-hash-based formatting function, see Section 7.2.3 */ +/* Implements KDF concatenate-and-hash-based formatting function, see Section 7.2.3 */ /* Input: const uint8_t * arg1, arg2, arg3 */ /* Input: const uint32_t a1length, a2length, a3length */ /* Input: const EVP_MD *md_type */ @@ -121,12 +121,12 @@ int cahb_f(const EVP_MD *md_type, uint8_t *kdf_context, uint32_t *clength, const } return rval; } -/* Implements the HMAC KDF function from Section 7.4.2 */ +/* Implements HKDF KDF function from Section 7.4.2 */ /* Input: const EVP_MD *md_type */ /* Input: const uint8_t *secret, *label, *context */ /* Input: const uint32_t slength, llength, clength */ /* Output: uint8_t *key_material, uint32_t *klength */ -/* Functionality: key_material = HMAC(secret, label, context, length) */ +/* Functionality: key_material = HKDF(secret, label, context, length) */ int kdf_hkdf(const EVP_MD *md_type, uint8_t *key_material, uint32_t *klength, const uint8_t *secret, const uint32_t slength, const uint8_t *label, const uint32_t llength, const uint8_t *context, const uint32_t clength) { @@ -171,12 +171,12 @@ int kdf_hkdf(const EVP_MD *md_type, uint8_t *key_material, uint32_t *klength, co } return rval; } -/* Implements the HMAC KDF function from Section 7.4.2 */ +/* Implements HMAC KDF function from Section 7.4.3 */ /* Input: const EVP_MD *md_type */ /* Input: const uint8_t *secret, *label, *context */ /* Input: const uint32_t slength, llength, clength */ /* Output: uint8_t *key_material, uint32_t *klength */ -/* Functionality: key_material = HMAC(secret, label, context, length) */ +/* Functionality: key_material = HMAC(label, secret || context) */ int kdf_hmac(const EVP_MD *md_type, uint8_t *key_material, uint32_t *klength, const uint8_t *secret, const uint32_t slength, const uint8_t *label, const uint32_t llength, const uint8_t *context, const uint32_t clength) { @@ -220,12 +220,12 @@ int kdf_hmac(const EVP_MD *md_type, uint8_t *key_material, uint32_t *klength, co } return rval; } -/* Implements the KMAC KDF function from Section 7.4.3 */ +/* Implements KMAC KDF function from Section 7.4.4 */ /* Input: const char *kmac */ /* Input: const uint8_t *secret, *label, *context */ /* Input: const uint32_t slength, llength, clength */ /* Output: uint8_t *key_material, uint32_t *klength */ -/* Functionality: key_material = KMAC#(label, counter || secret || context, length, "KDF") */ +/* Functionality: key_material = KMAC#(label, counter || secret || context, length * 8, "KDF") */ /* Functionality: key_material = SSKDF_kmac(secret, label, context, length) */ int kdf_kmac(const char *kmac, uint8_t *key_material, uint32_t *klength, const uint8_t *secret, const uint32_t slength, const uint8_t *label, const uint32_t llength, const uint8_t *context, const uint32_t clength) @@ -268,7 +268,7 @@ int kdf_kmac(const char *kmac, uint8_t *key_material, uint32_t *klength, const u } return rval; } -/* Implements the HMAC prf function from Section 7.3.2 */ +/* Implements HMAC PRF function from Section 7.3.2 */ /* Input: const EVP_MD *md_type */ /* Input: const uint8_t *secret, *ki, *MAi, *MBi */ /* Input: const uint8_t slength, const uint32_t kilength, mailength, mbilength */ @@ -330,7 +330,7 @@ int prf_hmac(const EVP_MD *md_type, uint8_t *output, uint32_t *olength, const ui } return rval; } -/* Implements the KMAC PRF function from Section 7.3.3 */ +/* Implements KMAC PRF function from Section 7.3.3 */ /* Input: const char *kmac */ /* Input: const uint8_t *secret, *ki, *MAi, *MBi */ /* Input: const uint8_t slength, const uint32_t kilength, mailength, mbilength */ @@ -388,9 +388,9 @@ int prf_kmac(const char *kmac, uint8_t *output, uint32_t *olength, const uint8_t } return rval; } -/* Implements the function Concatenation HKDF KDF from Section 8.2 */ +/* Implements function CatKDF from Section 8.2 using HKDF KDF as described in Section 7.4.2 */ /* Input: const EVP_MD *md_type */ -/* Input: uint8_t *psk, *k1, *k2, *MA, *MB, *info, *label */ +/* Input: uint8_t *psk, *k1, *k2, *MA, *MB, *info, *label */ /* Input: const uint32_t klength, plength, k1length, k2length, malength, mblength, clength, llength */ /* Output: uint8_t *key_material */ int hkex_concat_hkdf(const EVP_MD *md_type, uint8_t *key_material, const uint32_t klength, const uint8_t *psk, @@ -433,9 +433,9 @@ int hkex_concat_hkdf(const EVP_MD *md_type, uint8_t *key_material, const uint32_ } while (0); return rval; } -/* Implements the function Concatenation HMAC KDF from Section 8.2 */ +/* Implements function CatKDF from Section 8.2 using HMAC KDF as described in Section 7.4.3 */ /* Input: const EVP_MD *md_type */ -/* Input: uint8_t *psk, *k1, *k2, *MA, *MB, *info, *label */ +/* Input: uint8_t *psk, *k1, *k2, *MA, *MB, *info, *label */ /* Input: const uint32_t klength, plength, k1length, k2length, malength, mblength, clength, llength */ /* Output: uint8_t *key_material */ int hkex_concat_hmac(const EVP_MD *md_type, uint8_t *key_material, const uint32_t klength, const uint8_t *psk, @@ -478,9 +478,9 @@ int hkex_concat_hmac(const EVP_MD *md_type, uint8_t *key_material, const uint32_ } while (0); return rval; } -/* Implements the function Concatenation KMAC KDF from Section 8.2 */ +/* Implements function CatKDF from Section 8.2 using KMAC KDF as described in Section 7.4.4 */ /* Input: const char *kmac */ -/* Input: uint8_t *psk, *k1, *k2, *MA, *MB, *info, *label */ +/* Input: uint8_t *psk, *k1, *k2, *MA, *MB, *info, *label */ /* Input: const uint32_t klength, plength, k1length, k2length, malength, mblength, ilength, llength */ /* Output: uint8_t *key_material */ int hkex_concat_kmac(const char *kmac, uint8_t *key_material, const uint32_t klength, const uint8_t *psk, @@ -521,7 +521,7 @@ int hkex_concat_kmac(const char *kmac, uint8_t *key_material, const uint32_t kle } while (0); return rval; } -/* Implements the one round of the function Cascading HMAC KDF from Section 8.3 */ +/* Implements function CasKDF from Section 8.3 using HKDF KDF and HMAC PRF as described in Sections 7.4.2 and 7.3.2 */ /* Input: const EVP_MD *md_type */ /* Input: uint8_t *previous_chain_secret, *ki, *MAi, *MBi, infoi, *labeli */ /* Input: const uint32_t cslength, klength, pcslength, kilength, mailength, mbilength, iilength, lilength */ @@ -572,7 +572,7 @@ int hkex_cascade_hkdf(const EVP_MD *md_type, uint8_t *chain_secret, const uint32 } while (0); return rval; } -/* Implements the one round of the function Cascading HMAC KDF from Section 8.3 */ +/* Implements function CasKDF from Section 8.3 using HMAC KDF and HMAC PRF as described in Sections 7.4.3 and 7.3.2 */ /* Input: const EVP_MD *md_type */ /* Input: uint8_t *previous_chain_secret, *ki, *MAi, *MBi, infoi, *labeli */ /* Input: const uint32_t cslength, klength, pcslength, kilength, mailength, mbilength, iilength, lilength */ @@ -623,7 +623,7 @@ int hkex_cascade_hmac(const EVP_MD *md_type, uint8_t *chain_secret, const uint32 } while (0); return rval; } -/* Implements the function Cascade KMAC KDF from Section 8.3 */ +/* Implements function CasKDF from Section 8.3 using KMAC KDF and KMAC PRF as described in Sections 7.4.4 and 7.3.3 */ /* Input: const char *kmac */ /* Input: uint8_t *previous_chain_secret, *ki, *MAi, *MBi, infoi, *labeli */ /* Input: const uint32_t cslength, klength, pcslength, kilength, mailength, mbilength, iilength, lilength */ -- GitLab