From ef6b1c974dba6af3406738ea245a2da4366ba9cd Mon Sep 17 00:00:00 2001 From: "Node.js GitHub Bot" Date: Thu, 13 Nov 2025 12:32:55 +0000 Subject: [PATCH 1/4] test: update WPT for WebCryptoAPI to c58b6f4e0e --- test/fixtures/wpt/README.md | 2 +- .../WebCryptoAPI/derive_bits_keys/argon2.js | 89 ++ .../argon2.tentative.https.any.js | 7 + .../derive_bits_keys/argon2_vectors.js | 66 + .../digest/cshake.tentative.https.any.js | 210 ++++ .../digest/sha3.tentative.https.any.js | 140 +++ .../encap_decap_bits.tentative.https.any.js | 193 +++ .../encap_decap_keys.tentative.https.any.js | 448 +++++++ .../encap_decap/ml_kem_encap_decap.js | 410 +++++++ .../encap_decap/ml_kem_vectors.js | 659 ++++++++++ .../wpt/WebCryptoAPI/encrypt_decrypt/aes.js | 2 +- .../aes_ocb.tentative.https.any.js | 7 + .../encrypt_decrypt/aes_ocb_fixtures.js | 437 +++++++ .../encrypt_decrypt/aes_ocb_vectors.js | 142 +++ .../chacha20_poly1305.tentative.https.any.js | 340 ++++++ .../wpt/WebCryptoAPI/generateKey/failures.js | 10 + .../failures_AES-OCB.tentative.https.any.js | 5 + .../failures_ML-DSA.tentative.https.any.js | 5 + .../failures_ML-KEM.tentative.https.any.js | 5 + ...s_chacha20_poly1305.tentative.https.any.js | 5 + .../failures_kmac.tentative.https.any.js | 5 + .../wpt/WebCryptoAPI/generateKey/successes.js | 59 +- .../successes_AES-OCB.tentative.https.any.js | 6 + .../successes_ML-DSA.tentative.https.any.js | 6 + .../successes_ML-KEM.tentative.https.any.js | 6 + ...s_chacha20_poly1305.tentative.https.any.js | 6 + .../successes_kmac.tentative.https.any.js | 6 + .../getPublicKey.tentative.https.any.js | 266 ++++ .../AES-OCB_importKey.tentative.https.any.js | 6 + .../Argon2_importKey.tentative.https.any.js | 8 + ...-Poly1305_importKey.tentative.https.any.js | 6 + .../KMAC_importKey.tentative.https.any.js | 7 + .../import_export/ML-DSA_importKey.js | 222 ++++ .../ML-DSA_importKey.tentative.https.any.js | 9 + .../ML-DSA_importKey_fixtures.js | 449 +++++++ .../import_export/ML-KEM_importKey.js | 222 ++++ .../ML-KEM_importKey.tentative.https.any.js | 9 + .../ML-KEM_importKey_fixtures.js | 76 ++ .../import_export/importKey_failures.js | 20 +- .../symmetric_importKey.https.any.js | 228 +--- .../import_export/symmetric_importKey.js | 231 ++++ .../wpt/WebCryptoAPI/sign_verify/kmac.js | 419 +++++++ .../sign_verify/kmac.tentative.https.any.js | 6 + .../WebCryptoAPI/sign_verify/kmac_vectors.js | 143 +++ .../wpt/WebCryptoAPI/sign_verify/mldsa.js | 757 ++++++++++++ .../sign_verify/mldsa.tentative.https.any.js | 6 + .../WebCryptoAPI/sign_verify/mldsa_vectors.js | 1086 +++++++++++++++++ .../supports.tentative.https.any.js | 397 ++++++ .../fixtures/wpt/WebCryptoAPI/util/helpers.js | 38 +- test/fixtures/wpt/versions.json | 2 +- 50 files changed, 7649 insertions(+), 240 deletions(-) create mode 100644 test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/argon2.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/argon2.tentative.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/argon2_vectors.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/digest/cshake.tentative.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/digest/sha3.tentative.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/encap_decap/encap_decap_bits.tentative.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/encap_decap/encap_decap_keys.tentative.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/encap_decap/ml_kem_encap_decap.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/encap_decap/ml_kem_vectors.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/aes_ocb.tentative.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/aes_ocb_fixtures.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/aes_ocb_vectors.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/chacha20_poly1305.tentative.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/generateKey/failures_AES-OCB.tentative.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/generateKey/failures_ML-DSA.tentative.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/generateKey/failures_ML-KEM.tentative.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/generateKey/failures_chacha20_poly1305.tentative.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/generateKey/failures_kmac.tentative.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/generateKey/successes_AES-OCB.tentative.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/generateKey/successes_ML-DSA.tentative.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/generateKey/successes_ML-KEM.tentative.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/generateKey/successes_chacha20_poly1305.tentative.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/generateKey/successes_kmac.tentative.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/getPublicKey.tentative.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/import_export/AES-OCB_importKey.tentative.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/import_export/Argon2_importKey.tentative.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/import_export/ChaCha20-Poly1305_importKey.tentative.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/import_export/KMAC_importKey.tentative.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/import_export/ML-DSA_importKey.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/import_export/ML-DSA_importKey.tentative.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/import_export/ML-DSA_importKey_fixtures.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/import_export/ML-KEM_importKey.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/import_export/ML-KEM_importKey.tentative.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/import_export/ML-KEM_importKey_fixtures.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/import_export/symmetric_importKey.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/sign_verify/kmac.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/sign_verify/kmac.tentative.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/sign_verify/kmac_vectors.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/sign_verify/mldsa.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/sign_verify/mldsa.tentative.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/sign_verify/mldsa_vectors.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/supports.tentative.https.any.js diff --git a/test/fixtures/wpt/README.md b/test/fixtures/wpt/README.md index 5a6ab4e5522197..a00609e0e5dd33 100644 --- a/test/fixtures/wpt/README.md +++ b/test/fixtures/wpt/README.md @@ -34,7 +34,7 @@ Last update: - wasm/jsapi: https://github.com/web-platform-tests/wpt/tree/cde25e7e3c/wasm/jsapi - wasm/webapi: https://github.com/web-platform-tests/wpt/tree/fd1b23eeaa/wasm/webapi - web-locks: https://github.com/web-platform-tests/wpt/tree/10a122a6bc/web-locks -- WebCryptoAPI: https://github.com/web-platform-tests/wpt/tree/ff26d9b307/WebCryptoAPI +- WebCryptoAPI: https://github.com/web-platform-tests/wpt/tree/c58b6f4e0e/WebCryptoAPI - webidl/ecmascript-binding/es-exceptions: https://github.com/web-platform-tests/wpt/tree/2f96fa1996/webidl/ecmascript-binding/es-exceptions - webmessaging/broadcastchannel: https://github.com/web-platform-tests/wpt/tree/6495c91853/webmessaging/broadcastchannel - webstorage: https://github.com/web-platform-tests/wpt/tree/1d2c5fb36a/webstorage diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/argon2.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/argon2.js new file mode 100644 index 00000000000000..f1609403d623fa --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/argon2.js @@ -0,0 +1,89 @@ +function define_tests() { + var subtle = self.crypto.subtle; + + var testData = getTestData(); + var testVectors = testData.testVectors; + + return setUpBaseKeys().then(function (allKeys) { + var baseKeys = allKeys.baseKeys; + + testVectors.forEach(function (vector) { + var algorithmName = vector.algorithm; + var params = vector.params; + var expected = vector.expected; + + var testName = algorithmName + ' deriveBits'; + + // Test deriveBits + subsetTest( + promise_test, + function (test) { + var algorithm = Object.assign({ name: algorithmName }, params); + return subtle + .deriveBits(algorithm, baseKeys[algorithmName], 256) + .then( + function (derivation) { + assert_true( + equalBuffers(derivation, expected), + 'Derived correct key' + ); + }, + function (err) { + assert_unreached( + 'deriveBits failed with error ' + + err.name + + ': ' + + err.message + ); + } + ); + }, + testName + ); + }); + }); + + function setUpBaseKeys() { + var promises = []; + var baseKeys = {}; + + testVectors.forEach(function (vector) { + var algorithmName = vector.algorithm; + var password = vector.password; + + // Key for normal operations + promises.push( + subtle + .importKey('raw-secret', password, algorithmName, false, [ + 'deriveBits', + ]) + .then(function (key) { + baseKeys[algorithmName] = key; + }) + ); + }); + + return Promise.all(promises).then(function () { + return { + baseKeys: baseKeys, + }; + }); + } +} + +function equalBuffers(a, b) { + if (a.byteLength !== b.byteLength) { + return false; + } + + var aView = new Uint8Array(a); + var bView = new Uint8Array(b); + + for (var i = 0; i < aView.length; i++) { + if (aView[i] !== bView[i]) { + return false; + } + } + + return true; +} diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/argon2.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/argon2.tentative.https.any.js new file mode 100644 index 00000000000000..55fb11c995653e --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/argon2.tentative.https.any.js @@ -0,0 +1,7 @@ +// META: title=WebCryptoAPI: deriveBits() Using Argon2 +// META: timeout=long +// META: script=/common/subset-tests.js +// META: script=argon2_vectors.js +// META: script=argon2.js + +promise_test(define_tests, 'setup - define tests'); diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/argon2_vectors.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/argon2_vectors.js new file mode 100644 index 00000000000000..9b9acda5f42d3a --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/argon2_vectors.js @@ -0,0 +1,66 @@ +function getTestData() { + // Test vectors from RFC 9106 + // https://www.rfc-editor.org/rfc/rfc9106 + + // Test vectors from RFC 9106 + var testVectors = [ + // Argon2d test vector + { + algorithm: 'Argon2d', + password: new Uint8Array(32).fill(0x01), + params: { + memory: 32, + passes: 3, + parallelism: 4, + nonce: new Uint8Array(16).fill(0x02), + secretValue: new Uint8Array(8).fill(0x03), + associatedData: new Uint8Array(12).fill(0x04), + }, + expected: new Uint8Array([ + 0x51, 0x2b, 0x39, 0x1b, 0x6f, 0x11, 0x62, 0x97, 0x53, 0x71, 0xd3, 0x09, + 0x19, 0x73, 0x42, 0x94, 0xf8, 0x68, 0xe3, 0xbe, 0x39, 0x84, 0xf3, 0xc1, + 0xa1, 0x3a, 0x4d, 0xb9, 0xfa, 0xbe, 0x4a, 0xcb, + ]), + }, + // Argon2i test vector + { + algorithm: 'Argon2i', + password: new Uint8Array(32).fill(0x01), + params: { + memory: 32, + passes: 3, + parallelism: 4, + nonce: new Uint8Array(16).fill(0x02), + secretValue: new Uint8Array(8).fill(0x03), + associatedData: new Uint8Array(12).fill(0x04), + }, + expected: new Uint8Array([ + 0xc8, 0x14, 0xd9, 0xd1, 0xdc, 0x7f, 0x37, 0xaa, 0x13, 0xf0, 0xd7, 0x7f, + 0x24, 0x94, 0xbd, 0xa1, 0xc8, 0xde, 0x6b, 0x01, 0x6d, 0xd3, 0x88, 0xd2, + 0x99, 0x52, 0xa4, 0xc4, 0x67, 0x2b, 0x6c, 0xe8, + ]), + }, + // Argon2id test vector + { + algorithm: 'Argon2id', + password: new Uint8Array(32).fill(0x01), + params: { + memory: 32, + passes: 3, + parallelism: 4, + nonce: new Uint8Array(16).fill(0x02), + secretValue: new Uint8Array(8).fill(0x03), + associatedData: new Uint8Array(12).fill(0x04), + }, + expected: new Uint8Array([ + 0x0d, 0x64, 0x0d, 0xf5, 0x8d, 0x78, 0x76, 0x6c, 0x08, 0xc0, 0x37, 0xa3, + 0x4a, 0x8b, 0x53, 0xc9, 0xd0, 0x1e, 0xf0, 0x45, 0x2d, 0x75, 0xb6, 0x5e, + 0xb5, 0x25, 0x20, 0xe9, 0x6b, 0x01, 0xe6, 0x59, + ]), + }, + ]; + + return { + testVectors: testVectors, + }; +} diff --git a/test/fixtures/wpt/WebCryptoAPI/digest/cshake.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/digest/cshake.tentative.https.any.js new file mode 100644 index 00000000000000..e793722d8be598 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/digest/cshake.tentative.https.any.js @@ -0,0 +1,210 @@ +// META: title=WebCryptoAPI: digest() cSHAKE algorithms +// META: timeout=long + +var subtle = crypto.subtle; // Change to test prefixed implementations + +var sourceData = { + empty: new Uint8Array(0), + short: new Uint8Array([ + 21, 110, 234, 124, 193, 76, 86, 203, 148, 219, 3, 10, 74, 157, 149, 255, + ]), + medium: new Uint8Array([ + 182, 200, 249, 223, 100, 140, 208, 136, 183, 15, 56, 231, 65, 151, 177, 140, + 184, 30, 30, 67, 80, 213, 11, 204, 184, 251, 90, 115, 121, 200, 123, 178, + 227, 214, 237, 84, 97, 237, 30, 159, 54, 243, 64, 163, 150, 42, 68, 107, + 129, 91, 121, 75, 75, 212, 58, 68, 3, 80, 32, 119, 178, 37, 108, 200, 7, + 131, 127, 58, 172, 209, 24, 235, 75, 156, 43, 174, 184, 151, 6, 134, 37, + 171, 172, 161, 147, + ]), +}; + +// Test different output lengths for cSHAKE +var digestLengths = [0, 256, 384, 512]; + +var digestedData = { + cSHAKE128: { + 0: { + empty: new Uint8Array([]), + short: new Uint8Array([]), + medium: new Uint8Array([]), + }, + 256: { + empty: new Uint8Array([ + 127, 156, 43, 164, 232, 143, 130, 125, 97, 96, 69, 80, 118, 5, 133, 62, + 215, 59, 128, 147, 246, 239, 188, 136, 235, 26, 110, 172, 250, 102, 239, + 38, + ]), + short: new Uint8Array([ + 222, 166, 45, 115, 230, 181, 156, 247, 37, 208, 50, 13, 102, 0, 137, + 164, 71, 92, 187, 211, 184, 83, 158, 54, 105, 31, 21, 13, 71, 85, 103, + 148, + ]), + medium: new Uint8Array([ + 177, 172, 213, 58, 3, 231, 106, 34, 30, 82, 234, 87, 142, 4, 47, 104, + 106, 104, 195, 209, 201, 131, 42, 177, 130, 133, 207, 79, 48, 76, 163, + 45, + ]), + }, + 384: { + empty: new Uint8Array([ + 127, 156, 43, 164, 232, 143, 130, 125, 97, 96, 69, 80, 118, 5, 133, 62, + 215, 59, 128, 147, 246, 239, 188, 136, 235, 26, 110, 172, 250, 102, 239, + 38, 60, 177, 238, 169, 136, 0, 75, 147, 16, 60, 251, 10, 238, 253, 42, + 104, + ]), + short: new Uint8Array([ + 222, 166, 45, 115, 230, 181, 156, 247, 37, 208, 50, 13, 102, 0, 137, + 164, 71, 92, 187, 211, 184, 83, 158, 54, 105, 31, 21, 13, 71, 85, 103, + 148, 240, 55, 64, 1, 183, 136, 138, 188, 54, 152, 212, 11, 137, 174, 49, + 52, + ]), + medium: new Uint8Array([ + 177, 172, 213, 58, 3, 231, 106, 34, 30, 82, 234, 87, 142, 4, 47, 104, + 106, 104, 195, 209, 201, 131, 42, 177, 130, 133, 207, 79, 48, 76, 163, + 45, 63, 170, 9, 252, 130, 170, 225, 66, 211, 223, 205, 121, 5, 138, 93, + 92, + ]), + }, + 512: { + empty: new Uint8Array([ + 127, 156, 43, 164, 232, 143, 130, 125, 97, 96, 69, 80, 118, 5, 133, 62, + 215, 59, 128, 147, 246, 239, 188, 136, 235, 26, 110, 172, 250, 102, 239, + 38, 60, 177, 238, 169, 136, 0, 75, 147, 16, 60, 251, 10, 238, 253, 42, + 104, 110, 1, 250, 74, 88, 232, 163, 99, 156, 168, 161, 227, 249, 174, + 87, 226, + ]), + short: new Uint8Array([ + 222, 166, 45, 115, 230, 181, 156, 247, 37, 208, 50, 13, 102, 0, 137, + 164, 71, 92, 187, 211, 184, 83, 158, 54, 105, 31, 21, 13, 71, 85, 103, + 148, 240, 55, 64, 1, 183, 136, 138, 188, 54, 152, 212, 11, 137, 174, 49, + 52, 233, 51, 245, 26, 132, 202, 127, 218, 136, 12, 59, 253, 217, 220, + 58, 94, + ]), + medium: new Uint8Array([ + 177, 172, 213, 58, 3, 231, 106, 34, 30, 82, 234, 87, 142, 4, 47, 104, + 106, 104, 195, 209, 201, 131, 42, 177, 130, 133, 207, 79, 48, 76, 163, + 45, 63, 170, 9, 252, 130, 170, 225, 66, 211, 223, 205, 121, 5, 138, 93, + 92, 60, 17, 189, 45, 17, 195, 248, 169, 51, 31, 98, 172, 221, 186, 225, + 93, + ]), + }, + }, + cSHAKE256: { + 0: { + empty: new Uint8Array([]), + short: new Uint8Array([]), + medium: new Uint8Array([]), + }, + 256: { + empty: new Uint8Array([ + 70, 185, 221, 43, 11, 168, 141, 19, 35, 59, 63, 235, 116, 62, 235, 36, + 63, 205, 82, 234, 98, 184, 27, 130, 181, 12, 39, 100, 110, 213, 118, 47, + ]), + short: new Uint8Array([ + 23, 56, 17, 63, 90, 187, 62, 229, 50, 14, 225, 138, 162, 102, 195, 97, + 122, 116, 117, 219, 216, 237, 154, 152, 89, 148, 253, 221, 97, 18, 173, + 153, + ]), + medium: new Uint8Array([ + 65, 70, 193, 61, 134, 217, 188, 24, 107, 11, 48, 154, 182, 161, 36, 238, + 12, 116, 186, 38, 184, 198, 13, 204, 123, 62, 213, 5, 150, 154, 168, + 209, + ]), + }, + 384: { + empty: new Uint8Array([ + 70, 185, 221, 43, 11, 168, 141, 19, 35, 59, 63, 235, 116, 62, 235, 36, + 63, 205, 82, 234, 98, 184, 27, 130, 181, 12, 39, 100, 110, 213, 118, 47, + 215, 93, 196, 221, 216, 192, 242, 0, 203, 5, 1, 157, 103, 181, 146, 246, + ]), + short: new Uint8Array([ + 23, 56, 17, 63, 90, 187, 62, 229, 50, 14, 225, 138, 162, 102, 195, 97, + 122, 116, 117, 219, 216, 237, 154, 152, 89, 148, 253, 221, 97, 18, 173, + 153, 158, 200, 226, 235, 223, 234, 251, 150, 231, 111, 107, 179, 163, + 173, 186, 67, + ]), + medium: new Uint8Array([ + 65, 70, 193, 61, 134, 217, 188, 24, 107, 11, 48, 154, 182, 161, 36, 238, + 12, 116, 186, 38, 184, 198, 13, 204, 123, 62, 213, 5, 150, 154, 168, + 209, 144, 40, 198, 49, 121, 153, 160, 133, 177, 230, 182, 167, 133, 206, + 79, 246, + ]), + }, + 512: { + empty: new Uint8Array([ + 70, 185, 221, 43, 11, 168, 141, 19, 35, 59, 63, 235, 116, 62, 235, 36, + 63, 205, 82, 234, 98, 184, 27, 130, 181, 12, 39, 100, 110, 213, 118, 47, + 215, 93, 196, 221, 216, 192, 242, 0, 203, 5, 1, 157, 103, 181, 146, 246, + 252, 130, 28, 73, 71, 154, 180, 134, 64, 41, 46, 172, 179, 183, 196, + 190, + ]), + short: new Uint8Array([ + 23, 56, 17, 63, 90, 187, 62, 229, 50, 14, 225, 138, 162, 102, 195, 97, + 122, 116, 117, 219, 216, 237, 154, 152, 89, 148, 253, 221, 97, 18, 173, + 153, 158, 200, 226, 235, 223, 234, 251, 150, 231, 111, 107, 179, 163, + 173, 186, 67, 218, 96, 240, 12, 209, 36, 150, 223, 90, 243, 226, 138, + 230, 211, 222, 66, + ]), + medium: new Uint8Array([ + 65, 70, 193, 61, 134, 217, 188, 24, 107, 11, 48, 154, 182, 161, 36, 238, + 12, 116, 186, 38, 184, 198, 13, 204, 123, 62, 213, 5, 150, 154, 168, + 209, 144, 40, 198, 49, 121, 153, 160, 133, 177, 230, 182, 167, 133, 206, + 79, 246, 50, 174, 178, 116, 147, 34, 126, 68, 35, 47, 183, 179, 149, 33, + 65, 123, + ]), + }, + }, +}; + +// Test cSHAKE digest algorithms with variable output lengths +Object.keys(digestedData).forEach(function (alg) { + digestLengths.forEach(function (length) { + Object.keys(sourceData).forEach(function (size) { + promise_test(function (test) { + return crypto.subtle + .digest({ name: alg, length: length }, sourceData[size]) + .then(function (result) { + assert_true( + equalBuffers(result, digestedData[alg][length][size]), + 'digest matches expected' + ); + }); + }, alg + ' with ' + length + ' bit output and ' + size + ' source data'); + + promise_test(function (test) { + var buffer = new Uint8Array(sourceData[size]); + return crypto.subtle + .digest({ name: alg, length: length }, buffer) + .then(function (result) { + // Alter the buffer after calling digest + if (buffer.length > 0) { + buffer[0] = ~buffer[0]; + } + assert_true( + equalBuffers(result, digestedData[alg][length][size]), + 'digest matches expected' + ); + }); + }, alg + + ' with ' + + length + + ' bit output and ' + + size + + ' source data and altered buffer after call'); + }); + }); +}); + +function equalBuffers(a, b) { + if (a.byteLength !== b.byteLength) { + return false; + } + var aBytes = new Uint8Array(a); + var bBytes = new Uint8Array(b); + for (var i = 0; i < a.byteLength; i++) { + if (aBytes[i] !== bBytes[i]) { + return false; + } + } + return true; +} diff --git a/test/fixtures/wpt/WebCryptoAPI/digest/sha3.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/digest/sha3.tentative.https.any.js new file mode 100644 index 00000000000000..8f84ad08ca1a25 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/digest/sha3.tentative.https.any.js @@ -0,0 +1,140 @@ +// META: title=WebCryptoAPI: digest() SHA-3 algorithms +// META: timeout=long + +var subtle = crypto.subtle; // Change to test prefixed implementations + +var sourceData = { + empty: new Uint8Array(0), + short: new Uint8Array([ + 21, 110, 234, 124, 193, 76, 86, 203, 148, 219, 3, 10, 74, 157, 149, 255, + ]), + medium: new Uint8Array([ + 182, 200, 249, 223, 100, 140, 208, 136, 183, 15, 56, 231, 65, 151, 177, 140, + 184, 30, 30, 67, 80, 213, 11, 204, 184, 251, 90, 115, 121, 200, 123, 178, + 227, 214, 237, 84, 97, 237, 30, 159, 54, 243, 64, 163, 150, 42, 68, 107, + 129, 91, 121, 75, 75, 212, 58, 68, 3, 80, 32, 119, 178, 37, 108, 200, 7, + 131, 127, 58, 172, 209, 24, 235, 75, 156, 43, 174, 184, 151, 6, 134, 37, + 171, 172, 161, 147, + ]), +}; + +sourceData.long = new Uint8Array(1024 * sourceData.medium.byteLength); +for (var i = 0; i < 1024; i++) { + sourceData.long.set(sourceData.medium, i * sourceData.medium.byteLength); +} + +var digestedData = { + 'SHA3-256': { + empty: new Uint8Array([ + 167, 255, 198, 248, 191, 30, 215, 102, 81, 193, 71, 86, 160, 97, 214, 98, + 245, 128, 255, 77, 228, 59, 73, 250, 130, 216, 10, 75, 128, 248, 67, 74, + ]), + short: new Uint8Array([ + 48, 89, 175, 122, 163, 59, 81, 112, 132, 232, 173, 123, 188, 79, 178, 8, + 164, 76, 40, 239, 50, 180, 105, 141, 16, 61, 213, 64, 228, 249, 26, 161, + ]), + medium: new Uint8Array([ + 31, 167, 205, 29, 167, 76, 216, 4, 100, 23, 80, 140, 131, 20, 231, 74, + 154, 74, 157, 56, 249, 241, 142, 108, 178, 21, 184, 200, 145, 160, 168, + 14, + ]), + long: new Uint8Array([ + 178, 207, 198, 30, 3, 134, 205, 174, 245, 225, 10, 43, 225, 137, 137, 31, + 94, 245, 42, 118, 36, 191, 205, 142, 220, 137, 58, 204, 100, 254, 198, 0, + ]), + }, + 'SHA3-384': { + empty: new Uint8Array([ + 12, 99, 167, 91, 132, 94, 79, 125, 1, 16, 125, 133, 46, 76, 36, 133, 197, + 26, 80, 170, 170, 148, 252, 97, 153, 94, 113, 187, 238, 152, 58, 42, 195, + 113, 56, 49, 38, 74, 219, 71, 251, 107, 209, 224, 88, 213, 240, 4, + ]), + short: new Uint8Array([ + 84, 184, 240, 228, 207, 73, 116, 222, 116, 0, 152, 246, 107, 48, 36, 71, + 155, 1, 99, 19, 21, 166, 119, 54, 6, 195, 62, 173, 195, 37, 86, 166, 231, + 120, 224, 143, 2, 37, 174, 121, 38, 90, 236, 102, 108, 178, 57, 11, + ]), + medium: new Uint8Array([ + 67, 123, 125, 139, 104, 178, 80, 181, 193, 115, 158, 164, 204, 134, 219, + 32, 51, 135, 157, 251, 24, 222, 41, 44, 156, 80, 217, 193, 147, 164, 199, + 154, 8, 166, 202, 227, 244, 228, 131, 194, 121, 94, 165, 209, 239, 126, + 105, 210, + ]), + long: new Uint8Array([ + 59, 57, 196, 201, 122, 216, 118, 19, 48, 93, 12, 204, 152, 113, 129, 113, + 62, 45, 94, 132, 177, 249, 118, 0, 17, 188, 206, 12, 41, 116, 153, 0, 91, + 220, 232, 163, 210, 64, 155, 90, 208, 22, 79, 50, 187, 135, 120, 208, + ]), + }, + 'SHA3-512': { + empty: new Uint8Array([ + 166, 159, 115, 204, 162, 58, 154, 197, 200, 181, 103, 220, 24, 90, 117, + 110, 151, 201, 130, 22, 79, 226, 88, 89, 224, 209, 220, 193, 71, 92, 128, + 166, 21, 178, 18, 58, 241, 245, 249, 76, 17, 227, 233, 64, 44, 58, 197, + 88, 245, 0, 25, 157, 149, 182, 211, 227, 1, 117, 133, 134, 40, 29, 205, + 38, + ]), + short: new Uint8Array([ + 45, 210, 224, 122, 98, 230, 173, 4, 152, 186, 132, 243, 19, 196, 212, 2, + 76, 180, 96, 1, 247, 143, 117, 219, 51, 107, 13, 77, 139, 210, 169, 236, + 21, 44, 74, 210, 8, 120, 115, 93, 130, 186, 8, 114, 236, 245, 150, 8, 239, + 60, 237, 43, 42, 134, 105, 66, 126, 125, 163, 30, 54, 35, 51, 216, + ]), + medium: new Uint8Array([ + 230, 64, 162, 25, 9, 83, 102, 64, 54, 158, 155, 10, 72, 147, 28, 92, 178, + 239, 203, 201, 31, 236, 242, 71, 48, 107, 201, 106, 14, 76, 163, 51, 7, + 203, 142, 27, 154, 243, 103, 148, 109, 208, 28, 36, 63, 57, 7, 80, 141, 4, + 241, 105, 42, 49, 97, 223, 31, 137, 141, 232, 238, 37, 254, 190, + ]), + long: new Uint8Array([ + 189, 38, 44, 236, 245, 101, 195, 56, 3, 45, 229, 186, 1, 56, 240, 170, + 207, 231, 221, 232, 61, 39, 45, 13, 55, 217, 82, 130, 158, 210, 93, 225, + 161, 52, 45, 152, 101, 158, 247, 210, 250, 74, 202, 124, 226, 177, 170, 7, + 132, 216, 252, 29, 203, 248, 27, 206, 199, 167, 67, 26, 61, 163, 107, 247, + ]), + }, +}; + +// Test SHA-3 digest algorithms +Object.keys(sourceData).forEach(function (size) { + Object.keys(digestedData).forEach(function (alg) { + promise_test(function (test) { + return crypto.subtle + .digest(alg, sourceData[size]) + .then(function (result) { + assert_true( + equalBuffers(result, digestedData[alg][size]), + 'digest matches expected' + ); + }); + }, alg + ' with ' + size + ' source data'); + + promise_test(function (test) { + var buffer = new Uint8Array(sourceData[size]); + return crypto.subtle.digest(alg, buffer).then(function (result) { + // Alter the buffer after calling digest + if (buffer.length > 0) { + buffer[0] = ~buffer[0]; + } + assert_true( + equalBuffers(result, digestedData[alg][size]), + 'digest matches expected' + ); + }); + }, alg + ' with ' + size + ' source data and altered buffer after call'); + }); +}); + +function equalBuffers(a, b) { + if (a.byteLength !== b.byteLength) { + return false; + } + var aBytes = new Uint8Array(a); + var bBytes = new Uint8Array(b); + for (var i = 0; i < a.byteLength; i++) { + if (aBytes[i] !== bBytes[i]) { + return false; + } + } + return true; +} diff --git a/test/fixtures/wpt/WebCryptoAPI/encap_decap/encap_decap_bits.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/encap_decap/encap_decap_bits.tentative.https.any.js new file mode 100644 index 00000000000000..ab112e4d497676 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/encap_decap/encap_decap_bits.tentative.https.any.js @@ -0,0 +1,193 @@ +// META: title=WebCryptoAPI: ML-KEM encapsulateBits() and decapsulateBits() tests +// META: script=ml_kem_vectors.js +// META: script=../util/helpers.js +// META: timeout=long + +function define_bits_tests() { + var subtle = self.crypto.subtle; + var variants = ['ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024']; + + variants.forEach(function (algorithmName) { + // Test encapsulateBits operation + promise_test(async function (test) { + // Generate a key pair for testing + var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ + 'encapsulateBits', + 'decapsulateBits', + ]); + + // Test encapsulateBits + var encapsulatedBits = await subtle.encapsulateBits( + { name: algorithmName }, + keyPair.publicKey + ); + + assert_true( + encapsulatedBits instanceof Object, + 'encapsulateBits should return an object' + ); + assert_true( + encapsulatedBits.hasOwnProperty('sharedKey'), + 'Result should have sharedKey property' + ); + assert_true( + encapsulatedBits.hasOwnProperty('ciphertext'), + 'Result should have ciphertext property' + ); + assert_true( + encapsulatedBits.sharedKey instanceof ArrayBuffer, + 'sharedKey should be ArrayBuffer' + ); + assert_true( + encapsulatedBits.ciphertext instanceof ArrayBuffer, + 'ciphertext should be ArrayBuffer' + ); + + // Verify sharedKey length (should be 32 bytes for all ML-KEM variants) + assert_equals( + encapsulatedBits.sharedKey.byteLength, + 32, + 'Shared key should be 32 bytes' + ); + + // Verify ciphertext length based on algorithm variant + var expectedCiphertextLength; + switch (algorithmName) { + case 'ML-KEM-512': + expectedCiphertextLength = 768; + break; + case 'ML-KEM-768': + expectedCiphertextLength = 1088; + break; + case 'ML-KEM-1024': + expectedCiphertextLength = 1568; + break; + } + assert_equals( + encapsulatedBits.ciphertext.byteLength, + expectedCiphertextLength, + 'Ciphertext should be ' + + expectedCiphertextLength + + ' bytes for ' + + algorithmName + ); + }, algorithmName + ' encapsulateBits basic functionality'); + + // Test decapsulateBits operation + promise_test(async function (test) { + // Generate a key pair for testing + var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ + 'encapsulateBits', + 'decapsulateBits', + ]); + + // First encapsulate to get ciphertext + var encapsulatedBits = await subtle.encapsulateBits( + { name: algorithmName }, + keyPair.publicKey + ); + + // Then decapsulate using the private key + var decapsulatedBits = await subtle.decapsulateBits( + { name: algorithmName }, + keyPair.privateKey, + encapsulatedBits.ciphertext + ); + + assert_true( + decapsulatedBits instanceof ArrayBuffer, + 'decapsulateBits should return ArrayBuffer' + ); + assert_equals( + decapsulatedBits.byteLength, + 32, + 'Decapsulated bits should be 32 bytes' + ); + + // The decapsulated shared secret should match the original + assert_true( + equalBuffers(decapsulatedBits, encapsulatedBits.sharedKey), + 'Decapsulated shared secret should match original' + ); + }, algorithmName + ' decapsulateBits basic functionality'); + + // Test round-trip compatibility + promise_test(async function (test) { + var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ + 'encapsulateBits', + 'decapsulateBits', + ]); + + var encapsulatedBits = await subtle.encapsulateBits( + { name: algorithmName }, + keyPair.publicKey + ); + + var decapsulatedBits = await subtle.decapsulateBits( + { name: algorithmName }, + keyPair.privateKey, + encapsulatedBits.ciphertext + ); + + assert_true( + equalBuffers(encapsulatedBits.sharedKey, decapsulatedBits), + 'Encapsulated and decapsulated shared secrets should match' + ); + }, algorithmName + + ' encapsulateBits/decapsulateBits round-trip compatibility'); + + // Test vector-based decapsulation + promise_test(async function (test) { + var vectors = ml_kem_vectors[algorithmName]; + + // Import the private key from the vector's privateSeed + var privateKey = await subtle.importKey( + 'raw-seed', + vectors.privateSeed, + { name: algorithmName }, + false, + ['decapsulateBits'] + ); + + // Decapsulate the sample ciphertext from the vectors + var decapsulatedBits = await subtle.decapsulateBits( + { name: algorithmName }, + privateKey, + vectors.sampleCiphertext + ); + + assert_true( + decapsulatedBits instanceof ArrayBuffer, + 'decapsulateBits should return ArrayBuffer' + ); + assert_equals( + decapsulatedBits.byteLength, + 32, + 'Decapsulated bits should be 32 bytes' + ); + + // The decapsulated shared secret should match the expected value from vectors + assert_true( + equalBuffers(decapsulatedBits, vectors.expectedSharedSecret), + "Decapsulated shared secret should match vector's expectedSharedSecret" + ); + }, algorithmName + ' vector-based sampleCiphertext decapsulation'); + }); +} + +// Helper function to compare two ArrayBuffers +function equalBuffers(a, b) { + if (a.byteLength !== b.byteLength) { + return false; + } + var aBytes = new Uint8Array(a); + var bBytes = new Uint8Array(b); + for (var i = 0; i < a.byteLength; i++) { + if (aBytes[i] !== bBytes[i]) { + return false; + } + } + return true; +} + +define_bits_tests(); diff --git a/test/fixtures/wpt/WebCryptoAPI/encap_decap/encap_decap_keys.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/encap_decap/encap_decap_keys.tentative.https.any.js new file mode 100644 index 00000000000000..4ccb0585b84f87 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/encap_decap/encap_decap_keys.tentative.https.any.js @@ -0,0 +1,448 @@ +// META: title=WebCryptoAPI: ML-KEM encapsulateKey() and decapsulateKey() tests +// META: script=ml_kem_vectors.js +// META: script=../util/helpers.js +// META: timeout=long + +function define_key_tests() { + var subtle = self.crypto.subtle; + var variants = ['ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024']; + + // Test various 256-bit shared key algorithms + var sharedKeyConfigs = [ + { + algorithm: { name: 'AES-GCM', length: 256 }, + usages: ['encrypt', 'decrypt'], + description: 'AES-GCM-256', + }, + { + algorithm: { name: 'AES-CBC', length: 256 }, + usages: ['encrypt', 'decrypt'], + description: 'AES-CBC-256', + }, + { + algorithm: { name: 'AES-CTR', length: 256 }, + usages: ['encrypt', 'decrypt'], + description: 'AES-CTR-256', + }, + { + algorithm: { name: 'AES-KW', length: 256 }, + usages: ['wrapKey', 'unwrapKey'], + description: 'AES-KW-256', + }, + { + algorithm: { name: 'HMAC', hash: 'SHA-256' }, + usages: ['sign', 'verify'], + description: 'HMAC-SHA-256', + }, + ]; + + variants.forEach(function (algorithmName) { + sharedKeyConfigs.forEach(function (config) { + // Test encapsulateKey operation + promise_test(async function (test) { + // Generate a key pair for testing + var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ + 'encapsulateKey', + 'decapsulateKey', + ]); + + // Test encapsulateKey + var encapsulatedKey = await subtle.encapsulateKey( + { name: algorithmName }, + keyPair.publicKey, + config.algorithm, + true, + config.usages + ); + + assert_true( + encapsulatedKey instanceof Object, + 'encapsulateKey should return an object' + ); + assert_true( + encapsulatedKey.hasOwnProperty('sharedKey'), + 'Result should have sharedKey property' + ); + assert_true( + encapsulatedKey.hasOwnProperty('ciphertext'), + 'Result should have ciphertext property' + ); + assert_true( + encapsulatedKey.sharedKey instanceof CryptoKey, + 'sharedKey should be a CryptoKey' + ); + assert_true( + encapsulatedKey.ciphertext instanceof ArrayBuffer, + 'ciphertext should be ArrayBuffer' + ); + + // Verify the shared key properties + assert_equals( + encapsulatedKey.sharedKey.type, + 'secret', + 'Shared key should be secret type' + ); + assert_equals( + encapsulatedKey.sharedKey.algorithm.name, + config.algorithm.name, + 'Shared key algorithm should match' + ); + assert_true( + encapsulatedKey.sharedKey.extractable, + 'Shared key should be extractable as specified' + ); + assert_array_equals( + encapsulatedKey.sharedKey.usages, + config.usages, + 'Shared key should have correct usages' + ); + + // Verify algorithm-specific properties + if (config.algorithm.length) { + assert_equals( + encapsulatedKey.sharedKey.algorithm.length, + config.algorithm.length, + 'Key length should be 256' + ); + } + if (config.algorithm.hash) { + assert_equals( + encapsulatedKey.sharedKey.algorithm.hash.name, + config.algorithm.hash, + 'Hash algorithm should match' + ); + } + + // Verify ciphertext length based on algorithm variant + var expectedCiphertextLength; + switch (algorithmName) { + case 'ML-KEM-512': + expectedCiphertextLength = 768; + break; + case 'ML-KEM-768': + expectedCiphertextLength = 1088; + break; + case 'ML-KEM-1024': + expectedCiphertextLength = 1568; + break; + } + assert_equals( + encapsulatedKey.ciphertext.byteLength, + expectedCiphertextLength, + 'Ciphertext should be ' + + expectedCiphertextLength + + ' bytes for ' + + algorithmName + ); + }, algorithmName + ' encapsulateKey with ' + config.description); + + // Test decapsulateKey operation + promise_test(async function (test) { + // Generate a key pair for testing + var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ + 'encapsulateKey', + 'decapsulateKey', + ]); + + // First encapsulate to get ciphertext + var encapsulatedKey = await subtle.encapsulateKey( + { name: algorithmName }, + keyPair.publicKey, + config.algorithm, + true, + config.usages + ); + + // Then decapsulate using the private key + var decapsulatedKey = await subtle.decapsulateKey( + { name: algorithmName }, + keyPair.privateKey, + encapsulatedKey.ciphertext, + config.algorithm, + true, + config.usages + ); + + assert_true( + decapsulatedKey instanceof CryptoKey, + 'decapsulateKey should return a CryptoKey' + ); + assert_equals( + decapsulatedKey.type, + 'secret', + 'Decapsulated key should be secret type' + ); + assert_equals( + decapsulatedKey.algorithm.name, + config.algorithm.name, + 'Decapsulated key algorithm should match' + ); + assert_true( + decapsulatedKey.extractable, + 'Decapsulated key should be extractable as specified' + ); + assert_array_equals( + decapsulatedKey.usages, + config.usages, + 'Decapsulated key should have correct usages' + ); + + // Extract both keys and verify they are identical + var originalKeyMaterial = await subtle.exportKey( + 'raw', + encapsulatedKey.sharedKey + ); + var decapsulatedKeyMaterial = await subtle.exportKey( + 'raw', + decapsulatedKey + ); + + assert_true( + equalBuffers(originalKeyMaterial, decapsulatedKeyMaterial), + 'Decapsulated key material should match original' + ); + + // Verify the key material is 32 bytes (256 bits) + assert_equals( + originalKeyMaterial.byteLength, + 32, + 'Shared key material should be 32 bytes' + ); + }, algorithmName + ' decapsulateKey with ' + config.description); + + // Test round-trip compatibility + promise_test(async function (test) { + var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ + 'encapsulateKey', + 'decapsulateKey', + ]); + + var encapsulatedKey = await subtle.encapsulateKey( + { name: algorithmName }, + keyPair.publicKey, + config.algorithm, + true, + config.usages + ); + + var decapsulatedKey = await subtle.decapsulateKey( + { name: algorithmName }, + keyPair.privateKey, + encapsulatedKey.ciphertext, + config.algorithm, + true, + config.usages + ); + + // Verify keys have the same material + var originalKeyMaterial = await subtle.exportKey( + 'raw', + encapsulatedKey.sharedKey + ); + var decapsulatedKeyMaterial = await subtle.exportKey( + 'raw', + decapsulatedKey + ); + + assert_true( + equalBuffers(originalKeyMaterial, decapsulatedKeyMaterial), + 'Encapsulated and decapsulated keys should have the same material' + ); + + // Test that the derived keys can actually be used for their intended purpose + if ( + config.algorithm.name.startsWith('AES') && + config.usages.includes('encrypt') + ) { + await testAESOperation( + encapsulatedKey.sharedKey, + decapsulatedKey, + config.algorithm + ); + } else if (config.algorithm.name === 'HMAC') { + await testHMACOperation(encapsulatedKey.sharedKey, decapsulatedKey); + } + }, algorithmName + + ' encapsulateKey/decapsulateKey round-trip with ' + + config.description); + }); + + // Test vector-based decapsulation for each shared key config + sharedKeyConfigs.forEach(function (config) { + promise_test(async function (test) { + var vectors = ml_kem_vectors[algorithmName]; + + // Import the private key from the vector's privateSeed + var privateKey = await subtle.importKey( + 'raw-seed', + vectors.privateSeed, + { name: algorithmName }, + false, + ['decapsulateKey'] + ); + + // Decapsulate the sample ciphertext from the vectors to get a shared key + var decapsulatedKey = await subtle.decapsulateKey( + { name: algorithmName }, + privateKey, + vectors.sampleCiphertext, + config.algorithm, + true, + config.usages + ); + + assert_true( + decapsulatedKey instanceof CryptoKey, + 'decapsulateKey should return a CryptoKey' + ); + assert_equals( + decapsulatedKey.type, + 'secret', + 'Decapsulated key should be secret type' + ); + assert_equals( + decapsulatedKey.algorithm.name, + config.algorithm.name, + 'Decapsulated key algorithm should match' + ); + assert_true( + decapsulatedKey.extractable, + 'Decapsulated key should be extractable as specified' + ); + assert_array_equals( + decapsulatedKey.usages, + config.usages, + 'Decapsulated key should have correct usages' + ); + + // Extract the key material and verify it matches the expected shared secret + var keyMaterial = await subtle.exportKey('raw', decapsulatedKey); + assert_equals( + keyMaterial.byteLength, + 32, + 'Shared key material should be 32 bytes' + ); + assert_true( + equalBuffers(keyMaterial, vectors.expectedSharedSecret), + "Decapsulated key material should match vector's expectedSharedSecret" + ); + + // Verify algorithm-specific properties + if (config.algorithm.length) { + assert_equals( + decapsulatedKey.algorithm.length, + config.algorithm.length, + 'Key length should be 256' + ); + } + if (config.algorithm.hash) { + assert_equals( + decapsulatedKey.algorithm.hash.name, + config.algorithm.hash, + 'Hash algorithm should match' + ); + } + }, algorithmName + + ' vector-based sampleCiphertext decapsulation with ' + + config.description); + }); + }); +} + +async function testAESOperation(key1, key2, algorithm) { + var plaintext = new Uint8Array([ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + ]); + + if (algorithm.name === 'AES-GCM') { + var iv = crypto.getRandomValues(new Uint8Array(12)); + var params = { name: 'AES-GCM', iv: iv }; + + var ciphertext1 = await crypto.subtle.encrypt(params, key1, plaintext); + var ciphertext2 = await crypto.subtle.encrypt(params, key2, plaintext); + + assert_true( + equalBuffers(ciphertext1, ciphertext2), + 'AES-GCM encryption should produce identical results' + ); + + var decrypted1 = await crypto.subtle.decrypt(params, key1, ciphertext1); + var decrypted2 = await crypto.subtle.decrypt(params, key2, ciphertext2); + + assert_true( + equalBuffers(decrypted1, plaintext), + 'AES-GCM decryption should work with key1' + ); + assert_true( + equalBuffers(decrypted2, plaintext), + 'AES-GCM decryption should work with key2' + ); + } else if (algorithm.name === 'AES-CBC') { + var iv = crypto.getRandomValues(new Uint8Array(16)); + var params = { name: 'AES-CBC', iv: iv }; + + var ciphertext1 = await crypto.subtle.encrypt(params, key1, plaintext); + var ciphertext2 = await crypto.subtle.encrypt(params, key2, plaintext); + + assert_true( + equalBuffers(ciphertext1, ciphertext2), + 'AES-CBC encryption should produce identical results' + ); + } else if (algorithm.name === 'AES-CTR') { + var counter = crypto.getRandomValues(new Uint8Array(16)); + var params = { name: 'AES-CTR', counter: counter, length: 128 }; + + var ciphertext1 = await crypto.subtle.encrypt(params, key1, plaintext); + var ciphertext2 = await crypto.subtle.encrypt(params, key2, plaintext); + + assert_true( + equalBuffers(ciphertext1, ciphertext2), + 'AES-CTR encryption should produce identical results' + ); + } +} + +async function testHMACOperation(key1, key2) { + var data = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + + var signature1 = await crypto.subtle.sign({ name: 'HMAC' }, key1, data); + var signature2 = await crypto.subtle.sign({ name: 'HMAC' }, key2, data); + + assert_true( + equalBuffers(signature1, signature2), + 'HMAC signatures should be identical' + ); + + var verified1 = await crypto.subtle.verify( + { name: 'HMAC' }, + key1, + signature1, + data + ); + var verified2 = await crypto.subtle.verify( + { name: 'HMAC' }, + key2, + signature2, + data + ); + + assert_true(verified1, 'HMAC verification should succeed with key1'); + assert_true(verified2, 'HMAC verification should succeed with key2'); +} + +// Helper function to compare two ArrayBuffers +function equalBuffers(a, b) { + if (a.byteLength !== b.byteLength) { + return false; + } + var aBytes = new Uint8Array(a); + var bBytes = new Uint8Array(b); + for (var i = 0; i < a.byteLength; i++) { + if (aBytes[i] !== bBytes[i]) { + return false; + } + } + return true; +} + +define_key_tests(); diff --git a/test/fixtures/wpt/WebCryptoAPI/encap_decap/ml_kem_encap_decap.js b/test/fixtures/wpt/WebCryptoAPI/encap_decap/ml_kem_encap_decap.js new file mode 100644 index 00000000000000..9167efa63f0ca3 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/encap_decap/ml_kem_encap_decap.js @@ -0,0 +1,410 @@ +// Test implementation for ML-KEM encapsulate and decapsulate operations + +function define_tests() { + var subtle = self.crypto.subtle; + + // Test data for all ML-KEM variants + var variants = ['ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024']; + + variants.forEach(function (algorithmName) { + var testVector = ml_kem_vectors[algorithmName]; + + // Test encapsulateBits operation + promise_test(async function (test) { + // Generate a key pair for testing + var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ + 'encapsulateBits', + 'decapsulateBits', + ]); + + // Test encapsulateBits + var encapsulatedBits = await subtle.encapsulateBits( + { name: algorithmName }, + keyPair.publicKey + ); + + assert_true( + encapsulatedBits instanceof Object, + 'encapsulateBits should return an object' + ); + assert_true( + encapsulatedBits.hasOwnProperty('sharedKey'), + 'Result should have sharedKey property' + ); + assert_true( + encapsulatedBits.hasOwnProperty('ciphertext'), + 'Result should have ciphertext property' + ); + assert_true( + encapsulatedBits.sharedKey instanceof ArrayBuffer, + 'sharedKey should be ArrayBuffer' + ); + assert_true( + encapsulatedBits.ciphertext instanceof ArrayBuffer, + 'ciphertext should be ArrayBuffer' + ); + + // Verify sharedKey length (should be 32 bytes for all ML-KEM variants) + assert_equals( + encapsulatedBits.sharedKey.byteLength, + 32, + 'Shared key should be 32 bytes' + ); + + // Verify ciphertext length based on algorithm variant + var expectedCiphertextLength; + switch (algorithmName) { + case 'ML-KEM-512': + expectedCiphertextLength = 768; + break; + case 'ML-KEM-768': + expectedCiphertextLength = 1088; + break; + case 'ML-KEM-1024': + expectedCiphertextLength = 1568; + break; + } + assert_equals( + encapsulatedBits.ciphertext.byteLength, + expectedCiphertextLength, + 'Ciphertext should be ' + + expectedCiphertextLength + + ' bytes for ' + + algorithmName + ); + }, algorithmName + ' encapsulateBits basic functionality'); + + // Test decapsulateBits operation + promise_test(async function (test) { + // Generate a key pair for testing + var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ + 'encapsulateBits', + 'decapsulateBits', + ]); + + // First encapsulate to get ciphertext + var encapsulatedBits = await subtle.encapsulateBits( + { name: algorithmName }, + keyPair.publicKey + ); + + // Then decapsulate using the private key + var decapsulatedBits = await subtle.decapsulateBits( + { name: algorithmName }, + keyPair.privateKey, + encapsulatedBits.ciphertext + ); + + assert_true( + decapsulatedBits instanceof ArrayBuffer, + 'decapsulateBits should return ArrayBuffer' + ); + assert_equals( + decapsulatedBits.byteLength, + 32, + 'Decapsulated bits should be 32 bytes' + ); + + // The decapsulated shared secret should match the original + assert_true( + equalBuffers(decapsulatedBits, encapsulatedBits.sharedKey), + 'Decapsulated shared secret should match original' + ); + }, algorithmName + ' decapsulateBits basic functionality'); + + // Test encapsulateKey operation + promise_test(async function (test) { + // Generate a key pair for testing + var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ + 'encapsulateKey', + 'decapsulateKey', + ]); + + // Test encapsulateKey with AES-GCM as the shared key algorithm + var encapsulatedKey = await subtle.encapsulateKey( + { name: algorithmName }, + keyPair.publicKey, + { name: 'AES-GCM', length: 256 }, + true, + ['encrypt', 'decrypt'] + ); + + assert_true( + encapsulatedKey instanceof Object, + 'encapsulateKey should return an object' + ); + assert_true( + encapsulatedKey.hasOwnProperty('sharedKey'), + 'Result should have sharedKey property' + ); + assert_true( + encapsulatedKey.hasOwnProperty('ciphertext'), + 'Result should have ciphertext property' + ); + assert_true( + encapsulatedKey.sharedKey instanceof CryptoKey, + 'sharedKey should be a CryptoKey' + ); + assert_true( + encapsulatedKey.ciphertext instanceof ArrayBuffer, + 'ciphertext should be ArrayBuffer' + ); + + // Verify the shared key properties + assert_equals( + encapsulatedKey.sharedKey.type, + 'secret', + 'Shared key should be secret type' + ); + assert_equals( + encapsulatedKey.sharedKey.algorithm.name, + 'AES-GCM', + 'Shared key algorithm should be AES-GCM' + ); + assert_equals( + encapsulatedKey.sharedKey.algorithm.length, + 256, + 'Shared key length should be 256' + ); + assert_true( + encapsulatedKey.sharedKey.extractable, + 'Shared key should be extractable as specified' + ); + assert_array_equals( + encapsulatedKey.sharedKey.usages, + ['encrypt', 'decrypt'], + 'Shared key should have correct usages' + ); + }, algorithmName + ' encapsulateKey basic functionality'); + + // Test decapsulateKey operation + promise_test(async function (test) { + // Generate a key pair for testing + var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ + 'encapsulateKey', + 'decapsulateKey', + ]); + + // First encapsulate to get ciphertext + var encapsulatedKey = await subtle.encapsulateKey( + { name: algorithmName }, + keyPair.publicKey, + { name: 'AES-GCM', length: 256 }, + true, + ['encrypt', 'decrypt'] + ); + + // Then decapsulate using the private key + var decapsulatedKey = await subtle.decapsulateKey( + { name: algorithmName }, + keyPair.privateKey, + encapsulatedKey.ciphertext, + { name: 'AES-GCM', length: 256 }, + true, + ['encrypt', 'decrypt'] + ); + + assert_true( + decapsulatedKey instanceof CryptoKey, + 'decapsulateKey should return a CryptoKey' + ); + assert_equals( + decapsulatedKey.type, + 'secret', + 'Decapsulated key should be secret type' + ); + assert_equals( + decapsulatedKey.algorithm.name, + 'AES-GCM', + 'Decapsulated key algorithm should be AES-GCM' + ); + assert_equals( + decapsulatedKey.algorithm.length, + 256, + 'Decapsulated key length should be 256' + ); + assert_true( + decapsulatedKey.extractable, + 'Decapsulated key should be extractable as specified' + ); + assert_array_equals( + decapsulatedKey.usages, + ['encrypt', 'decrypt'], + 'Decapsulated key should have correct usages' + ); + + // Extract both keys and verify they are identical + var originalKeyMaterial = await subtle.exportKey( + 'raw', + encapsulatedKey.sharedKey + ); + var decapsulatedKeyMaterial = await subtle.exportKey( + 'raw', + decapsulatedKey + ); + + assert_true( + equalBuffers(originalKeyMaterial, decapsulatedKeyMaterial), + 'Decapsulated key material should match original' + ); + }, algorithmName + ' decapsulateKey basic functionality'); + + // Test error cases for encapsulateBits + promise_test(async function (test) { + var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ + 'encapsulateBits', + 'decapsulateBits', + ]); + + // Test with wrong key type (private key instead of public) + await promise_rejects_dom( + test, + 'InvalidAccessError', + subtle.encapsulateBits({ name: algorithmName }, keyPair.privateKey), + 'encapsulateBits should reject private key' + ); + + // Test with wrong algorithm name + await promise_rejects_dom( + test, + 'InvalidAccessError', + subtle.encapsulateBits({ name: 'AES-GCM' }, keyPair.publicKey), + 'encapsulateBits should reject mismatched algorithm' + ); + }, algorithmName + ' encapsulateBits error cases'); + + // Test error cases for decapsulateBits + promise_test(async function (test) { + var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ + 'encapsulateBits', + 'decapsulateBits', + ]); + + var encapsulatedBits = await subtle.encapsulateBits( + { name: algorithmName }, + keyPair.publicKey + ); + + // Test with wrong key type (public key instead of private) + await promise_rejects_dom( + test, + 'InvalidAccessError', + subtle.decapsulateBits( + { name: algorithmName }, + keyPair.publicKey, + encapsulatedBits.ciphertext + ), + 'decapsulateBits should reject public key' + ); + + // Test with wrong algorithm name + await promise_rejects_dom( + test, + 'InvalidAccessError', + subtle.decapsulateBits( + { name: 'AES-GCM' }, + keyPair.privateKey, + encapsulatedBits.ciphertext + ), + 'decapsulateBits should reject mismatched algorithm' + ); + + // Test with invalid ciphertext + var invalidCiphertext = new Uint8Array(10); // Wrong size + await promise_rejects_dom( + test, + 'OperationError', + subtle.decapsulateBits( + { name: algorithmName }, + keyPair.privateKey, + invalidCiphertext + ), + 'decapsulateBits should reject invalid ciphertext' + ); + }, algorithmName + ' decapsulateBits error cases'); + + // Test error cases for encapsulateKey + promise_test(async function (test) { + var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ + 'encapsulateKey', + 'decapsulateKey', + ]); + + // Test with key without encapsulateKey usage + var wrongKeyPair = await subtle.generateKey( + { name: algorithmName }, + false, + ['decapsulateKey'] // Missing encapsulateKey usage + ); + + await promise_rejects_dom( + test, + 'InvalidAccessError', + subtle.encapsulateKey( + { name: algorithmName }, + wrongKeyPair.publicKey, + { name: 'AES-GCM', length: 256 }, + true, + ['encrypt', 'decrypt'] + ), + 'encapsulateKey should reject key without encapsulateKey usage' + ); + }, algorithmName + ' encapsulateKey error cases'); + + // Test error cases for decapsulateKey + promise_test(async function (test) { + var keyPair = await subtle.generateKey({ name: algorithmName }, false, [ + 'encapsulateKey', + 'decapsulateKey', + ]); + + var encapsulatedKey = await subtle.encapsulateKey( + { name: algorithmName }, + keyPair.publicKey, + { name: 'AES-GCM', length: 256 }, + true, + ['encrypt', 'decrypt'] + ); + + // Test with key without decapsulateKey usage + var wrongKeyPair = await subtle.generateKey( + { name: algorithmName }, + false, + ['encapsulateKey'] // Missing decapsulateKey usage + ); + + await promise_rejects_dom( + test, + 'InvalidAccessError', + subtle.decapsulateKey( + { name: algorithmName }, + wrongKeyPair.privateKey, + encapsulatedKey.ciphertext, + { name: 'AES-GCM', length: 256 }, + true, + ['encrypt', 'decrypt'] + ), + 'decapsulateKey should reject key without decapsulateKey usage' + ); + }, algorithmName + ' decapsulateKey error cases'); + }); +} + +// Helper function to compare two ArrayBuffers +function equalBuffers(a, b) { + if (a.byteLength !== b.byteLength) { + return false; + } + var aBytes = new Uint8Array(a); + var bBytes = new Uint8Array(b); + for (var i = 0; i < a.byteLength; i++) { + if (aBytes[i] !== bBytes[i]) { + return false; + } + } + return true; +} + +function run_test() { + define_tests(); +} diff --git a/test/fixtures/wpt/WebCryptoAPI/encap_decap/ml_kem_vectors.js b/test/fixtures/wpt/WebCryptoAPI/encap_decap/ml_kem_vectors.js new file mode 100644 index 00000000000000..3e04fda6a3b3da --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/encap_decap/ml_kem_vectors.js @@ -0,0 +1,659 @@ +var ml_kem_vectors = {}; + +// ML-KEM-512 test vectors +ml_kem_vectors['ML-KEM-512'] = { + // 800-byte publicKey + publicKey: new Uint8Array([ + 0xce, 0xcb, 0x75, 0x1f, 0x32, 0x67, 0x09, 0xb4, 0x9e, 0x14, 0xca, 0xa4, + 0xbe, 0x30, 0x95, 0xee, 0xe9, 0x85, 0x58, 0x86, 0x2b, 0x83, 0xb9, 0x33, + 0x56, 0x86, 0x4e, 0xad, 0x05, 0xcb, 0x38, 0x26, 0x95, 0x4c, 0xdb, 0xb2, + 0x1d, 0xc4, 0x52, 0x44, 0x60, 0x36, 0xdd, 0x77, 0x82, 0x30, 0x09, 0x4f, + 0xe3, 0xb8, 0x14, 0xc7, 0x99, 0x8f, 0x94, 0x45, 0x82, 0xd3, 0x89, 0xcc, + 0xc7, 0x38, 0x97, 0x4e, 0x39, 0x49, 0x6d, 0xb5, 0x34, 0xd4, 0xdb, 0x78, + 0x4b, 0x65, 0x44, 0x6e, 0xa9, 0xbc, 0x59, 0xe8, 0x96, 0xa3, 0x39, 0xbe, + 0x6c, 0x13, 0x46, 0x3a, 0xb7, 0x4a, 0xe2, 0x02, 0x8a, 0x12, 0x69, 0x5c, + 0x5b, 0x12, 0xc1, 0xc9, 0xd5, 0x70, 0x06, 0x58, 0x19, 0xf6, 0x82, 0x3b, + 0x53, 0x3b, 0x29, 0xbb, 0xc8, 0x93, 0x8b, 0xc0, 0xaa, 0x74, 0x52, 0x77, + 0xe7, 0x33, 0x57, 0xd9, 0x52, 0x5c, 0xec, 0x0c, 0xaf, 0xe1, 0xf0, 0x8a, + 0x1b, 0x9b, 0x11, 0xa2, 0xf8, 0xaa, 0xc1, 0xf5, 0xab, 0xb2, 0xa6, 0xb4, + 0x5f, 0x10, 0x95, 0x69, 0xb2, 0x0c, 0xfe, 0xba, 0xaf, 0x32, 0xb4, 0x90, + 0x64, 0x4c, 0x18, 0x84, 0xd7, 0x7f, 0xe3, 0x88, 0xa1, 0x20, 0xb0, 0x85, + 0x14, 0xc9, 0x6e, 0xeb, 0xb3, 0xbc, 0x0c, 0xd9, 0x77, 0x06, 0x76, 0x9f, + 0x70, 0xf0, 0x48, 0x47, 0x09, 0x8a, 0xbf, 0x62, 0x82, 0xac, 0x00, 0x2f, + 0xa0, 0x15, 0x84, 0xab, 0x96, 0x76, 0x0b, 0xdc, 0x46, 0x57, 0x09, 0x3b, + 0xb6, 0x97, 0x9e, 0x0a, 0xf8, 0x54, 0x0b, 0xb7, 0x20, 0x72, 0x2a, 0x6c, + 0xbb, 0xb8, 0x48, 0x1f, 0xd0, 0x36, 0xf5, 0xd3, 0x64, 0xc5, 0x64, 0xc9, + 0x6f, 0x4a, 0xa6, 0xbe, 0xb2, 0x40, 0x86, 0xb3, 0xb1, 0x04, 0xe0, 0xaf, + 0x59, 0x10, 0x63, 0x8b, 0x66, 0x7d, 0x7d, 0x29, 0xb3, 0x2e, 0x93, 0xad, + 0xdb, 0xa0, 0x54, 0x37, 0x82, 0x38, 0x58, 0xf7, 0xcf, 0xc6, 0x9a, 0xcd, + 0xaa, 0x94, 0xba, 0x74, 0x90, 0x29, 0x73, 0xb8, 0x8a, 0x9b, 0x08, 0xce, + 0x2f, 0xb1, 0x09, 0xb2, 0xa1, 0x6d, 0x31, 0xf1, 0x0d, 0x8b, 0xb4, 0x52, + 0xa0, 0x89, 0x96, 0xb9, 0x54, 0x78, 0x49, 0x90, 0x8a, 0x61, 0xba, 0x0d, + 0x92, 0xf3, 0x6f, 0x46, 0x7a, 0xa5, 0x22, 0x4c, 0xb9, 0x2c, 0xaa, 0x17, + 0xab, 0xc9, 0x37, 0x84, 0x2a, 0x4f, 0xac, 0xf6, 0x4a, 0xf4, 0xe2, 0x81, + 0x12, 0x78, 0x49, 0x6d, 0xac, 0xa6, 0xe1, 0xa9, 0x89, 0x8a, 0x5c, 0x02, + 0x8e, 0xa4, 0x6a, 0x64, 0xe5, 0x67, 0x84, 0xc5, 0xbe, 0x7e, 0xf9, 0x39, + 0x60, 0xa9, 0x10, 0xd7, 0x01, 0x1e, 0x03, 0xb1, 0x7c, 0xaf, 0x42, 0xce, + 0x3e, 0xc2, 0x13, 0x75, 0x96, 0x93, 0x32, 0x0b, 0x2c, 0x96, 0xb2, 0x2a, + 0xef, 0x80, 0x10, 0xa3, 0x82, 0x5d, 0x60, 0xbc, 0xc0, 0xe9, 0x15, 0x1a, + 0x0f, 0xa4, 0x3d, 0xf1, 0x0c, 0xa3, 0xa3, 0xcc, 0x6b, 0x6d, 0x6b, 0xb6, + 0xa2, 0xf6, 0x03, 0x5f, 0xe3, 0xc0, 0x23, 0x62, 0xae, 0x07, 0xe5, 0xa9, + 0x79, 0x28, 0x69, 0x24, 0xd0, 0x5a, 0x54, 0xc5, 0x13, 0x7b, 0x46, 0xb3, + 0x99, 0x85, 0x74, 0xa7, 0x3c, 0xc0, 0x09, 0x87, 0x5d, 0xd5, 0x66, 0xbe, + 0xae, 0x6b, 0x4d, 0x47, 0xa2, 0x79, 0xf5, 0x85, 0xaf, 0x8e, 0xc5, 0x7c, + 0xfc, 0xa2, 0x81, 0x16, 0xa9, 0x54, 0x03, 0xfa, 0x6e, 0x49, 0xe7, 0xa4, + 0x11, 0x16, 0x89, 0xf2, 0x34, 0x0f, 0xe9, 0x08, 0x8e, 0x07, 0x43, 0xa2, + 0x6e, 0x06, 0xbc, 0x6c, 0x54, 0xb0, 0x12, 0x61, 0x76, 0x69, 0x05, 0xcf, + 0xb2, 0x78, 0x5e, 0xf5, 0xd5, 0xc9, 0x86, 0xec, 0xc9, 0xd7, 0x4c, 0x66, + 0xef, 0xec, 0x57, 0x69, 0xa9, 0x2c, 0x8a, 0x03, 0x48, 0x90, 0x30, 0x0f, + 0x2b, 0x7c, 0x7d, 0x20, 0xa8, 0x0f, 0xfb, 0x73, 0x1c, 0xe4, 0x19, 0x2c, + 0xec, 0x02, 0x1a, 0xd9, 0xb9, 0xac, 0x25, 0xdc, 0x99, 0x46, 0x00, 0x4c, + 0xcd, 0xcc, 0xa5, 0xf4, 0xb2, 0x95, 0x81, 0xf2, 0x7e, 0xb3, 0xe7, 0x24, + 0x50, 0x4a, 0xc3, 0x6e, 0x95, 0xae, 0xb7, 0xbc, 0x49, 0xc6, 0x5a, 0x78, + 0x3a, 0xb8, 0xc2, 0xd1, 0x69, 0xcc, 0xc0, 0x11, 0x3b, 0x18, 0x26, 0x30, + 0x7e, 0x51, 0xb3, 0xc5, 0x73, 0x07, 0xa6, 0x8a, 0xc3, 0xe6, 0x18, 0xba, + 0x22, 0x39, 0x28, 0xd6, 0x33, 0x61, 0x51, 0x28, 0x92, 0xbf, 0x93, 0xb1, + 0x52, 0x68, 0xae, 0x54, 0xea, 0xc4, 0x4f, 0x62, 0x1d, 0x82, 0x94, 0x39, + 0xe2, 0x98, 0x7c, 0x1b, 0xea, 0x13, 0x26, 0x92, 0x6a, 0xb1, 0x1c, 0x59, + 0x11, 0x47, 0x7c, 0x7b, 0xeb, 0x28, 0x2a, 0xe8, 0x81, 0x0b, 0x55, 0x14, + 0x53, 0x80, 0x28, 0xb8, 0x58, 0x8b, 0x1c, 0xa5, 0x91, 0x4e, 0x55, 0x9e, + 0x68, 0x32, 0x5d, 0x5f, 0x94, 0x87, 0x83, 0x73, 0x3f, 0xfc, 0x8b, 0xb4, + 0x8c, 0xd9, 0x52, 0xf8, 0x74, 0x5f, 0x76, 0xc2, 0x63, 0x9a, 0x87, 0x54, + 0x10, 0x47, 0x1e, 0x83, 0x82, 0x31, 0x6d, 0x22, 0x26, 0x16, 0x32, 0xb1, + 0xa1, 0x78, 0x09, 0xd5, 0x8b, 0xbb, 0x75, 0xd7, 0x8b, 0xa2, 0x99, 0xcf, + 0xde, 0x2a, 0x73, 0x0f, 0x80, 0x91, 0xdc, 0x44, 0xb8, 0xaa, 0x73, 0x69, + 0x55, 0xfa, 0x23, 0xb8, 0x16, 0xb1, 0xd7, 0x78, 0x4d, 0x97, 0xab, 0xcb, + 0x0c, 0xf4, 0xcb, 0xb7, 0xc8, 0x36, 0x4e, 0xf1, 0x2a, 0x82, 0xb0, 0x09, + 0x10, 0x3c, 0x8f, 0x7a, 0x76, 0xc6, 0xac, 0x08, 0x6a, 0xe1, 0x0a, 0x3e, + 0x6b, 0x06, 0x39, 0xcb, 0x35, 0xce, 0x10, 0xc3, 0x1f, 0xaa, 0xaa, 0x26, + 0xfc, 0x22, 0xb9, 0xd5, 0x12, 0xcc, 0xa8, 0x48, 0x0a, 0x61, 0xac, 0x3a, + 0xa1, 0x87, 0xbf, 0xea, 0x79, 0x11, 0x7d, 0xfb, 0xc4, 0xfe, 0x0b, 0x4f, + 0x94, 0x57, 0xd8, 0x7b, 0xa4, 0x91, 0x4e, 0xe5, 0x5a, 0x4b, 0xaa, 0x94, + 0x6e, 0x91, 0x55, 0xe9, 0x9b, 0xae, 0xac, 0xe9, 0x52, 0x2c, 0xc6, 0x4b, + 0xee, 0x7b, 0xd7, 0xfa, 0x45, 0xeb, 0x2f, 0x6b, + ]), + // 64-byte privateSeed + privateSeed: new Uint8Array([ + 0x3e, 0x42, 0x62, 0xca, 0xd1, 0x44, 0x02, 0x6d, 0xe9, 0xbd, 0x35, 0xbf, + 0x20, 0x3f, 0xfb, 0x40, 0x26, 0x3c, 0x8c, 0x76, 0x5d, 0x05, 0xd2, 0xa4, + 0xd0, 0x0a, 0x8a, 0xe9, 0x25, 0x07, 0xd2, 0xd2, 0xc5, 0x60, 0xb8, 0x43, + 0x5a, 0x05, 0x4d, 0x81, 0x6e, 0x5f, 0x25, 0x35, 0xa3, 0xdf, 0x91, 0x83, + 0x3c, 0xca, 0xd2, 0x63, 0xe5, 0x8e, 0x3c, 0x34, 0x55, 0x5c, 0xd8, 0xc5, + 0x73, 0x25, 0xad, 0x9d, + ]), + // 768-byte sampleCiphertext + sampleCiphertext: new Uint8Array([ + 0x0e, 0x48, 0x87, 0x58, 0xdc, 0xd4, 0x55, 0x52, 0x56, 0x5b, 0xec, 0xe5, + 0xb8, 0xbd, 0xa4, 0x52, 0x35, 0x44, 0xde, 0x14, 0xee, 0xd1, 0x3f, 0xec, + 0x29, 0xcf, 0x92, 0x60, 0x16, 0x15, 0x89, 0x13, 0x14, 0x32, 0x24, 0xdb, + 0x55, 0x5a, 0x2d, 0x6d, 0x42, 0xc2, 0xce, 0x30, 0xf6, 0x3b, 0x72, 0x34, + 0xb8, 0x25, 0xab, 0x11, 0xb6, 0xb1, 0x0b, 0xba, 0xc1, 0x98, 0x35, 0xc2, + 0x3c, 0xac, 0x07, 0xe3, 0xb3, 0x7f, 0xed, 0x08, 0xa1, 0xeb, 0x88, 0x61, + 0x99, 0xee, 0x2d, 0xb9, 0x5e, 0x01, 0x35, 0xaf, 0x1c, 0x21, 0xd3, 0x75, + 0xed, 0xd0, 0xc1, 0x34, 0x66, 0x17, 0xb6, 0x6c, 0xfc, 0xd9, 0xcd, 0xa8, + 0x5a, 0x80, 0x28, 0xda, 0x74, 0x5d, 0x9d, 0x36, 0x53, 0xfc, 0x5b, 0x80, + 0xc6, 0xd2, 0x9b, 0x4c, 0xd9, 0xb0, 0x2d, 0x6c, 0x5a, 0xc8, 0xe7, 0xc0, + 0x27, 0xa7, 0x02, 0x58, 0x57, 0x31, 0x98, 0xbc, 0x72, 0x40, 0x4a, 0x31, + 0xde, 0x1f, 0x44, 0x38, 0x54, 0xe7, 0xbe, 0xcb, 0x3b, 0xcf, 0x39, 0x0a, + 0x6f, 0xe7, 0xc8, 0x6c, 0x3a, 0x0b, 0x14, 0x9e, 0x51, 0xa5, 0x10, 0x3b, + 0x2d, 0xd8, 0x4b, 0x96, 0xd2, 0x0d, 0x1f, 0x3b, 0x1a, 0x53, 0x08, 0xdd, + 0x94, 0x11, 0xfa, 0x87, 0x75, 0x4d, 0x7d, 0x85, 0x72, 0xad, 0x58, 0x36, + 0x27, 0xdb, 0x9a, 0xa9, 0x8d, 0x2f, 0xe0, 0x9b, 0x6f, 0xdd, 0xca, 0x3c, + 0xa8, 0xf9, 0x4e, 0x64, 0x3b, 0x56, 0xd9, 0x2b, 0xab, 0xaf, 0x10, 0x5e, + 0x52, 0xba, 0x70, 0x82, 0xe3, 0x34, 0xf7, 0xb8, 0xe4, 0x86, 0x6f, 0x45, + 0xf4, 0x15, 0xa1, 0xd4, 0x69, 0x01, 0xba, 0x93, 0x2c, 0x29, 0x8d, 0xcd, + 0xb0, 0xe9, 0x64, 0xd1, 0x8a, 0x0b, 0x72, 0x5a, 0xd0, 0x58, 0xc2, 0xd5, + 0xea, 0x72, 0x13, 0xff, 0x7f, 0x44, 0xaf, 0xea, 0xcf, 0x1b, 0x6a, 0x10, + 0x29, 0xfd, 0x93, 0xce, 0x50, 0xa6, 0xb3, 0x4b, 0xf5, 0x1e, 0x83, 0x23, + 0xc7, 0xda, 0x58, 0x60, 0x06, 0xd3, 0xc1, 0xf7, 0x8c, 0x98, 0xca, 0x79, + 0xcc, 0xbc, 0xff, 0x1c, 0x14, 0xa0, 0x30, 0x94, 0x96, 0xbf, 0xb4, 0xf4, + 0xbc, 0x24, 0x40, 0x2a, 0x47, 0x91, 0x2f, 0x98, 0x00, 0x5d, 0xef, 0xbc, + 0x08, 0x2b, 0x96, 0xc2, 0x06, 0xdc, 0xa0, 0x2c, 0x93, 0x27, 0xd7, 0xa4, + 0x16, 0x6b, 0x9c, 0xcf, 0xea, 0x2c, 0x45, 0x32, 0x6a, 0x98, 0xa1, 0xab, + 0x84, 0xdc, 0xac, 0x0e, 0xa3, 0x5a, 0x2b, 0x1a, 0x2c, 0x40, 0x1b, 0x91, + 0x1c, 0xdf, 0x27, 0x65, 0x23, 0x38, 0xe7, 0x4b, 0xea, 0xfa, 0xb4, 0xd9, + 0x45, 0xc3, 0xf1, 0x3c, 0xa2, 0x96, 0x50, 0x7c, 0x87, 0xf7, 0x3e, 0x34, + 0x8b, 0xb4, 0x43, 0xb7, 0xfa, 0x7e, 0xc0, 0x5f, 0xa0, 0xe3, 0x5b, 0x9f, + 0x19, 0x1e, 0xc8, 0xba, 0xde, 0x96, 0x60, 0x92, 0x74, 0x8c, 0xda, 0x72, + 0x9e, 0x25, 0xa4, 0xcf, 0x8d, 0x9f, 0x8f, 0xc0, 0x6d, 0xaf, 0x4a, 0x60, + 0xf3, 0xb9, 0x85, 0x30, 0x28, 0x2e, 0xab, 0xbf, 0x57, 0x67, 0x4d, 0x34, + 0xf9, 0x6c, 0xf5, 0x37, 0x63, 0x96, 0x95, 0x35, 0x78, 0x25, 0x11, 0x1e, + 0x0c, 0xa9, 0xaf, 0xc0, 0x4a, 0x78, 0x9d, 0xf2, 0x83, 0xb1, 0x25, 0xd9, + 0xf9, 0xf1, 0xb5, 0x59, 0x27, 0xc9, 0x3b, 0xd4, 0x8e, 0x1b, 0xcc, 0x62, + 0xf3, 0x6e, 0x76, 0x28, 0xea, 0x8b, 0xdd, 0xf4, 0x48, 0xae, 0x0c, 0xe2, + 0x98, 0x44, 0x2f, 0x1a, 0x8c, 0x8d, 0x31, 0xdc, 0x23, 0xb9, 0x68, 0x32, + 0x60, 0x3c, 0xf2, 0x03, 0x6f, 0xba, 0xe9, 0x6f, 0xc0, 0xfb, 0xd2, 0x57, + 0x0a, 0xa5, 0xd6, 0x51, 0x7c, 0xc3, 0x52, 0xdd, 0xdf, 0xa9, 0x44, 0x52, + 0x4a, 0x4c, 0xa6, 0xc5, 0xc7, 0x6d, 0xb9, 0x8c, 0xc7, 0x96, 0xc8, 0xf9, + 0xcf, 0xe3, 0x92, 0x74, 0x8c, 0xb3, 0xb2, 0x2e, 0xaf, 0x58, 0x43, 0x45, + 0x77, 0x29, 0xa7, 0xb6, 0xa8, 0x01, 0xca, 0x0c, 0xa9, 0xb4, 0x65, 0x6a, + 0xbc, 0x9d, 0xf0, 0x91, 0x1a, 0x3d, 0x1a, 0x11, 0xc8, 0x5b, 0xe1, 0xf4, + 0x13, 0x60, 0xe8, 0x5a, 0x47, 0xe7, 0x66, 0xdc, 0xd9, 0x9c, 0xd0, 0xa3, + 0x5f, 0x1f, 0xa6, 0xc0, 0x94, 0x58, 0x05, 0xc8, 0x46, 0xd2, 0xa0, 0x86, + 0x55, 0x36, 0x34, 0x01, 0xae, 0x98, 0x86, 0xd4, 0x26, 0xc3, 0xa1, 0x5a, + 0xef, 0xd0, 0x98, 0x4d, 0x5a, 0x12, 0x8c, 0x03, 0x18, 0xf1, 0x81, 0x8d, + 0x73, 0x4f, 0x62, 0x4b, 0xc6, 0xe7, 0x3a, 0x5d, 0x42, 0xf8, 0x13, 0x29, + 0x76, 0x4c, 0x3b, 0x51, 0x86, 0xe7, 0xd6, 0x87, 0x2e, 0x9e, 0x3e, 0x22, + 0xde, 0x4f, 0xae, 0xf9, 0x6a, 0xe1, 0xa7, 0x72, 0xfa, 0x1e, 0x8f, 0xc1, + 0x95, 0xe8, 0x60, 0x1d, 0xd5, 0x46, 0x8a, 0xcb, 0x80, 0x61, 0x9c, 0x65, + 0x8e, 0x06, 0xe7, 0x89, 0xfa, 0xb5, 0xfd, 0x68, 0x8f, 0x8c, 0x08, 0xc3, + 0x6a, 0xc8, 0x84, 0x13, 0x52, 0x32, 0xce, 0x83, 0x2e, 0x68, 0xa0, 0xc1, + 0x5f, 0x01, 0x65, 0xb8, 0x4c, 0x38, 0x82, 0xaf, 0xac, 0x0b, 0xbe, 0x4e, + 0xef, 0x7a, 0x42, 0xde, 0x92, 0x17, 0x4a, 0xf0, 0xf6, 0x85, 0xfe, 0x47, + 0xba, 0xf2, 0xbc, 0x79, 0x7c, 0xed, 0x19, 0xdf, 0x18, 0x08, 0x72, 0x8a, + 0xce, 0x57, 0x86, 0xcf, 0xc5, 0x54, 0x17, 0x19, 0xab, 0x0c, 0xeb, 0xa5, + 0x44, 0x33, 0x5c, 0x1f, 0x02, 0xec, 0x8b, 0x80, 0xdd, 0xe7, 0x50, 0x74, + 0x97, 0x43, 0xa8, 0xa3, 0xb9, 0x1a, 0x8e, 0x1d, 0x21, 0x97, 0x95, 0x6c, + 0x96, 0xa0, 0x2d, 0xc5, 0x1b, 0xad, 0xed, 0x9d, 0x88, 0x46, 0x89, 0x9d, + 0xbd, 0x4a, 0xc5, 0x57, 0xa7, 0x4c, 0x4e, 0x78, 0x43, 0xa4, 0xc3, 0x43, + 0x11, 0x32, 0xde, 0xaf, 0xa3, 0xf4, 0x18, 0xd7, 0xc3, 0x9d, 0x52, 0x76, + ]), + // 32-byte expectedSharedSecret + expectedSharedSecret: new Uint8Array([ + 0x6b, 0x15, 0xad, 0xd5, 0xb3, 0x66, 0xb2, 0x2c, 0x66, 0x8a, 0x1d, 0x81, + 0x90, 0x1d, 0x2e, 0xe2, 0x11, 0x33, 0x03, 0xb6, 0xaf, 0xa8, 0x2e, 0xaf, + 0x67, 0x64, 0xdb, 0xea, 0xd7, 0x66, 0xb8, 0xfc, + ]), +}; + +// ML-KEM-768 test vectors +ml_kem_vectors['ML-KEM-768'] = { + // 1184-byte publicKey + publicKey: new Uint8Array([ + 0x0f, 0x61, 0x02, 0x18, 0x60, 0x7b, 0xac, 0x16, 0x36, 0xd1, 0x2a, 0x24, + 0x50, 0x79, 0x65, 0xbc, 0x4b, 0x6f, 0x39, 0x75, 0x69, 0x9e, 0x24, 0xba, + 0x48, 0x9a, 0xb0, 0x0e, 0xb8, 0xbb, 0x94, 0xc4, 0x16, 0xe0, 0x9b, 0x5b, + 0x3c, 0x22, 0x05, 0xda, 0x71, 0xa4, 0x0a, 0xf3, 0x8b, 0x10, 0x95, 0xb9, + 0x98, 0xb7, 0x34, 0x46, 0x2a, 0x0c, 0xdf, 0x33, 0x7b, 0xe7, 0x85, 0x25, + 0xfb, 0xd9, 0x84, 0x54, 0x7a, 0x98, 0x1e, 0x11, 0x9a, 0x10, 0xa1, 0x9b, + 0xb6, 0x22, 0x21, 0xf7, 0x17, 0x60, 0xf4, 0x71, 0x1b, 0x3d, 0x88, 0x31, + 0x7e, 0xf7, 0x83, 0x84, 0xd5, 0x20, 0x28, 0xa9, 0x49, 0x77, 0xa7, 0x59, + 0x96, 0x10, 0xb3, 0x4b, 0xc3, 0x39, 0x4b, 0x90, 0x9c, 0xcc, 0x3a, 0xbf, + 0x62, 0xfb, 0xc2, 0xcc, 0x66, 0xae, 0xc6, 0x17, 0xcd, 0xc9, 0x09, 0x17, + 0xc1, 0x80, 0xba, 0x14, 0x81, 0x68, 0x64, 0xf5, 0x41, 0xc4, 0x3a, 0x1f, + 0x29, 0x98, 0x77, 0xfa, 0x28, 0x4a, 0xca, 0x65, 0x5b, 0xd5, 0xa7, 0xb5, + 0xda, 0x3b, 0x77, 0xe4, 0x86, 0x96, 0xbf, 0xf7, 0x25, 0x25, 0x10, 0x59, + 0x34, 0x26, 0x9f, 0xef, 0x4c, 0x0b, 0xb4, 0x83, 0xce, 0x3d, 0x8c, 0x12, + 0x6f, 0xa4, 0xc0, 0xe4, 0x4a, 0x18, 0x1f, 0x97, 0x31, 0xbe, 0x18, 0x39, + 0xad, 0x08, 0x95, 0xe2, 0x7b, 0x1b, 0xf2, 0xe5, 0x89, 0xf3, 0x08, 0x60, + 0x6c, 0x50, 0xc5, 0x2d, 0x2c, 0x0c, 0x15, 0x78, 0x58, 0x88, 0x65, 0x5e, + 0x72, 0x18, 0x25, 0xd1, 0xa4, 0xb5, 0x25, 0x65, 0x51, 0x85, 0x59, 0xc3, + 0xf2, 0xa7, 0xb4, 0xb5, 0x86, 0x18, 0xe6, 0xe6, 0x91, 0x49, 0xb0, 0x29, + 0x62, 0x21, 0x73, 0x96, 0x89, 0x7e, 0xb7, 0x42, 0x12, 0xb1, 0x07, 0x0d, + 0x9f, 0xb0, 0x9d, 0x0c, 0xf3, 0x93, 0x75, 0x08, 0x9b, 0xf3, 0x25, 0x1e, + 0xf9, 0x92, 0xb2, 0x55, 0xb1, 0x5b, 0x83, 0xc9, 0xb4, 0x75, 0x15, 0x1b, + 0x93, 0x22, 0x83, 0xfc, 0xd9, 0x43, 0xee, 0x7a, 0x2e, 0x7c, 0xb2, 0x48, + 0xdf, 0xb8, 0x32, 0x5d, 0xc0, 0xc7, 0x0d, 0x55, 0x71, 0x31, 0xcc, 0x69, + 0x66, 0x46, 0xa2, 0x31, 0x75, 0x5b, 0xe2, 0x0a, 0x9c, 0xee, 0x44, 0x15, + 0xde, 0x08, 0x5d, 0xf3, 0xa4, 0x16, 0x65, 0x56, 0x0a, 0x59, 0xc1, 0x5a, + 0x95, 0x60, 0x87, 0x96, 0x96, 0xc0, 0xbb, 0x34, 0x4a, 0x27, 0x87, 0x91, + 0x6c, 0xb7, 0x77, 0x3a, 0xf0, 0x5c, 0x65, 0xbb, 0x79, 0xcd, 0xf9, 0x24, + 0x75, 0x1b, 0xcb, 0x4d, 0x8a, 0x20, 0xae, 0x59, 0xa6, 0x09, 0xc1, 0x58, + 0xb1, 0x41, 0x9c, 0x83, 0x64, 0x9a, 0x74, 0xe1, 0x7e, 0x69, 0x76, 0x5a, + 0xd4, 0xf5, 0x28, 0xac, 0x66, 0xc9, 0x81, 0x19, 0xc6, 0x20, 0xa3, 0x18, + 0xc8, 0x17, 0x98, 0x14, 0xc2, 0x57, 0x58, 0x43, 0x2a, 0x5c, 0xb6, 0x73, + 0x4e, 0x31, 0xa0, 0x2a, 0xa9, 0xc8, 0xba, 0x14, 0x88, 0xa1, 0x1a, 0x9c, + 0xf3, 0x69, 0x29, 0xe2, 0x12, 0x8d, 0xb8, 0x76, 0x6d, 0x95, 0xb2, 0xab, + 0x22, 0xb1, 0x15, 0x5a, 0x22, 0x53, 0xe4, 0x27, 0x7d, 0xc7, 0x80, 0xb0, + 0x10, 0xe5, 0x9a, 0x42, 0xea, 0x95, 0xc6, 0xa9, 0xa0, 0xd6, 0xf9, 0x45, + 0xd5, 0x73, 0x45, 0xe5, 0x55, 0xc9, 0xf3, 0x39, 0x80, 0x8a, 0xe0, 0x0a, + 0xa5, 0x47, 0x5e, 0xc6, 0xc4, 0x52, 0x6b, 0xb0, 0x10, 0xfc, 0xac, 0x24, + 0x47, 0x5a, 0x21, 0x8a, 0x75, 0x8e, 0x62, 0xf9, 0x20, 0x56, 0x77, 0x11, + 0xc0, 0x38, 0x19, 0x6c, 0xd0, 0x37, 0xab, 0xb5, 0x7a, 0xd1, 0x32, 0xad, + 0x62, 0x2a, 0x2e, 0x3e, 0x39, 0x61, 0x7c, 0xf3, 0x66, 0xa3, 0x98, 0x56, + 0x4f, 0x31, 0xad, 0xb5, 0x40, 0x5f, 0xf6, 0xa9, 0x20, 0xc5, 0x32, 0x6e, + 0xc7, 0x26, 0xa3, 0x97, 0xfc, 0x11, 0xcf, 0x79, 0x25, 0x9e, 0x48, 0x62, + 0xe6, 0xd3, 0x39, 0x48, 0x29, 0x9e, 0x55, 0xf5, 0x68, 0x93, 0xea, 0xcd, + 0x10, 0xdc, 0x9f, 0x89, 0x98, 0x47, 0xac, 0x12, 0x7c, 0xb8, 0xb5, 0x52, + 0x7c, 0xaa, 0x9e, 0x8c, 0xf4, 0xaf, 0x1b, 0xf5, 0xc5, 0x06, 0x01, 0x4c, + 0x76, 0x05, 0x8b, 0x1e, 0xd1, 0x0f, 0xa0, 0xf6, 0x09, 0xb7, 0x78, 0xaa, + 0x26, 0xca, 0xcc, 0x3b, 0xb0, 0x3e, 0x04, 0xb4, 0x9e, 0x99, 0xfa, 0x7a, + 0xc0, 0x33, 0x0e, 0xf2, 0x92, 0x55, 0x38, 0x80, 0x4e, 0xbc, 0x24, 0x53, + 0x00, 0x03, 0xcf, 0x08, 0x17, 0x3a, 0x4b, 0x5a, 0x78, 0x7b, 0xcb, 0x3b, + 0xb0, 0x6b, 0x6b, 0x7d, 0xe1, 0x7a, 0x7a, 0xd7, 0x4b, 0xc3, 0x12, 0x5b, + 0x9f, 0xa0, 0xcb, 0x46, 0x55, 0x0c, 0xfd, 0xc9, 0xa9, 0xa8, 0x40, 0x0a, + 0x8f, 0xe5, 0x1f, 0x9f, 0x39, 0xa2, 0x8a, 0xa2, 0xa7, 0x52, 0xc1, 0x61, + 0x19, 0xf9, 0x25, 0xe4, 0xdb, 0x6a, 0x4a, 0x37, 0xb2, 0x6e, 0x85, 0xc7, + 0x80, 0x22, 0xb8, 0x95, 0x2b, 0x30, 0x59, 0x98, 0x33, 0xbf, 0x18, 0x96, + 0xba, 0x1a, 0x16, 0xfd, 0xb7, 0x1e, 0x4a, 0x30, 0x31, 0x05, 0x85, 0x00, + 0xc8, 0x5a, 0x05, 0xfd, 0x36, 0xb9, 0x97, 0x41, 0xca, 0xc7, 0x90, 0x24, + 0x3a, 0xf9, 0x4c, 0xfb, 0xe2, 0x5d, 0xec, 0x58, 0x08, 0xfa, 0x43, 0xcf, + 0xc7, 0x92, 0xa9, 0xfc, 0xc1, 0xad, 0xf9, 0x62, 0x07, 0x98, 0x32, 0x89, + 0x70, 0x49, 0xb9, 0x99, 0x9a, 0x71, 0x85, 0x72, 0x88, 0xa0, 0xea, 0x84, + 0x23, 0xe1, 0x7e, 0x1d, 0x50, 0xc8, 0xa5, 0x6a, 0x97, 0xfb, 0xfc, 0x0c, + 0xa4, 0x19, 0x5f, 0xc9, 0xd2, 0x0d, 0x6b, 0x7b, 0xbf, 0x62, 0x55, 0x91, + 0xa6, 0x85, 0x8f, 0x75, 0xca, 0x79, 0x1b, 0x65, 0x57, 0x58, 0x5b, 0x4f, + 0x23, 0x86, 0x8a, 0x38, 0x7a, 0xbd, 0x20, 0x08, 0x51, 0x1c, 0xbb, 0x4b, + 0x68, 0x1c, 0x3f, 0x90, 0x49, 0x9c, 0x53, 0xc1, 0x6e, 0x8a, 0x35, 0x22, + 0x49, 0x58, 0x48, 0xc5, 0x0a, 0x0e, 0x37, 0x92, 0x67, 0xd0, 0xb9, 0xbc, + 0xce, 0x9b, 0x84, 0x6b, 0x34, 0x15, 0xbe, 0x0b, 0xa2, 0xa9, 0x52, 0xc3, + 0x7d, 0xfc, 0x68, 0x10, 0xc4, 0x72, 0x6d, 0x01, 0x97, 0x4e, 0xba, 0x5d, + 0x4c, 0x8a, 0xb5, 0x9a, 0x99, 0xb7, 0x5b, 0x7b, 0x9c, 0x6b, 0x86, 0x6d, + 0xe4, 0xc3, 0x87, 0xed, 0x58, 0x4b, 0xf3, 0x91, 0xb7, 0x0c, 0xa8, 0x7a, + 0x37, 0x47, 0x85, 0x44, 0x03, 0x2e, 0x00, 0xcb, 0xbf, 0xf4, 0xd7, 0x4a, + 0x1b, 0x42, 0x99, 0x1e, 0x72, 0x9c, 0x8c, 0x4b, 0xcb, 0x98, 0x0a, 0x48, + 0x7c, 0x55, 0x4b, 0xb7, 0x55, 0x6a, 0x24, 0x23, 0x83, 0xca, 0xb9, 0x36, + 0x36, 0x63, 0x44, 0xe7, 0xe3, 0x3c, 0x8c, 0x91, 0x6d, 0x64, 0xb4, 0x6e, + 0xc2, 0x99, 0x35, 0xbc, 0xa6, 0x5c, 0x8e, 0xda, 0x3f, 0x67, 0x55, 0x9e, + 0xda, 0xda, 0x07, 0x30, 0x16, 0x44, 0xfb, 0xc4, 0x64, 0x3f, 0x9c, 0x2f, + 0xea, 0x45, 0x19, 0x5d, 0x8c, 0x67, 0xce, 0x56, 0x87, 0xff, 0xd0, 0x64, + 0xd2, 0x82, 0xca, 0x82, 0x3b, 0x44, 0x9f, 0x9b, 0x2e, 0xe5, 0x96, 0x29, + 0x7f, 0xf6, 0xa3, 0x4d, 0x38, 0x54, 0xb5, 0x87, 0xc5, 0x96, 0xe3, 0xbc, + 0x2f, 0x7c, 0x4e, 0x91, 0x33, 0x39, 0xbe, 0xc8, 0x54, 0x35, 0xb7, 0x83, + 0x21, 0xb1, 0x23, 0xa8, 0x93, 0x56, 0x44, 0x41, 0xc5, 0x15, 0xa2, 0x80, + 0x56, 0x31, 0x50, 0xd3, 0xf8, 0x0f, 0xfc, 0x68, 0x86, 0x74, 0x34, 0x61, + 0x59, 0x46, 0x1d, 0x17, 0x6c, 0x77, 0xa4, 0xcc, 0xc0, 0x52, 0x73, 0x57, + 0xc9, 0xd0, 0x0d, 0x17, 0x23, 0x73, 0x4e, 0x78, 0xb5, 0xb3, 0x74, 0xb2, + 0xd8, 0x95, 0xb0, 0xe0, 0x8b, 0x33, 0xe9, 0x7b, 0x2d, 0x73, 0xa6, 0xb9, + 0x94, 0xf9, 0x0e, 0x89, 0xbc, 0xab, 0xea, 0xc2, 0xbe, 0xe4, 0x98, 0xbb, + 0x09, 0xc4, 0xbc, 0x03, 0xca, 0x2c, 0x8e, 0x00, 0xce, 0x99, 0xfa, 0x04, + 0xfb, 0x04, 0x8d, 0x86, 0x4c, 0x3b, 0xb6, 0xe1, 0x23, 0x6e, 0x5c, 0xac, + 0x3d, 0xe3, 0x04, 0x07, 0xc3, 0x28, 0x4b, 0x2c, 0x64, 0x3f, 0xe0, 0x2c, + 0x6e, 0xfa, 0x02, 0x4d, 0x96, 0x40, 0x1f, 0x1b, 0xc4, 0x63, 0xe5, 0xbb, + 0xd9, 0xc0, 0x8c, 0x81, 0x79, 0x2d, 0xba, 0xe5, 0x10, 0xf1, 0xb7, 0x27, + 0xf3, 0xa1, 0xb5, 0x30, 0x40, 0x2b, 0x47, 0xc6, 0xb6, 0xdb, 0xd5, 0x14, + 0x75, 0x79, 0x93, 0x8f, 0xa9, 0x72, 0xaf, 0xc4, 0x6e, 0x74, 0x26, 0x78, + 0x2e, 0x26, 0xa9, 0xc8, 0xe2, 0xc5, 0x70, 0x45, 0x48, 0x2a, 0xdc, 0x10, + 0x03, 0x17, 0x17, 0x3e, 0xe5, 0x1d, 0x03, 0xf3, 0x19, 0x7a, 0x10, 0x2c, + 0x9f, 0xd7, 0xb6, 0x07, 0x35, 0x1b, 0x4a, 0xd5, 0xb6, 0xbd, 0xe4, 0x51, + 0x13, 0xd6, 0x37, 0x33, 0x2a, 0x28, 0x8e, 0x4f, 0x6b, 0xb6, 0x7e, 0x44, + 0x4c, 0x32, 0x3e, 0xe8, 0x21, 0x8b, 0x5c, 0x1d, 0x15, 0x99, 0xb5, 0x8d, + 0xde, 0x35, 0x2f, 0xd6, 0xcd, 0x64, 0x7a, 0x52, + ]), + // 64-byte privateSeed + privateSeed: new Uint8Array([ + 0x46, 0x97, 0x3b, 0x12, 0xa0, 0x54, 0xa8, 0x9f, 0x47, 0xd5, 0x3a, 0xf5, + 0x83, 0xad, 0x94, 0x67, 0x6b, 0xbe, 0x8a, 0xc1, 0x04, 0x6b, 0x07, 0x1d, + 0x66, 0x6f, 0x55, 0x81, 0x3b, 0x68, 0x98, 0xaa, 0xaa, 0xcb, 0x55, 0x59, + 0xd0, 0x07, 0xea, 0x68, 0x14, 0x68, 0x3b, 0x49, 0x9d, 0x8b, 0xe1, 0xa0, + 0xf5, 0xbd, 0xf0, 0x52, 0x7a, 0xd9, 0xdf, 0xa8, 0x66, 0x90, 0x38, 0xfb, + 0x33, 0xbe, 0x26, 0xc5, + ]), + // 1088-byte sampleCiphertext + sampleCiphertext: new Uint8Array([ + 0x1a, 0xd4, 0x01, 0xa3, 0xc4, 0x3e, 0x18, 0xa5, 0x80, 0x8d, 0x49, 0xbc, + 0xfa, 0x19, 0x13, 0x2e, 0x0a, 0x3c, 0x0a, 0x55, 0x13, 0x79, 0x16, 0x9c, + 0x07, 0x70, 0x37, 0x6a, 0x12, 0xd2, 0xdd, 0x49, 0x9e, 0xfb, 0xc8, 0x60, + 0xe5, 0x06, 0x77, 0x07, 0xde, 0x7b, 0xe9, 0xb1, 0x64, 0x18, 0x5a, 0x46, + 0x12, 0xdc, 0x88, 0xef, 0x8c, 0xc7, 0x55, 0xf2, 0x53, 0xfe, 0x90, 0x81, + 0xb9, 0xfb, 0x25, 0x82, 0x7f, 0x2e, 0x31, 0x6a, 0x09, 0xae, 0x62, 0xeb, + 0xf8, 0x5d, 0x97, 0x45, 0x46, 0x93, 0xfb, 0x22, 0x04, 0x22, 0xee, 0xc6, + 0xd3, 0xa1, 0x78, 0x21, 0x84, 0x97, 0x7f, 0xce, 0xd1, 0x95, 0x1a, 0xd0, + 0xa8, 0xb7, 0xea, 0xc8, 0x97, 0xf4, 0xe8, 0xe3, 0xbb, 0x7d, 0x15, 0xfd, + 0x3f, 0x78, 0xed, 0x8d, 0x37, 0xea, 0xd1, 0xa5, 0x4e, 0xbf, 0xa2, 0x30, + 0xaf, 0x95, 0xf3, 0x32, 0x6f, 0xbb, 0x05, 0x57, 0xbc, 0x55, 0x8a, 0x8b, + 0x19, 0x50, 0xd9, 0xe5, 0x46, 0x3a, 0x4d, 0x2c, 0xea, 0xaa, 0x1f, 0x7a, + 0x67, 0xf8, 0xd6, 0x25, 0xc9, 0x86, 0x40, 0xa8, 0x9e, 0xd4, 0xee, 0xc2, + 0xe6, 0x3d, 0x34, 0xc0, 0x6d, 0x7b, 0x31, 0xff, 0xe8, 0x3f, 0x86, 0x1a, + 0x3a, 0x7e, 0x50, 0xfe, 0x64, 0x4b, 0x6b, 0xc7, 0x2e, 0x78, 0xce, 0xb7, + 0x73, 0x83, 0x1d, 0x1d, 0x90, 0x5f, 0x7a, 0x34, 0x08, 0xac, 0xb0, 0x73, + 0xac, 0x81, 0xbf, 0x40, 0xed, 0x37, 0x66, 0xf2, 0x83, 0xa5, 0xbc, 0x07, + 0xd2, 0x06, 0xa8, 0x26, 0x4a, 0xfd, 0xef, 0x77, 0x1a, 0xdc, 0xe3, 0x87, + 0x8f, 0x8d, 0x1d, 0x34, 0x6f, 0x92, 0x92, 0xd6, 0xbb, 0xb8, 0xb9, 0xc6, + 0xcb, 0x8e, 0x85, 0x7e, 0xd0, 0x47, 0x98, 0x52, 0x82, 0x89, 0x35, 0xbb, + 0x68, 0xaa, 0x04, 0x69, 0x82, 0x84, 0x34, 0x06, 0x2a, 0xa5, 0xea, 0x49, + 0x30, 0x7a, 0x80, 0xf1, 0x10, 0xff, 0xc1, 0x43, 0xac, 0x86, 0x44, 0xe5, + 0xaa, 0x3a, 0x74, 0xe5, 0x85, 0x39, 0x86, 0xce, 0x97, 0xa2, 0xe6, 0x99, + 0xad, 0xd9, 0xcb, 0x77, 0x53, 0xa1, 0x98, 0x3d, 0x08, 0xd2, 0x53, 0xfd, + 0x5e, 0x25, 0xef, 0xc8, 0xd9, 0xf1, 0x10, 0xe2, 0xbb, 0xf8, 0x9b, 0x31, + 0x95, 0x7f, 0xe0, 0xd3, 0xcd, 0xf5, 0xb1, 0xf6, 0x25, 0x6f, 0xf8, 0x8d, + 0x7a, 0xa4, 0xec, 0xb6, 0xb5, 0xf9, 0x1d, 0x66, 0x20, 0xe2, 0xc8, 0x61, + 0xdc, 0x87, 0x0a, 0x90, 0x38, 0x34, 0xb4, 0xf1, 0xb6, 0x08, 0xac, 0x90, + 0x40, 0x43, 0xea, 0x5c, 0x5c, 0x0a, 0x1f, 0x8e, 0xc4, 0x4f, 0x91, 0xc5, + 0x1c, 0x9a, 0x2e, 0x5f, 0xb8, 0x79, 0xd7, 0xdb, 0xfb, 0x9f, 0x94, 0x8c, + 0x19, 0x17, 0xca, 0x60, 0x7c, 0xa1, 0x03, 0xa1, 0xbf, 0xea, 0xcc, 0xfa, + 0xd2, 0xef, 0x34, 0xa8, 0x79, 0x9f, 0x39, 0x26, 0x13, 0x04, 0xd6, 0x77, + 0x29, 0x38, 0xb5, 0x82, 0xa2, 0xea, 0x94, 0x8a, 0x28, 0x39, 0xff, 0xb4, + 0x3d, 0xc3, 0x15, 0xd0, 0xae, 0x31, 0x1f, 0x1e, 0x54, 0x29, 0x4c, 0xb6, + 0xdb, 0xc1, 0xef, 0xa9, 0x04, 0xa6, 0x66, 0xb0, 0xa3, 0x81, 0xc8, 0xb5, + 0x28, 0xd1, 0x0a, 0x56, 0x26, 0x41, 0xea, 0xd9, 0x52, 0x93, 0xb7, 0x4e, + 0xcc, 0x78, 0xc2, 0xe6, 0x4a, 0xf9, 0x8b, 0xa6, 0x38, 0x82, 0x78, 0xb5, + 0x09, 0x1e, 0xf2, 0x9f, 0x8b, 0x50, 0x6e, 0x7e, 0xa4, 0xe2, 0xb8, 0x59, + 0x1c, 0xca, 0x61, 0x45, 0x20, 0x5e, 0xfc, 0x91, 0xf9, 0xde, 0x7e, 0x28, + 0x60, 0xd7, 0xe2, 0x89, 0x3c, 0x88, 0x88, 0x07, 0xbe, 0x0b, 0x76, 0x5a, + 0x12, 0xa8, 0x56, 0x3c, 0xe0, 0x4f, 0xcb, 0x99, 0xd6, 0x85, 0x10, 0x31, + 0x2f, 0x77, 0x4f, 0xcc, 0xcd, 0x4c, 0x5d, 0x0f, 0x87, 0x64, 0xcf, 0xb9, + 0xff, 0xff, 0xfd, 0x67, 0xb2, 0xdc, 0x3f, 0xf5, 0xb4, 0xb4, 0x7d, 0xa0, + 0x66, 0x54, 0x09, 0xd3, 0xdc, 0x4e, 0xc4, 0xda, 0x3e, 0x36, 0xb9, 0x91, + 0xf9, 0xf3, 0xea, 0x2c, 0xc0, 0x1e, 0x34, 0x7d, 0x69, 0x25, 0x6f, 0xf7, + 0x05, 0x7b, 0x20, 0x1f, 0x3e, 0x04, 0x34, 0x3b, 0x2b, 0xc8, 0x1e, 0x67, + 0x00, 0x9e, 0xa6, 0x59, 0xc1, 0x20, 0xe0, 0xc6, 0x06, 0xed, 0x2a, 0xeb, + 0xe8, 0xa6, 0x71, 0x96, 0x48, 0x1e, 0xf3, 0xc5, 0x30, 0x1b, 0xc1, 0x73, + 0xa3, 0x3c, 0x61, 0xed, 0x93, 0x19, 0x16, 0xd2, 0x1a, 0x0e, 0x6d, 0x9a, + 0xe7, 0x39, 0x81, 0xdd, 0x3e, 0xb2, 0xa3, 0x3b, 0x33, 0xa8, 0x4e, 0xce, + 0xbf, 0xbe, 0x42, 0x24, 0x9f, 0x54, 0xa3, 0xd8, 0x17, 0x03, 0x8e, 0xc6, + 0xc6, 0x0e, 0x89, 0x98, 0xdc, 0x9e, 0xbd, 0x17, 0xb9, 0x68, 0x87, 0xbd, + 0x3c, 0x69, 0xc7, 0xb4, 0x54, 0x7f, 0x40, 0x2f, 0x24, 0x98, 0x1f, 0x52, + 0x93, 0xe0, 0xce, 0x5e, 0x77, 0x07, 0xaa, 0xf3, 0x33, 0xb9, 0xbd, 0x98, + 0x21, 0x95, 0xaf, 0xff, 0xab, 0x10, 0xa8, 0x0d, 0x53, 0xa9, 0xec, 0xca, + 0x12, 0x95, 0x79, 0xd5, 0xf5, 0xfd, 0xdd, 0x6d, 0xc5, 0x24, 0x56, 0x40, + 0xf8, 0x3c, 0xf3, 0xbf, 0x9a, 0xe7, 0xf8, 0x39, 0x45, 0x5a, 0x14, 0xae, + 0xaf, 0xfc, 0x2a, 0x17, 0x7d, 0x7a, 0x5e, 0x93, 0x11, 0x0f, 0x74, 0xf9, + 0xea, 0x27, 0xed, 0x22, 0x4d, 0xf2, 0x58, 0x68, 0x17, 0x53, 0x68, 0x3a, + 0xe1, 0x75, 0x5a, 0xe4, 0xa8, 0xd6, 0x16, 0xfb, 0xae, 0x8c, 0xc6, 0x86, + 0xea, 0x06, 0xa3, 0x1b, 0x39, 0xdf, 0x7a, 0x56, 0x37, 0x35, 0x83, 0x9a, + 0xad, 0xc4, 0xac, 0x05, 0xf7, 0xf4, 0xb9, 0xed, 0xc6, 0xb1, 0x73, 0x57, + 0x6f, 0xdc, 0xc7, 0xce, 0x30, 0x72, 0xdc, 0xed, 0x29, 0xde, 0xe8, 0x35, + 0x59, 0x66, 0xdb, 0x7d, 0x25, 0xbb, 0x2f, 0x61, 0x3e, 0xa6, 0xe3, 0x2a, + 0x7c, 0x51, 0x3c, 0xc2, 0x47, 0x4b, 0x71, 0xb3, 0xdb, 0x7d, 0x5f, 0x8a, + 0x64, 0xc6, 0x6f, 0x7c, 0xbe, 0xad, 0xf3, 0x41, 0x7d, 0x7b, 0x7f, 0x60, + 0xf2, 0x7e, 0x23, 0x56, 0x6a, 0xdb, 0x11, 0xda, 0x10, 0xc7, 0x04, 0x9c, + 0xe1, 0x29, 0xfe, 0x55, 0xa6, 0x5a, 0xd1, 0x6f, 0x60, 0xdf, 0xec, 0xaa, + 0x1f, 0xaa, 0x05, 0x36, 0xc5, 0x4f, 0x66, 0xa3, 0xa0, 0xe4, 0x1e, 0x04, + 0x00, 0x10, 0xc2, 0x8b, 0x2c, 0xe6, 0xc5, 0xe5, 0xc9, 0xc0, 0x93, 0x59, + 0x9b, 0x1b, 0xcb, 0x0d, 0xdd, 0x4d, 0x23, 0xef, 0x4a, 0x6a, 0x49, 0x13, + 0x6a, 0x31, 0xd7, 0x69, 0xec, 0xd1, 0x4c, 0xa4, 0xdd, 0x83, 0xe6, 0x6d, + 0x90, 0xa9, 0x3a, 0xc1, 0x01, 0x94, 0x88, 0x75, 0xb7, 0x84, 0xa3, 0x94, + 0x0b, 0x02, 0x4e, 0x3f, 0x8c, 0xe2, 0xd0, 0x45, 0x42, 0xfe, 0x67, 0x14, + 0xcb, 0xf0, 0x05, 0x39, 0xf6, 0x50, 0x00, 0x5b, 0xa5, 0x8e, 0xba, 0x04, + 0x37, 0x7e, 0x37, 0x34, 0xbf, 0xe9, 0xff, 0x99, 0xb6, 0xca, 0xbf, 0xa0, + 0x87, 0x43, 0x36, 0x9e, 0x48, 0x47, 0xe3, 0xb1, 0x54, 0x45, 0x25, 0x1a, + 0x94, 0xb6, 0x42, 0x70, 0xf6, 0x18, 0xa5, 0x96, 0xce, 0x94, 0xe2, 0x2c, + 0x1f, 0x71, 0xe4, 0x0f, 0xd1, 0x97, 0x65, 0x49, 0x8b, 0xc2, 0x1c, 0x9a, + 0x59, 0xab, 0x7e, 0xb7, 0x7c, 0xae, 0xe8, 0x1e, 0xaf, 0xed, 0x0d, 0xe8, + 0xd5, 0x42, 0x4e, 0xe3, 0xce, 0xff, 0x86, 0x0e, 0xab, 0xb3, 0xb1, 0x38, + 0x1f, 0xa5, 0x28, 0x76, 0x42, 0xec, 0x50, 0xea, 0x9e, 0xe9, 0x57, 0x8a, + 0x8b, 0x7a, 0xbc, 0x00, 0xeb, 0x18, 0x7b, 0x15, 0x8c, 0x75, 0x66, 0x9c, + 0x17, 0x5d, 0x50, 0xe3, 0x00, 0xa4, 0xe0, 0x0b, 0xae, 0x5a, 0x53, 0x33, + 0xa7, 0x59, 0x33, 0x93, 0x86, 0x01, 0x18, 0x3f, 0x8a, 0x69, 0xbf, 0x54, + 0x7d, 0x5b, 0xe4, 0x9b, 0x7f, 0xae, 0xa3, 0x91, 0xbd, 0x2a, 0x4f, 0x5c, + 0xab, 0x05, 0x76, 0x42, 0x20, 0x5b, 0x55, 0x43, 0x7f, 0x99, 0xcc, 0x81, + 0x14, 0xcc, 0x21, 0xba, 0x9e, 0x9f, 0x16, 0xe8, 0x84, 0x4c, 0xf9, 0xda, + 0xd5, 0x39, 0x31, 0x40, 0x9c, 0xf4, 0xef, 0x6c, 0x6e, 0x65, 0xe7, 0x7f, + 0x21, 0xee, 0x2b, 0x3e, 0x70, 0x92, 0x71, 0x29, 0xa4, 0xb5, 0xd7, 0x80, + 0x44, 0xea, 0x70, 0x31, 0x26, 0x4b, 0xce, 0x6a, + ]), + // 32-byte expectedSharedSecret + expectedSharedSecret: new Uint8Array([ + 0x53, 0x2e, 0x3b, 0x9a, 0xf0, 0x8e, 0x5f, 0x55, 0x28, 0x92, 0x9b, 0x76, + 0x2f, 0xb6, 0xe4, 0xd3, 0x0b, 0x28, 0x86, 0xf0, 0x18, 0xf9, 0x70, 0x78, + 0x41, 0x99, 0xf3, 0x15, 0xe3, 0xf5, 0xcf, 0xc3, + ]), +}; + +// ML-KEM-1024 test vectors +ml_kem_vectors['ML-KEM-1024'] = { + // 1568-byte publicKey + publicKey: new Uint8Array([ + 0x51, 0xe6, 0x70, 0x71, 0x69, 0x47, 0x5b, 0x3a, 0x30, 0x8f, 0x01, 0x40, + 0x59, 0x58, 0x3b, 0x83, 0x04, 0xcd, 0x2d, 0x93, 0x68, 0x7e, 0x53, 0x15, + 0x83, 0x46, 0x44, 0x79, 0x35, 0x10, 0xd8, 0xbc, 0xb4, 0x6d, 0x90, 0x53, + 0xaf, 0xe0, 0xcb, 0x91, 0x09, 0x5f, 0x39, 0xac, 0x78, 0x2b, 0x8a, 0x61, + 0x27, 0x81, 0xc9, 0xff, 0x6a, 0x4e, 0xf7, 0xb1, 0x7b, 0xb7, 0x62, 0xc1, + 0x38, 0xb5, 0x43, 0xf4, 0x86, 0x54, 0xe6, 0x79, 0x70, 0x66, 0xec, 0xce, + 0x85, 0xd4, 0x3d, 0x42, 0xe7, 0x93, 0x44, 0x6b, 0x74, 0xe3, 0x49, 0x29, + 0x6b, 0x44, 0x5a, 0xfd, 0x2c, 0x9f, 0x45, 0x64, 0x64, 0x97, 0xd1, 0x08, + 0x3f, 0x32, 0x9b, 0xc5, 0x72, 0x3b, 0x3b, 0x62, 0x56, 0x39, 0x6a, 0x13, + 0x5c, 0x31, 0x03, 0x00, 0x41, 0x1b, 0xfb, 0x17, 0x45, 0x03, 0x50, 0xb7, + 0xe1, 0x80, 0x83, 0x2c, 0x00, 0x38, 0xe2, 0x45, 0x0e, 0x78, 0xf5, 0x18, + 0xee, 0x31, 0x84, 0x42, 0xcc, 0xa1, 0x36, 0xab, 0x93, 0x8e, 0xf8, 0x79, + 0x75, 0x25, 0x8b, 0xf2, 0xcc, 0x51, 0x62, 0xb1, 0xa9, 0x3d, 0x8a, 0x51, + 0xea, 0x52, 0xa1, 0xa8, 0xd4, 0xca, 0x23, 0xb9, 0xb6, 0x0b, 0xd6, 0x8c, + 0x7f, 0x41, 0x86, 0xa9, 0x80, 0x69, 0x99, 0xcc, 0x88, 0x6f, 0xa3, 0x69, + 0x2f, 0xfc, 0xbb, 0x46, 0xaa, 0xa2, 0x8f, 0x85, 0x6f, 0x9a, 0x77, 0x43, + 0x57, 0x40, 0x2f, 0xb0, 0xa5, 0xce, 0x80, 0xf6, 0x96, 0x31, 0xe5, 0x23, + 0x36, 0x72, 0x9e, 0x04, 0x38, 0xa1, 0xe9, 0x3a, 0x21, 0x4a, 0xe9, 0x9f, + 0x15, 0x26, 0x3e, 0xff, 0x13, 0x5d, 0xe0, 0xa9, 0x42, 0xd8, 0xb3, 0xc2, + 0x61, 0xb4, 0x22, 0xc0, 0x34, 0xb1, 0xbe, 0xc7, 0x90, 0x36, 0xb0, 0xa0, + 0x41, 0xc3, 0x7b, 0xe0, 0x33, 0x34, 0xae, 0x42, 0xcf, 0x86, 0x13, 0x28, + 0x3e, 0xe8, 0x0e, 0x69, 0x31, 0x49, 0x89, 0xf3, 0x69, 0x6f, 0x18, 0x25, + 0xbc, 0x53, 0xc8, 0x94, 0x32, 0x3e, 0x17, 0x75, 0xc7, 0x2f, 0x77, 0x94, + 0x15, 0xb8, 0x84, 0x87, 0xec, 0x26, 0xf4, 0xb1, 0x64, 0x46, 0xa0, 0xaa, + 0xb0, 0xe5, 0x22, 0x6b, 0x83, 0x7b, 0x8d, 0x13, 0x29, 0x7e, 0x31, 0xb4, + 0x7b, 0x4b, 0x41, 0xa4, 0x9b, 0x82, 0x3f, 0x69, 0x64, 0xe5, 0x37, 0x8a, + 0x78, 0x06, 0x3a, 0xfa, 0x24, 0xb5, 0xe6, 0x29, 0x4f, 0x27, 0x0b, 0xba, + 0x5a, 0x7b, 0x90, 0xe4, 0x2a, 0x2d, 0x6b, 0xa4, 0x41, 0x9f, 0x85, 0x8a, + 0xdb, 0xb1, 0x8f, 0x90, 0x1c, 0x37, 0xa0, 0xf2, 0x78, 0xbf, 0x6c, 0x46, + 0x8e, 0x72, 0x3f, 0x00, 0xbc, 0xba, 0x37, 0x10, 0x80, 0x9b, 0xd5, 0x5e, + 0x35, 0xbb, 0xb5, 0x20, 0xdc, 0x9f, 0x44, 0x61, 0x46, 0x65, 0x00, 0x6f, + 0x71, 0x3b, 0x5b, 0xa2, 0x64, 0xbb, 0x26, 0xb7, 0x10, 0x6d, 0x89, 0xbb, + 0x71, 0x4c, 0x65, 0xc0, 0xf3, 0x78, 0xdf, 0x16, 0x51, 0xa5, 0x75, 0xcd, + 0x63, 0x77, 0xa2, 0x83, 0x74, 0xb7, 0x66, 0x8b, 0xb6, 0xb1, 0x43, 0x66, + 0x12, 0xa3, 0x9c, 0x71, 0xea, 0xa4, 0x82, 0xeb, 0x78, 0xb7, 0xd0, 0x7d, + 0x49, 0x14, 0x87, 0x3e, 0x36, 0x38, 0x42, 0x90, 0xa7, 0xc4, 0x47, 0x86, + 0xe9, 0xb3, 0x7b, 0x8b, 0x42, 0x78, 0x82, 0x06, 0x9f, 0x0a, 0x90, 0x18, + 0xb4, 0x87, 0xa5, 0xff, 0xa8, 0xbc, 0x83, 0xd5, 0x2a, 0xab, 0x57, 0x95, + 0x63, 0x97, 0xac, 0x60, 0x56, 0x31, 0x3b, 0x94, 0xb5, 0x3c, 0xe1, 0xc3, + 0x9b, 0x71, 0x7e, 0x9b, 0xe2, 0x8b, 0xc7, 0xca, 0x12, 0xc4, 0x93, 0x8e, + 0x48, 0xbb, 0x03, 0x1a, 0x56, 0x39, 0x62, 0xc0, 0x5f, 0x25, 0xa4, 0x06, + 0xda, 0x2b, 0x7c, 0x1b, 0x98, 0x3a, 0x55, 0x5c, 0x5a, 0xe7, 0x93, 0x62, + 0x2c, 0x31, 0x93, 0xc4, 0xc1, 0x75, 0xfe, 0x0a, 0x8d, 0xfe, 0x20, 0xc1, + 0xcb, 0xb9, 0x4d, 0x96, 0x97, 0x16, 0x01, 0x60, 0x87, 0x8c, 0x67, 0x20, + 0xee, 0xf4, 0x4f, 0x8c, 0x22, 0x54, 0x9c, 0xf6, 0x2a, 0x2b, 0x4c, 0xbf, + 0xfc, 0x11, 0x9b, 0xd1, 0xc4, 0x6a, 0x10, 0xd0, 0x66, 0x1d, 0x5c, 0x4b, + 0x1a, 0x92, 0x77, 0xaa, 0x31, 0x00, 0xd8, 0xe3, 0x63, 0x68, 0x99, 0xbe, + 0xe5, 0x43, 0x12, 0x7c, 0xbb, 0x2a, 0x8c, 0x70, 0xb6, 0x76, 0x8c, 0xc5, + 0x1a, 0xa4, 0x39, 0x93, 0x87, 0x25, 0x87, 0x71, 0x87, 0xaa, 0x25, 0x3e, + 0xea, 0x51, 0xc6, 0x78, 0x4c, 0x29, 0xb3, 0x65, 0x07, 0xe4, 0x03, 0x9c, + 0x37, 0xb8, 0x45, 0xee, 0x4b, 0x05, 0x81, 0x55, 0xa3, 0xb8, 0x51, 0xca, + 0x68, 0x5c, 0x05, 0x4f, 0x80, 0x86, 0xca, 0x95, 0x58, 0x24, 0xab, 0x41, + 0x44, 0xc4, 0x36, 0x8d, 0xdc, 0x70, 0x76, 0x4a, 0x18, 0x4c, 0x2a, 0x2a, + 0xbe, 0xcc, 0x84, 0xad, 0xd7, 0x65, 0x07, 0x36, 0xa0, 0xf8, 0x86, 0x5e, + 0xc0, 0xc6, 0xb4, 0xbe, 0x22, 0x34, 0x5c, 0xeb, 0xc6, 0xed, 0x7a, 0x27, + 0xd5, 0x61, 0x61, 0xf3, 0x50, 0xa6, 0x05, 0xeb, 0x4b, 0x3f, 0x18, 0xa6, + 0x85, 0xdb, 0x16, 0x06, 0x35, 0x2e, 0x05, 0x2a, 0x97, 0xe9, 0xa5, 0xcf, + 0xb3, 0xb1, 0xc9, 0x09, 0xf5, 0x54, 0x5c, 0xe0, 0xa4, 0x19, 0xc6, 0x05, + 0xb7, 0x85, 0x94, 0x0f, 0x32, 0xc6, 0x22, 0xe3, 0x17, 0x87, 0xc5, 0xa3, + 0x61, 0xf4, 0x5e, 0xcd, 0xa5, 0x0b, 0x4b, 0x75, 0x46, 0xe7, 0x55, 0xaa, + 0x62, 0x67, 0x9f, 0x13, 0xea, 0xaa, 0x78, 0x75, 0x5f, 0x31, 0x18, 0x99, + 0x1b, 0x0a, 0x57, 0x92, 0x49, 0x59, 0x9a, 0x39, 0x21, 0x47, 0x11, 0x52, + 0x63, 0x4b, 0x4f, 0xe4, 0x01, 0xb1, 0x1c, 0xe7, 0x18, 0x2c, 0x54, 0xa3, + 0x21, 0x89, 0x9a, 0x94, 0xb4, 0x45, 0xb7, 0xca, 0x32, 0xbe, 0x5c, 0x13, + 0x02, 0xf7, 0x7e, 0x51, 0xdc, 0x86, 0xfc, 0xf3, 0x61, 0x59, 0x3b, 0x13, + 0xeb, 0x9c, 0xb0, 0x1d, 0xf3, 0xb1, 0x69, 0x93, 0xc1, 0x57, 0xc5, 0x66, + 0xac, 0x0b, 0xbc, 0xe3, 0x10, 0x83, 0xcb, 0xb1, 0x49, 0x53, 0x5b, 0x05, + 0xfd, 0xc8, 0x66, 0x55, 0xa5, 0x76, 0x65, 0x42, 0x34, 0x1f, 0x99, 0xb9, + 0xf2, 0x74, 0x77, 0x18, 0xfb, 0x58, 0xef, 0x1c, 0x00, 0x11, 0x18, 0x4c, + 0x21, 0xe3, 0xca, 0x80, 0xb1, 0xb9, 0x12, 0x8b, 0x79, 0x6b, 0x16, 0x9c, + 0x2b, 0x0a, 0xad, 0x8e, 0xbb, 0x2d, 0xa5, 0x36, 0x9f, 0x44, 0xdb, 0x2c, + 0x99, 0x5c, 0xa5, 0x67, 0x56, 0xc6, 0x68, 0xe4, 0xbd, 0xfe, 0x38, 0x86, + 0x2c, 0xc7, 0xba, 0xe4, 0xd1, 0xae, 0x50, 0x5c, 0x6e, 0x93, 0x6c, 0xba, + 0xae, 0x9b, 0x42, 0xe5, 0xbb, 0x28, 0x68, 0xc1, 0x41, 0xc2, 0x5b, 0x81, + 0xed, 0x7c, 0xc7, 0x06, 0x84, 0x6e, 0xa9, 0xa0, 0x59, 0xea, 0x65, 0x96, + 0x02, 0xb4, 0x29, 0xdc, 0x91, 0x11, 0xf1, 0xb0, 0xb3, 0x18, 0xf7, 0x40, + 0x2f, 0xe2, 0x06, 0x98, 0xa9, 0x3b, 0x77, 0x09, 0x78, 0xd6, 0x03, 0x5d, + 0xb8, 0xd4, 0x06, 0x5c, 0x49, 0x27, 0x5f, 0xfa, 0xbe, 0x68, 0x75, 0xc6, + 0x62, 0x15, 0x6d, 0x2a, 0x07, 0xbd, 0x3d, 0x91, 0xcc, 0x9a, 0x70, 0x3f, + 0x0f, 0x1b, 0x63, 0x99, 0x03, 0x63, 0xe4, 0x9b, 0xbf, 0xb6, 0x7c, 0x86, + 0x78, 0x27, 0x59, 0xf1, 0xe3, 0xaf, 0xd1, 0x09, 0x4d, 0x66, 0xb6, 0x10, + 0x0d, 0x87, 0x2b, 0x72, 0x54, 0xbd, 0xa0, 0xb1, 0x7b, 0x17, 0xb9, 0xcd, + 0x15, 0x44, 0x50, 0x9f, 0x9a, 0x72, 0xb7, 0x9c, 0x21, 0x96, 0x92, 0x54, + 0x82, 0x3c, 0x50, 0x13, 0x24, 0x4c, 0x68, 0x1a, 0x77, 0x28, 0x29, 0x78, + 0x69, 0xbb, 0x7c, 0xae, 0x71, 0x6f, 0x9d, 0x59, 0x86, 0x8d, 0x0c, 0x2a, + 0xef, 0x98, 0x21, 0x53, 0xe2, 0x18, 0xab, 0x55, 0xb8, 0xce, 0x96, 0x9f, + 0x31, 0x85, 0x26, 0x8a, 0x88, 0x0c, 0x31, 0x98, 0x87, 0x38, 0x58, 0x9d, + 0x42, 0xb8, 0x1b, 0xbc, 0xe5, 0xae, 0xdb, 0x29, 0xb0, 0xe9, 0x93, 0x37, + 0xf2, 0x38, 0x9a, 0xa5, 0x43, 0x50, 0x28, 0x97, 0x42, 0x45, 0x63, 0x84, + 0x66, 0x91, 0x87, 0xd2, 0xc6, 0x91, 0x8c, 0x59, 0x03, 0x3c, 0x92, 0x49, + 0x69, 0xa3, 0x67, 0x51, 0xb1, 0x01, 0x34, 0x54, 0x99, 0x75, 0xb2, 0x77, + 0xaf, 0xd9, 0x03, 0x3f, 0x50, 0xce, 0x65, 0xdc, 0x63, 0x3e, 0x5a, 0x1d, + 0x01, 0xa3, 0xb6, 0x13, 0x8c, 0x6f, 0x01, 0xf7, 0xae, 0xa1, 0x79, 0xc7, + 0xc8, 0xc7, 0x9e, 0x4b, 0xfb, 0x20, 0x3f, 0xd9, 0xb2, 0x8f, 0xa2, 0x3c, + 0x14, 0xe6, 0x55, 0xba, 0x77, 0x91, 0x92, 0x8a, 0xc4, 0x6f, 0xe1, 0xa6, + 0xb8, 0xb9, 0x36, 0x58, 0x09, 0x27, 0x68, 0xe6, 0x5e, 0x85, 0xc5, 0xae, + 0xd9, 0xe8, 0x97, 0xdd, 0x8a, 0x45, 0x71, 0x2a, 0xab, 0xcb, 0x7c, 0x19, + 0x19, 0x07, 0x65, 0x68, 0x49, 0x55, 0x9e, 0xd8, 0x4d, 0x40, 0x77, 0xc1, + 0x14, 0xd9, 0x11, 0xf9, 0xe8, 0x26, 0x70, 0x28, 0xa5, 0x85, 0x6a, 0x90, + 0x23, 0xba, 0x51, 0x08, 0x67, 0x86, 0x68, 0x92, 0x67, 0xa5, 0x6b, 0x06, + 0xe6, 0x28, 0x1f, 0x1b, 0xc3, 0x43, 0x4b, 0x01, 0xbf, 0x96, 0xb0, 0x24, + 0x3e, 0x08, 0x86, 0xd7, 0xf4, 0x37, 0x25, 0xf9, 0xaa, 0x59, 0x8b, 0x51, + 0x5c, 0xea, 0x40, 0x1b, 0x77, 0x51, 0xe1, 0xa2, 0x59, 0x81, 0x65, 0x26, + 0x23, 0x2a, 0x75, 0xd0, 0x72, 0x74, 0xf6, 0xbc, 0x4b, 0xd0, 0xd1, 0xa6, + 0x1e, 0xbb, 0x11, 0x80, 0x4a, 0xa7, 0x9f, 0x09, 0x40, 0x08, 0xe5, 0xa1, + 0x90, 0x85, 0x43, 0x1a, 0xc1, 0x1c, 0x50, 0x8a, 0x6f, 0xbd, 0x50, 0x26, + 0x8a, 0x8c, 0x80, 0x21, 0xc4, 0xb1, 0x9b, 0xfa, 0x56, 0x90, 0x97, 0x20, + 0xbf, 0xb7, 0x26, 0xca, 0xe9, 0xa7, 0xb7, 0x73, 0x6f, 0xaf, 0x17, 0xcf, + 0xba, 0x9b, 0x3b, 0x4a, 0x32, 0xad, 0xbb, 0x04, 0x50, 0xe9, 0x00, 0x24, + 0xbb, 0xe8, 0x2c, 0xdb, 0xb0, 0x2f, 0x62, 0x00, 0x5e, 0xf3, 0x34, 0x79, + 0x8c, 0xb3, 0xbd, 0x7f, 0xda, 0xa7, 0xfa, 0x63, 0x5f, 0xe3, 0xa6, 0x43, + 0xef, 0x74, 0x5f, 0x10, 0x37, 0xcb, 0x6b, 0x82, 0x4b, 0x7c, 0x60, 0x85, + 0x15, 0xe3, 0x7f, 0x5b, 0x73, 0xa4, 0x88, 0x24, 0x8d, 0xe1, 0x7c, 0x66, + 0x5d, 0x3b, 0xb4, 0xd9, 0x25, 0x75, 0x26, 0x6a, 0x0f, 0x65, 0x65, 0x26, + 0x4e, 0xb6, 0xa4, 0x64, 0x3b, 0x52, 0xb3, 0xd2, 0x3a, 0x80, 0x25, 0x46, + 0x10, 0x58, 0x5c, 0x22, 0xc3, 0x30, 0xa1, 0xe2, 0x35, 0xeb, 0xc7, 0x3d, + 0xe0, 0xba, 0xbf, 0x9b, 0x39, 0xa9, 0xc5, 0xf4, 0x8e, 0xf0, 0xac, 0x06, + 0x0f, 0xe9, 0x6a, 0x00, 0xfa, 0x4b, 0xe7, 0x6b, 0xbc, 0x47, 0x28, 0x37, + 0x1d, 0xe9, 0x64, 0x6d, 0xfa, 0x7d, 0x5c, 0x83, 0x3d, 0xe1, 0xf6, 0x46, + 0x28, 0x76, 0x33, 0xde, 0xb4, 0x1f, 0x46, 0x76, 0xc7, 0x44, 0x72, 0x25, + 0x07, 0xf1, 0xc3, 0x53, 0xa8, 0x5e, 0x85, 0xea, 0x10, 0xb3, 0xd4, 0x3e, + 0x8a, 0x78, 0x4c, 0x3e, 0xf2, 0x62, 0xf2, 0x81, 0xbd, 0xd5, 0xdb, 0x44, + 0xe0, 0x3c, 0x4e, 0xca, 0xd2, 0xa0, 0x5b, 0x48, 0x0b, 0xa1, 0x99, 0xbb, + 0x32, 0xbb, 0x07, 0xaf, 0xc4, 0x62, 0x57, 0xf9, 0x5b, 0xdf, 0x51, 0x6f, + 0xea, 0x63, 0xc6, 0x6c, 0xc4, 0x84, 0x26, 0xfa, 0xca, 0xcc, 0x06, 0x56, + 0xb7, 0xf6, 0x01, 0x79, 0xf7, 0x92, 0xb7, 0xd6, 0x86, 0xdf, 0xe7, 0x07, + 0xd7, 0xb9, 0x16, 0xb1, 0xe8, 0xb2, 0x49, 0x50, 0xc7, 0x4b, 0x9b, 0x60, + 0x01, 0x60, 0x4e, 0x5d, 0x33, 0x3a, 0x35, 0x99, 0x2a, 0x7c, 0xc4, 0x4c, + 0xe3, 0xbc, 0x1b, 0xbd, 0xb8, 0xc7, 0x2f, 0x08, 0x42, 0x8d, 0x8a, 0x6e, + 0x59, 0x20, 0x61, 0x9d, 0x81, 0x96, 0xa7, 0xd3, 0x26, 0x95, 0x33, 0xbd, + 0xcd, 0x34, 0x35, 0x18, 0x3b, 0x5d, 0x6e, 0x98, + ]), + // 64-byte privateSeed + privateSeed: new Uint8Array([ + 0xd7, 0x10, 0xa2, 0xbc, 0x47, 0x89, 0x36, 0x8c, 0xf2, 0x0a, 0xf5, 0xfe, + 0xee, 0xdc, 0x8b, 0x9a, 0x8d, 0x0a, 0x88, 0xeb, 0xd7, 0x70, 0xf9, 0x1e, + 0x9a, 0x44, 0x11, 0x46, 0x52, 0x6f, 0x6b, 0x0e, 0x71, 0x1d, 0x94, 0x5a, + 0x87, 0x86, 0xbd, 0xce, 0x9f, 0x16, 0x7d, 0xdc, 0x5d, 0xa8, 0xc7, 0xab, + 0x96, 0xdc, 0x30, 0x5d, 0x6a, 0x36, 0x63, 0x19, 0xd5, 0xf8, 0xa6, 0x92, + 0x4f, 0x18, 0x39, 0x59, + ]), + // 1568-byte sampleCiphertext + sampleCiphertext: new Uint8Array([ + 0xd5, 0x4d, 0xf4, 0xd6, 0x79, 0x31, 0x4c, 0xfd, 0x6f, 0x32, 0x91, 0xcb, + 0x64, 0x4b, 0x99, 0x73, 0x14, 0x5a, 0x78, 0x8c, 0x98, 0xef, 0x94, 0xe6, + 0x8e, 0x9f, 0x8d, 0x1f, 0x92, 0xeb, 0x84, 0x23, 0x96, 0x84, 0x9e, 0x69, + 0x14, 0xd8, 0xcf, 0x53, 0x09, 0x02, 0x57, 0x88, 0x2f, 0x26, 0xb1, 0xfb, + 0x4c, 0x07, 0xa2, 0xb6, 0xad, 0xea, 0xf3, 0xbd, 0x56, 0x8c, 0x5d, 0x3c, + 0x5b, 0x54, 0x32, 0x0d, 0x95, 0x0f, 0xa5, 0x59, 0x80, 0xaf, 0x8d, 0x96, + 0xfd, 0x7d, 0x49, 0x65, 0x82, 0x5b, 0x63, 0x88, 0x42, 0x92, 0x9f, 0x7b, + 0x6a, 0xcf, 0x5d, 0xfd, 0x30, 0x33, 0xf3, 0xf3, 0x45, 0xaf, 0x31, 0x32, + 0x80, 0xe0, 0x10, 0x5f, 0xaa, 0xdd, 0x42, 0x71, 0x5f, 0xff, 0x55, 0x55, + 0x0c, 0xaa, 0x64, 0x36, 0x89, 0x67, 0xf1, 0x58, 0xca, 0x3a, 0x7d, 0x00, + 0xae, 0xb4, 0xdf, 0x1e, 0xcc, 0xde, 0x24, 0x0f, 0x5b, 0x21, 0x10, 0xef, + 0xe6, 0x5f, 0x58, 0xe9, 0xb3, 0xee, 0x54, 0x98, 0x7e, 0x07, 0xea, 0xe1, + 0x95, 0x27, 0x9a, 0xfa, 0x37, 0x3d, 0x74, 0x62, 0xa4, 0x8d, 0x9c, 0x79, + 0xb7, 0xc8, 0xa3, 0xf8, 0x16, 0x2d, 0x84, 0x30, 0xbd, 0x0d, 0x97, 0xbd, + 0x90, 0x14, 0x36, 0x29, 0x7c, 0x12, 0x3e, 0x41, 0xf7, 0x40, 0x96, 0x06, + 0x54, 0x69, 0xd5, 0x87, 0xb9, 0xe7, 0x42, 0x77, 0x3f, 0xfe, 0xf9, 0x13, + 0x46, 0xe3, 0x51, 0xbb, 0x95, 0xb4, 0x3b, 0x8c, 0x08, 0x2a, 0x28, 0x7b, + 0x97, 0x98, 0x91, 0x17, 0x4e, 0x71, 0x86, 0xdc, 0x8c, 0xf2, 0xd6, 0x4a, + 0x07, 0x71, 0x1f, 0x6e, 0x9f, 0x17, 0xcf, 0x02, 0xad, 0xdc, 0xc3, 0xb8, + 0x03, 0xfd, 0xc2, 0xe3, 0xee, 0xc9, 0xd3, 0x91, 0x84, 0x1f, 0x0b, 0x38, + 0x5e, 0x2d, 0x3e, 0x09, 0x08, 0xab, 0x84, 0x18, 0x82, 0x67, 0xce, 0xdd, + 0xcf, 0xb6, 0x9d, 0x2f, 0x44, 0x4f, 0x69, 0x00, 0x88, 0x16, 0x45, 0x8d, + 0xa4, 0xda, 0xd5, 0x9a, 0x79, 0xe3, 0x37, 0x83, 0x33, 0x9c, 0xcc, 0xeb, + 0x55, 0x24, 0xa0, 0x22, 0x7f, 0x11, 0x4a, 0x23, 0x67, 0xdb, 0xcc, 0x5f, + 0x97, 0x85, 0xef, 0x15, 0x66, 0x5e, 0x92, 0x1e, 0x87, 0x7b, 0x24, 0x05, + 0x87, 0x67, 0x43, 0xec, 0xed, 0x6d, 0x76, 0xaf, 0x9d, 0x4a, 0xa6, 0xa6, + 0x80, 0x33, 0xc2, 0x43, 0x51, 0x58, 0xd7, 0xb0, 0x10, 0x60, 0x58, 0xef, + 0x98, 0x52, 0xa8, 0x1a, 0x46, 0x2b, 0xfb, 0x3c, 0xf8, 0xb1, 0x60, 0x27, + 0xe5, 0xe0, 0x82, 0x50, 0xc1, 0x2c, 0xb1, 0xe4, 0x13, 0x06, 0x68, 0x17, + 0x36, 0x23, 0x35, 0x6f, 0x97, 0x93, 0xdb, 0x05, 0xbd, 0x06, 0x5e, 0xa3, + 0x6a, 0x61, 0x32, 0x6c, 0xca, 0xf5, 0x3d, 0x2e, 0xc0, 0xa1, 0x34, 0xdc, + 0x1f, 0xc6, 0xc7, 0x2a, 0x40, 0x3d, 0x27, 0x46, 0x30, 0xb7, 0x34, 0x64, + 0xaa, 0xa1, 0x6b, 0x46, 0xa7, 0x1c, 0x82, 0xd8, 0xa0, 0x27, 0xcb, 0x50, + 0x05, 0xf2, 0x24, 0x26, 0xc0, 0xb5, 0x31, 0x4b, 0x04, 0xb7, 0x08, 0xd7, + 0xac, 0xa3, 0xf4, 0xb8, 0x53, 0x8e, 0xc1, 0x92, 0x53, 0xf9, 0x40, 0xb4, + 0xb8, 0x15, 0xaf, 0x22, 0xce, 0x82, 0xbd, 0xcd, 0x7d, 0xa8, 0x5a, 0x61, + 0xac, 0x18, 0x7c, 0x92, 0xef, 0x38, 0xc8, 0xc2, 0x99, 0x00, 0x51, 0x91, + 0x64, 0x82, 0x37, 0x47, 0xea, 0xa5, 0xf6, 0x8b, 0xea, 0x24, 0xe8, 0x7e, + 0x62, 0x3c, 0xb7, 0x4d, 0xac, 0x2c, 0x7b, 0x57, 0xfa, 0x1f, 0x28, 0x53, + 0x16, 0xfd, 0x74, 0x4b, 0x83, 0x80, 0x0e, 0xf3, 0x66, 0x36, 0xcd, 0xf5, + 0x29, 0x23, 0x0d, 0xc6, 0x9e, 0x7b, 0xb2, 0x8b, 0xc5, 0xc6, 0x48, 0xdb, + 0x1d, 0xbb, 0x61, 0x48, 0xae, 0x05, 0x10, 0x99, 0x9b, 0x48, 0x23, 0x8c, + 0x10, 0x50, 0xee, 0x5e, 0xa0, 0x49, 0x86, 0x27, 0x4e, 0xfe, 0xa8, 0x63, + 0xde, 0x71, 0xf5, 0x52, 0x8c, 0xef, 0xcc, 0xd3, 0x9e, 0x0e, 0x17, 0x9b, + 0x57, 0x49, 0xb7, 0x27, 0x29, 0x01, 0x3c, 0xbb, 0x1e, 0x85, 0xb9, 0x6a, + 0x13, 0x47, 0x59, 0xd8, 0x0b, 0xca, 0xb2, 0xa5, 0xe4, 0xeb, 0x93, 0xfd, + 0x7e, 0xef, 0x26, 0xae, 0x23, 0xed, 0x1e, 0x07, 0xd5, 0x91, 0x72, 0xa4, + 0x8d, 0x09, 0xae, 0xef, 0xfa, 0xfe, 0x12, 0xad, 0x46, 0xd7, 0x91, 0xbf, + 0xc6, 0xa7, 0x13, 0x30, 0x7d, 0xad, 0x2b, 0x8e, 0xd4, 0x14, 0x87, 0xf2, + 0x89, 0xeb, 0x2c, 0xca, 0xb8, 0x36, 0x12, 0xb0, 0xec, 0x61, 0xc8, 0xdc, + 0x32, 0x80, 0xae, 0x89, 0x9a, 0x4b, 0x57, 0xe2, 0xe1, 0x33, 0xb5, 0xdb, + 0x0d, 0x89, 0x6a, 0xd4, 0x18, 0xa5, 0xaf, 0xef, 0x5d, 0xab, 0x36, 0xf8, + 0x7c, 0x64, 0x79, 0x32, 0x39, 0x67, 0x2d, 0x50, 0xa6, 0x7b, 0x6a, 0xc1, + 0x6d, 0x6f, 0xcb, 0xac, 0x5d, 0x3e, 0x71, 0x1d, 0x48, 0x7c, 0xcd, 0x0e, + 0x4a, 0xc1, 0xc9, 0x64, 0xaa, 0x51, 0x55, 0xcc, 0x3b, 0xa0, 0x10, 0xb5, + 0x78, 0x3d, 0xcd, 0xd0, 0xef, 0x10, 0x56, 0x7e, 0x7c, 0xf1, 0x98, 0x62, + 0xc0, 0x0d, 0x71, 0x23, 0x02, 0x41, 0xef, 0x13, 0x29, 0xc5, 0x21, 0x3d, + 0x09, 0x83, 0xa5, 0x8f, 0x56, 0x5c, 0x12, 0xdd, 0x78, 0x6d, 0x68, 0xd8, + 0xbc, 0x31, 0x15, 0x8d, 0xe6, 0xcd, 0x02, 0x73, 0xbd, 0xfd, 0x8e, 0x58, + 0xf2, 0x16, 0x48, 0x96, 0x00, 0x57, 0x5b, 0x9f, 0x37, 0x34, 0xcf, 0xde, + 0x2a, 0x22, 0xc6, 0xf3, 0x30, 0x17, 0x56, 0x28, 0x50, 0x19, 0xc7, 0x77, + 0xf2, 0x3e, 0xed, 0x8f, 0x10, 0x11, 0x09, 0xe9, 0xff, 0xbd, 0x75, 0x65, + 0x52, 0x3b, 0x5c, 0x0f, 0xb4, 0x95, 0x09, 0xe6, 0x6a, 0x28, 0x91, 0x5e, + 0x26, 0xbf, 0xce, 0xfc, 0x75, 0x5c, 0xc0, 0x2d, 0xc8, 0x63, 0x7f, 0x31, + 0xd3, 0x59, 0xf0, 0xe2, 0xa7, 0xe8, 0x21, 0x4c, 0x99, 0xd5, 0x2f, 0x29, + 0x9f, 0x8c, 0x1f, 0x2c, 0xba, 0x34, 0xff, 0x1e, 0x96, 0x74, 0x58, 0x17, + 0x1a, 0x40, 0xe3, 0xc4, 0x46, 0xf0, 0xfd, 0x2b, 0x44, 0x3a, 0x06, 0x03, + 0x9f, 0x30, 0xac, 0xe8, 0xa0, 0x7e, 0xc9, 0xf1, 0x57, 0x7d, 0xb6, 0xf9, + 0x52, 0x4f, 0x1e, 0x70, 0x5e, 0xd7, 0x97, 0xe4, 0xa6, 0xf9, 0x9f, 0xed, + 0xa6, 0x05, 0x72, 0x1e, 0xbc, 0x68, 0x8f, 0x1a, 0x72, 0xe0, 0xb2, 0x67, + 0xe9, 0xcc, 0x4f, 0x26, 0x4f, 0x5a, 0x6c, 0x46, 0xda, 0x62, 0x0a, 0x47, + 0xf5, 0x89, 0xab, 0x0f, 0x80, 0x49, 0x3e, 0x18, 0xe5, 0xc0, 0x55, 0x9f, + 0x97, 0x18, 0xcc, 0x99, 0xb3, 0xb2, 0xa9, 0xb8, 0xdb, 0xfe, 0x0d, 0x94, + 0x16, 0xec, 0xe2, 0x62, 0x26, 0x5e, 0x93, 0x18, 0x09, 0x4a, 0x24, 0xf9, + 0xc0, 0x10, 0x3c, 0xcd, 0xcf, 0x77, 0xd7, 0xcd, 0x00, 0xde, 0xcd, 0x22, + 0x01, 0x60, 0x2b, 0x8f, 0x49, 0x86, 0x40, 0x70, 0x21, 0xee, 0x68, 0x3e, + 0x1a, 0x1e, 0x21, 0x58, 0x7a, 0xff, 0x70, 0x52, 0xd3, 0x0f, 0x76, 0x97, + 0x1e, 0x9c, 0x34, 0x86, 0xa4, 0x81, 0xdf, 0x81, 0xb2, 0x24, 0xc1, 0x69, + 0x56, 0x52, 0x37, 0x46, 0x4e, 0xee, 0xa0, 0xd0, 0xc6, 0xb2, 0xe9, 0x3f, + 0x35, 0xbd, 0xe3, 0xd0, 0x87, 0x36, 0xce, 0x85, 0xb8, 0xac, 0x48, 0xec, + 0xf4, 0x9d, 0xa7, 0x90, 0xed, 0x8b, 0x26, 0xff, 0x13, 0x1e, 0x55, 0xa3, + 0x81, 0x74, 0x03, 0xf5, 0x85, 0x03, 0xa2, 0x28, 0x43, 0x16, 0x55, 0xc2, + 0x8b, 0xb5, 0x84, 0x32, 0x3e, 0xd0, 0x2b, 0xde, 0x2f, 0x70, 0x0c, 0x96, + 0x4e, 0x59, 0x51, 0xb7, 0x19, 0x10, 0xdd, 0x19, 0x0d, 0x71, 0xfc, 0x37, + 0xa1, 0xfd, 0x19, 0x31, 0xe7, 0xa6, 0x52, 0x5c, 0x23, 0x1d, 0xf5, 0xe0, + 0x69, 0xe0, 0x2d, 0xb1, 0x76, 0xf2, 0xe0, 0xcf, 0xf5, 0x68, 0x33, 0x9d, + 0x05, 0x0e, 0x7c, 0x76, 0x7a, 0x4a, 0xf8, 0x54, 0x09, 0xb6, 0x0f, 0x9a, + 0x36, 0xba, 0x25, 0x26, 0x01, 0x57, 0xe4, 0x32, 0xc4, 0xa5, 0xe6, 0x57, + 0x18, 0xe4, 0x74, 0xa2, 0xfd, 0xee, 0x8e, 0x95, 0x4f, 0x35, 0x33, 0x3c, + 0xb0, 0x03, 0x5f, 0x65, 0xc8, 0x65, 0x59, 0x38, 0x9e, 0x98, 0x5f, 0x63, + 0x3d, 0x13, 0xa6, 0x19, 0x3c, 0x6f, 0x81, 0x40, 0x27, 0x5a, 0x30, 0x5c, + 0xbe, 0x67, 0x59, 0x96, 0xf6, 0x83, 0x53, 0x2f, 0xed, 0x01, 0x30, 0xb4, + 0xae, 0x13, 0x0c, 0xee, 0xc7, 0x47, 0x6b, 0xa0, 0xb7, 0x9e, 0xf0, 0xc3, + 0x60, 0x6e, 0x07, 0x88, 0x49, 0x47, 0xc1, 0x8f, 0x39, 0x20, 0xa3, 0x2a, + 0x3b, 0x39, 0xf6, 0x6c, 0xcd, 0xa8, 0x2c, 0x15, 0x9b, 0x37, 0x18, 0xf2, + 0x66, 0xd9, 0x0d, 0xe8, 0x31, 0xc9, 0x01, 0xcc, 0x75, 0x8c, 0xd0, 0xdf, + 0xe4, 0xa4, 0xaf, 0xfb, 0x4d, 0xe7, 0x7a, 0xad, 0x1e, 0x8f, 0x9d, 0xdf, + 0x5a, 0xcf, 0x39, 0xcb, 0x65, 0x94, 0xb5, 0x00, 0x99, 0x49, 0xe5, 0xbc, + 0xa5, 0x02, 0x98, 0xd9, 0xad, 0x8b, 0xc7, 0xae, 0x02, 0x1c, 0x48, 0x9b, + 0x30, 0x4d, 0x7b, 0xe8, 0xfc, 0xde, 0x0e, 0x18, 0xbf, 0x4a, 0x81, 0x7d, + 0x79, 0xf7, 0xb5, 0x12, 0xd6, 0x2b, 0x30, 0xaf, 0xf6, 0xd2, 0xbc, 0x31, + 0xa2, 0x94, 0x0d, 0x07, 0x4e, 0x6f, 0x78, 0xc0, 0x13, 0xc8, 0x22, 0x06, + 0x96, 0xcf, 0xd0, 0x2e, 0xc8, 0x31, 0x45, 0xe7, 0xb9, 0x80, 0x2a, 0x97, + 0x04, 0x2c, 0x28, 0xe9, 0xe6, 0x19, 0x57, 0xca, 0xfb, 0x7d, 0xc4, 0x5d, + 0x2b, 0xa1, 0x29, 0x72, 0x23, 0xdb, 0x25, 0x3a, 0xd5, 0xc1, 0x7a, 0x71, + 0xc7, 0xde, 0x34, 0xb6, 0x77, 0x27, 0xbf, 0xff, 0xb6, 0xea, 0x54, 0x24, + 0x72, 0x58, 0x55, 0x0a, 0xf9, 0x63, 0x75, 0x1a, 0xe4, 0x3e, 0x2a, 0x24, + 0x09, 0xb6, 0x35, 0x95, 0xe8, 0x23, 0x90, 0xfc, 0x24, 0xc6, 0x71, 0x82, + 0xb5, 0x74, 0xad, 0xc1, 0x4c, 0xc7, 0xf6, 0x53, 0x64, 0x28, 0xad, 0x93, + 0xee, 0x47, 0xe9, 0x1a, 0x58, 0x9a, 0x51, 0x96, 0x3d, 0xe7, 0x3a, 0xee, + 0x5b, 0x8b, 0x05, 0x0e, 0x37, 0xda, 0x2c, 0x89, 0x9b, 0x0a, 0x7b, 0x67, + 0xe5, 0x86, 0xc2, 0x5e, 0xfa, 0x76, 0xa2, 0x38, 0x91, 0xec, 0x12, 0xf9, + 0x35, 0x47, 0x8c, 0x99, 0x70, 0xf7, 0xce, 0xe6, 0xac, 0xf9, 0x2e, 0x3f, + 0x45, 0x7c, 0x35, 0xe6, 0x33, 0xbf, 0x2a, 0xcf, 0x08, 0x7b, 0xd0, 0xab, + 0x5a, 0xc2, 0x7a, 0x6d, 0xf9, 0xfe, 0x09, 0x7a, 0x29, 0xe0, 0xcf, 0x38, + 0x93, 0xdf, 0xe4, 0xda, 0x6b, 0x66, 0x0c, 0xe2, 0x83, 0x64, 0xa6, 0xfb, + 0x74, 0x25, 0x78, 0x9b, 0x74, 0xf7, 0x05, 0xd8, 0xe1, 0x39, 0x48, 0x1b, + 0x60, 0x06, 0x16, 0xc9, 0xc3, 0xa9, 0xc2, 0xad, 0xd0, 0xf8, 0x86, 0x2b, + 0x44, 0xe4, 0xc1, 0x4e, 0xd4, 0x26, 0x8f, 0x8e, 0xd9, 0xa6, 0xa1, 0xef, + 0xbb, 0xac, 0x2c, 0x98, 0x82, 0xba, 0xdd, 0x14, 0x8d, 0x14, 0xe0, 0x09, + 0xd1, 0x50, 0x44, 0xcc, 0x4e, 0x03, 0x59, 0x92, 0x00, 0x9a, 0x60, 0x36, + 0xba, 0xd6, 0xa9, 0xae, 0x75, 0xfd, 0x36, 0x59, 0x87, 0x7c, 0xd3, 0x47, + 0xa4, 0x5d, 0x99, 0xe9, 0x9d, 0xb2, 0x17, 0x55, 0x83, 0xed, 0x3c, 0xeb, + 0x25, 0x60, 0xa8, 0xfd, 0xcf, 0xa3, 0x5c, 0x15, 0x09, 0x31, 0x5d, 0x4c, + 0x8f, 0xb0, 0xe4, 0xa0, 0xac, 0x29, 0x81, 0x13, 0x28, 0x56, 0x29, 0x26, + 0x1d, 0xd9, 0xb2, 0xb3, 0x8f, 0xee, 0x18, 0x1c, 0xc9, 0x57, 0xa1, 0xcb, + 0x58, 0x24, 0x71, 0x1a, 0x67, 0xb1, 0xdc, 0xe4, 0x0d, 0x99, 0xca, 0x28, + 0xf9, 0x23, 0xb2, 0xf9, 0x9f, 0x2b, 0x38, 0x30, 0x96, 0x43, 0xb1, 0x4c, + 0x01, 0x41, 0x35, 0x02, 0x12, 0x47, 0xb6, 0xe8, 0xd1, 0x15, 0xb2, 0x4b, + 0xed, 0xf9, 0xbb, 0x20, 0x6c, 0x7e, 0xe1, 0xf9, 0x2a, 0xa6, 0x2c, 0xb9, + 0x78, 0xc1, 0xb8, 0xdb, 0x4f, 0x25, 0x9a, 0x9c, + ]), + // 32-byte expectedSharedSecret + expectedSharedSecret: new Uint8Array([ + 0x2f, 0x52, 0x11, 0x10, 0xa9, 0xe8, 0x53, 0x86, 0x70, 0x13, 0xce, 0xe3, + 0x4a, 0x38, 0xf1, 0x07, 0xbe, 0xa1, 0xc4, 0x68, 0x90, 0x67, 0x16, 0x08, + 0xe4, 0xec, 0xa1, 0x13, 0xed, 0xe9, 0x09, 0x7e, + ]), +}; diff --git a/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/aes.js b/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/aes.js index fdeb7963f761e9..d93b60f8b87569 100644 --- a/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/aes.js +++ b/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/aes.js @@ -284,7 +284,7 @@ function run_test() { resolve(vector); }); } else { - return subtle.importKey("raw", vector.keyBuffer, {name: vector.algorithm.name}, false, usages) + return subtle.importKey(vector.algorithm.name.toUpperCase() === "AES-OCB" ? "raw-secret" : "raw", vector.keyBuffer, {name: vector.algorithm.name}, false, usages) .then(function(key) { vector.key = key; return vector; diff --git a/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/aes_ocb.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/aes_ocb.tentative.https.any.js new file mode 100644 index 00000000000000..1d321fcfe8a5a3 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/aes_ocb.tentative.https.any.js @@ -0,0 +1,7 @@ +// META: title=WebCryptoAPI: encrypt() Using AES-OCB w/ 120-bit iv +// META: script=aes_ocb_fixtures.js +// META: script=aes_ocb_vectors.js +// META: script=aes.js +// META: timeout=long + +run_test(); diff --git a/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/aes_ocb_fixtures.js b/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/aes_ocb_fixtures.js new file mode 100644 index 00000000000000..a5795195f163ce --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/aes_ocb_fixtures.js @@ -0,0 +1,437 @@ +function getFixtures() { + // Before we can really start, we need to fill a bunch of buffers with data + var plaintext = new Uint8Array([ + 84, 104, 105, 115, 32, 115, 112, 101, 99, 105, 102, 105, 99, 97, 116, 105, + 111, 110, 32, 100, 101, 115, 99, 114, 105, 98, 101, 115, 32, 97, 32, 74, 97, + 118, 97, 83, 99, 114, 105, 112, 116, 32, 65, 80, 73, 32, 102, 111, 114, 32, + 112, 101, 114, 102, 111, 114, 109, 105, 110, 103, 32, 98, 97, 115, 105, 99, + 32, 99, 114, 121, 112, 116, 111, 103, 114, 97, 112, 104, 105, 99, 32, 111, + 112, 101, 114, 97, 116, 105, 111, 110, 115, 32, 105, 110, 32, 119, 101, 98, + 32, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 115, 44, 32, 115, + 117, 99, 104, 32, 97, 115, 32, 104, 97, 115, 104, 105, 110, 103, 44, 32, + 115, 105, 103, 110, 97, 116, 117, 114, 101, 32, 103, 101, 110, 101, 114, 97, + 116, 105, 111, 110, 32, 97, 110, 100, 32, 118, 101, 114, 105, 102, 105, 99, + 97, 116, 105, 111, 110, 44, 32, 97, 110, 100, 32, 101, 110, 99, 114, 121, + 112, 116, 105, 111, 110, 32, 97, 110, 100, 32, 100, 101, 99, 114, 121, 112, + 116, 105, 111, 110, 46, 32, 65, 100, 100, 105, 116, 105, 111, 110, 97, 108, + 108, 121, 44, 32, 105, 116, 32, 100, 101, 115, 99, 114, 105, 98, 101, 115, + 32, 97, 110, 32, 65, 80, 73, 32, 102, 111, 114, 32, 97, 112, 112, 108, 105, + 99, 97, 116, 105, 111, 110, 115, 32, 116, 111, 32, 103, 101, 110, 101, 114, + 97, 116, 101, 32, 97, 110, 100, 47, 111, 114, 32, 109, 97, 110, 97, 103, + 101, 32, 116, 104, 101, 32, 107, 101, 121, 105, 110, 103, 32, 109, 97, 116, + 101, 114, 105, 97, 108, 32, 110, 101, 99, 101, 115, 115, 97, 114, 121, 32, + 116, 111, 32, 112, 101, 114, 102, 111, 114, 109, 32, 116, 104, 101, 115, + 101, 32, 111, 112, 101, 114, 97, 116, 105, 111, 110, 115, 46, 32, 85, 115, + 101, 115, 32, 102, 111, 114, 32, 116, 104, 105, 115, 32, 65, 80, 73, 32, + 114, 97, 110, 103, 101, 32, 102, 114, 111, 109, 32, 117, 115, 101, 114, 32, + 111, 114, 32, 115, 101, 114, 118, 105, 99, 101, 32, 97, 117, 116, 104, 101, + 110, 116, 105, 99, 97, 116, 105, 111, 110, 44, 32, 100, 111, 99, 117, 109, + 101, 110, 116, 32, 111, 114, 32, 99, 111, 100, 101, 32, 115, 105, 103, 110, + 105, 110, 103, 44, 32, 97, 110, 100, 32, 116, 104, 101, 32, 99, 111, 110, + 102, 105, 100, 101, 110, 116, 105, 97, 108, 105, 116, 121, 32, 97, 110, 100, + 32, 105, 110, 116, 101, 103, 114, 105, 116, 121, 32, 111, 102, 32, 99, 111, + 109, 109, 117, 110, 105, 99, 97, 116, 105, 111, 110, 115, 46, + ]); + + // We want some random key bytes of various sizes. + // These were randomly generated from a script. + var keyBytes = { + 128: new Uint8Array([ + 222, 192, 212, 252, 191, 60, 71, 65, 200, 146, 218, 189, 28, 212, 192, 78, + ]), + 192: new Uint8Array([ + 208, 238, 131, 65, 63, 68, 196, 63, 186, 208, 61, 207, 166, 18, 99, 152, + 29, 109, 221, 95, 240, 30, 28, 246, + ]), + 256: new Uint8Array([ + 103, 105, 56, 35, 251, 29, 88, 7, 63, 145, 236, 233, 204, 58, 249, 16, + 229, 83, 38, 22, 164, 210, 123, 19, 235, 123, 116, 216, 0, 11, 191, 48, + ]), + }; + + var iv = new Uint8Array([ + 58, 146, 115, 42, 166, 234, 57, 191, 57, 134, 224, 199, 108, 116, 46, + ]); + + var additionalData = new Uint8Array([ + 84, 104, 101, 114, 101, 32, 97, 114, 101, 32, 55, 32, 102, 117, 114, 116, + 104, 101, 114, 32, 101, 100, 105, 116, 111, 114, 105, 97, 108, 32, 110, 111, + 116, 101, 115, 32, 105, 110, 32, 116, 104, 101, 32, 100, 111, 99, 117, 109, + 101, 110, 116, 46, + ]); + + var ciphertext = { + 128: { + 64: new Uint8Array([ + 65, 221, 187, 210, 119, 207, 141, 109, 144, 97, 82, 124, 60, 189, 176, + 2, 250, 48, 64, 29, 197, 22, 59, 96, 246, 211, 155, 184, 126, 116, 79, + 37, 168, 109, 191, 38, 77, 90, 74, 112, 222, 105, 173, 190, 182, 226, + 244, 47, 130, 191, 207, 190, 105, 186, 153, 58, 132, 212, 108, 156, 108, + 30, 56, 180, 7, 133, 144, 169, 249, 120, 191, 16, 40, 13, 157, 127, 170, + 134, 193, 12, 39, 84, 117, 13, 68, 26, 4, 52, 188, 51, 30, 55, 171, 181, + 255, 252, 12, 238, 46, 197, 114, 255, 125, 171, 6, 162, 40, 42, 217, + 221, 127, 164, 14, 171, 249, 105, 12, 133, 246, 205, 161, 97, 238, 208, + 179, 30, 161, 182, 134, 100, 112, 205, 93, 101, 69, 254, 253, 201, 244, + 67, 2, 87, 172, 247, 144, 141, 88, 80, 236, 188, 190, 73, 179, 253, 211, + 142, 98, 141, 16, 97, 166, 2, 71, 224, 232, 44, 238, 82, 33, 16, 32, + 224, 111, 191, 89, 157, 99, 127, 28, 95, 175, 15, 86, 10, 44, 180, 127, + 200, 162, 37, 138, 69, 78, 119, 165, 96, 98, 107, 211, 122, 21, 49, 124, + 60, 156, 38, 20, 22, 196, 86, 20, 182, 173, 23, 42, 42, 26, 213, 84, 21, + 160, 156, 96, 20, 234, 208, 177, 44, 112, 110, 165, 233, 20, 56, 123, + 110, 129, 57, 158, 148, 98, 241, 47, 148, 113, 198, 10, 80, 16, 221, 91, + 8, 192, 194, 190, 183, 113, 67, 134, 234, 239, 20, 108, 150, 83, 106, + 209, 112, 93, 196, 12, 135, 2, 177, 151, 168, 46, 202, 197, 22, 24, 48, + 105, 76, 218, 21, 229, 45, 127, 109, 93, 38, 189, 215, 123, 110, 23, + 110, 94, 232, 46, 167, 50, 5, 212, 120, 69, 230, 35, 149, 228, 24, 115, + 134, 10, 187, 73, 79, 197, 47, 5, 200, 142, 166, 159, 51, 154, 199, 178, + 88, 127, 240, 228, 141, 20, 122, 191, 173, 66, 120, 130, 223, 180, 218, + 107, 134, 224, 251, 127, 180, 17, 196, 223, 182, 230, 5, 217, 23, 146, + 3, 251, 129, 27, 162, 223, 19, 72, 108, 117, 51, 77, 53, 21, 158, 135, + 114, 157, 8, 166, 80, 246, 162, 103, 61, 116, 188, 30, 201, 112, 239, + 13, 244, 46, 123, 193, 206, 91, 17, 188, 78, 81, 21, 226, 218, 56, 177, + 139, 17, 4, 94, 165, 250, 207, 170, 141, 211, 247, 201, 101, 122, 198, + 121, 99, 24, 177, 98, 188, 192, 252, 96, 181, 110, 111, 154, 144, 57, + 141, 114, 50, 228, 192, 154, 123, 241, 143, 78, 250, 156, 140, 128, 195, + 151, 145, 153, 130, 43, 154, 34, 187, 242, 243, 55, 91, 154, 149, 193, + 214, 82, 249, 212, 79, 131, 230, 179, 4, 251, 6, 135, 210, + ]), + 96: new Uint8Array([ + 116, 195, 75, 212, 107, 179, 95, 161, 75, 160, 249, 225, 187, 238, 165, + 13, 225, 89, 223, 89, 247, 241, 11, 92, 196, 16, 218, 185, 132, 72, 201, + 90, 151, 176, 56, 167, 227, 75, 251, 171, 9, 230, 136, 101, 165, 140, + 144, 22, 130, 178, 45, 119, 40, 202, 73, 204, 59, 237, 19, 47, 69, 34, + 127, 34, 196, 150, 65, 6, 136, 178, 159, 166, 234, 195, 139, 124, 71, + 183, 154, 189, 142, 34, 209, 19, 109, 149, 154, 26, 36, 158, 109, 31, + 190, 39, 74, 118, 167, 66, 245, 31, 194, 58, 64, 46, 213, 32, 51, 61, + 99, 255, 236, 134, 87, 67, 205, 192, 77, 30, 212, 51, 205, 55, 48, 97, + 58, 122, 86, 165, 33, 32, 26, 107, 122, 32, 144, 192, 102, 53, 27, 207, + 166, 61, 8, 83, 123, 162, 237, 209, 52, 220, 100, 99, 252, 157, 115, 97, + 137, 98, 13, 37, 66, 141, 94, 27, 132, 24, 161, 6, 146, 159, 64, 240, + 12, 236, 45, 211, 121, 194, 184, 143, 35, 72, 204, 231, 168, 226, 36, + 45, 74, 47, 14, 6, 145, 68, 119, 196, 6, 33, 184, 155, 10, 103, 94, 180, + 175, 13, 58, 121, 37, 97, 80, 149, 175, 240, 167, 3, 254, 122, 3, 118, + 188, 137, 32, 147, 123, 245, 29, 189, 97, 44, 140, 137, 54, 145, 241, + 216, 160, 47, 140, 30, 149, 239, 122, 103, 54, 19, 187, 73, 59, 34, 32, + 43, 35, 220, 167, 180, 220, 124, 110, 51, 23, 64, 127, 6, 30, 38, 106, + 45, 42, 110, 9, 180, 158, 251, 255, 129, 18, 243, 116, 251, 159, 139, + 229, 108, 48, 105, 120, 222, 118, 220, 127, 69, 198, 116, 126, 157, 164, + 161, 225, 120, 220, 253, 158, 92, 159, 214, 175, 116, 80, 57, 117, 10, + 174, 133, 166, 182, 43, 186, 233, 10, 174, 82, 7, 161, 197, 165, 60, 70, + 113, 150, 15, 32, 165, 11, 7, 160, 110, 61, 1, 45, 216, 51, 129, 171, + 156, 35, 46, 21, 160, 21, 217, 135, 223, 231, 180, 30, 163, 75, 251, + 151, 13, 2, 165, 71, 12, 38, 185, 208, 103, 132, 136, 73, 173, 99, 67, + 169, 126, 185, 180, 61, 216, 206, 192, 69, 228, 190, 244, 233, 172, 97, + 32, 74, 219, 254, 70, 177, 179, 196, 75, 157, 11, 108, 94, 240, 84, 26, + 219, 200, 255, 236, 109, 139, 188, 99, 38, 221, 10, 173, 108, 25, 42, + 87, 1, 15, 171, 197, 255, 190, 222, 21, 27, 162, 150, 52, 79, 82, 61, + 156, 95, 231, 170, 247, 189, 177, 91, 62, 24, 26, 66, 113, 207, 66, 208, + 101, 215, 18, 106, 161, 240, 66, 216, 91, 12, 247, 50, 232, 243, 96, + 153, 226, 0, 85, 234, 218, 24, 209, 91, 40, 119, + ]), + 128: new Uint8Array([ + 49, 92, 208, 197, 89, 61, 226, 4, 124, 46, 215, 121, 228, 211, 234, 42, + 228, 175, 236, 139, 48, 88, 75, 81, 194, 242, 144, 113, 49, 107, 153, + 91, 135, 221, 210, 102, 120, 174, 103, 144, 201, 223, 73, 220, 52, 117, + 71, 100, 200, 29, 53, 86, 15, 223, 21, 208, 205, 235, 143, 137, 20, 119, + 193, 77, 202, 117, 62, 20, 39, 157, 85, 48, 135, 76, 115, 241, 39, 71, + 58, 175, 227, 190, 64, 21, 64, 94, 46, 23, 236, 68, 228, 232, 9, 173, + 189, 162, 99, 0, 228, 110, 126, 8, 201, 183, 37, 172, 191, 149, 98, 96, + 190, 93, 21, 108, 250, 83, 149, 235, 38, 47, 205, 15, 126, 188, 69, 200, + 178, 132, 63, 116, 9, 89, 227, 110, 115, 250, 82, 41, 127, 44, 44, 95, + 2, 188, 67, 31, 123, 23, 121, 60, 11, 57, 146, 245, 14, 63, 131, 212, + 70, 39, 237, 148, 226, 126, 245, 4, 174, 239, 64, 127, 108, 246, 211, + 172, 76, 129, 133, 114, 144, 243, 157, 85, 126, 67, 101, 193, 205, 115, + 147, 154, 82, 92, 32, 82, 7, 40, 163, 152, 135, 62, 137, 29, 117, 164, + 82, 220, 169, 224, 143, 118, 130, 116, 210, 192, 45, 21, 202, 180, 252, + 72, 223, 37, 224, 154, 14, 52, 252, 153, 243, 241, 101, 228, 169, 188, + 91, 20, 119, 49, 215, 112, 180, 244, 102, 26, 123, 94, 250, 63, 36, 156, + 254, 72, 225, 33, 180, 108, 96, 144, 43, 26, 44, 147, 195, 58, 74, 188, + 48, 178, 233, 158, 184, 251, 207, 70, 42, 124, 191, 10, 142, 13, 130, + 222, 97, 24, 216, 13, 111, 188, 209, 145, 9, 81, 32, 53, 159, 247, 165, + 109, 23, 212, 131, 80, 125, 44, 237, 63, 104, 111, 84, 12, 22, 195, 48, + 171, 1, 221, 172, 65, 132, 75, 54, 235, 129, 152, 248, 227, 81, 170, + 220, 45, 168, 254, 108, 166, 239, 192, 71, 199, 119, 252, 101, 90, 159, + 133, 248, 214, 245, 83, 8, 217, 202, 215, 29, 69, 73, 250, 186, 230, + 158, 38, 213, 179, 92, 183, 241, 197, 186, 114, 90, 108, 0, 246, 194, + 242, 123, 127, 244, 6, 161, 3, 238, 127, 234, 245, 30, 79, 93, 202, 103, + 93, 90, 123, 42, 105, 133, 230, 80, 159, 209, 198, 122, 153, 200, 38, 1, + 119, 89, 40, 42, 162, 183, 5, 77, 10, 161, 143, 128, 251, 104, 4, 132, + 172, 252, 146, 144, 5, 183, 31, 140, 54, 31, 155, 234, 110, 129, 41, 12, + 125, 231, 187, 49, 210, 196, 213, 85, 155, 135, 129, 33, 96, 71, 253, + 244, 140, 117, 80, 36, 107, 236, 198, 170, 93, 149, 112, 64, 167, 32, + 143, 89, 143, 151, 253, 118, 59, 152, 246, 197, 148, 87, + ]), + }, + 192: { + 64: new Uint8Array([ + 230, 126, 210, 64, 27, 223, 123, 87, 122, 27, 240, 255, 220, 9, 217, + 113, 209, 54, 104, 143, 75, 65, 22, 34, 143, 217, 125, 37, 22, 29, 228, + 59, 123, 35, 39, 168, 216, 34, 178, 27, 23, 2, 108, 156, 74, 59, 68, 37, + 72, 191, 103, 170, 5, 2, 135, 227, 184, 211, 164, 153, 218, 48, 90, 37, + 136, 121, 86, 64, 4, 82, 145, 246, 235, 198, 169, 107, 229, 27, 247, + 230, 135, 150, 159, 182, 144, 41, 179, 62, 165, 94, 254, 201, 0, 154, + 65, 65, 216, 72, 6, 168, 73, 12, 74, 128, 150, 168, 38, 163, 62, 77, + 179, 88, 120, 191, 70, 185, 188, 14, 91, 116, 185, 128, 135, 150, 50, + 123, 200, 159, 100, 17, 39, 252, 28, 205, 178, 33, 89, 38, 52, 123, 62, + 85, 53, 99, 7, 143, 251, 194, 35, 153, 127, 170, 170, 196, 49, 26, 173, + 5, 190, 15, 185, 34, 3, 254, 169, 95, 254, 109, 107, 7, 254, 149, 189, + 54, 172, 21, 89, 57, 250, 142, 107, 52, 143, 25, 83, 242, 125, 164, 108, + 123, 135, 38, 72, 139, 33, 67, 246, 22, 71, 216, 1, 128, 238, 244, 183, + 144, 106, 177, 152, 169, 193, 97, 57, 218, 121, 53, 200, 85, 61, 26, + 156, 185, 74, 142, 12, 182, 112, 60, 214, 31, 147, 104, 74, 50, 68, 47, + 1, 245, 149, 208, 28, 213, 73, 244, 216, 102, 65, 94, 64, 216, 224, 236, + 101, 112, 27, 197, 173, 24, 57, 113, 99, 177, 142, 1, 171, 72, 254, 171, + 22, 70, 158, 151, 38, 219, 190, 107, 118, 120, 18, 39, 200, 17, 44, 250, + 121, 78, 49, 44, 187, 223, 134, 150, 207, 123, 250, 209, 250, 91, 203, + 131, 236, 131, 82, 165, 175, 246, 8, 55, 98, 135, 105, 141, 207, 131, + 169, 92, 148, 234, 13, 33, 215, 126, 121, 79, 174, 229, 42, 135, 172, + 199, 29, 142, 254, 73, 147, 110, 82, 107, 73, 122, 38, 106, 133, 28, 33, + 99, 115, 142, 73, 102, 122, 194, 151, 243, 104, 200, 122, 52, 201, 180, + 5, 195, 223, 19, 221, 195, 38, 62, 238, 66, 197, 180, 8, 194, 249, 139, + 184, 87, 205, 207, 79, 160, 235, 137, 193, 81, 49, 20, 218, 226, 249, + 32, 197, 193, 143, 173, 135, 146, 152, 198, 189, 21, 80, 161, 225, 20, + 44, 28, 87, 151, 222, 180, 191, 147, 89, 79, 159, 46, 8, 174, 242, 173, + 54, 58, 108, 112, 51, 95, 90, 140, 162, 50, 162, 242, 239, 220, 190, 76, + 78, 7, 156, 25, 190, 195, 71, 140, 32, 133, 98, 48, 203, 145, 214, 207, + 212, 109, 186, 12, 122, 209, 88, 201, 225, 247, 228, 89, 217, 124, 40, + 136, 40, 105, 54, 45, 243, 34, 202, 122, 55, + ]), + 96: new Uint8Array([ + 132, 13, 203, 226, 200, 159, 255, 134, 178, 251, 192, 7, 168, 139, 69, + 151, 15, 76, 167, 58, 233, 112, 100, 150, 84, 45, 29, 94, 122, 99, 230, + 41, 34, 122, 29, 128, 62, 131, 131, 106, 56, 178, 85, 246, 149, 62, 58, + 73, 131, 69, 95, 9, 125, 68, 134, 101, 107, 127, 164, 64, 79, 128, 216, + 94, 211, 163, 140, 197, 201, 174, 95, 47, 215, 67, 28, 93, 125, 87, 5, + 157, 157, 150, 235, 54, 190, 253, 190, 151, 39, 71, 138, 188, 196, 55, + 214, 194, 216, 197, 193, 30, 18, 55, 117, 168, 203, 123, 197, 84, 190, + 4, 135, 13, 212, 108, 59, 14, 8, 255, 49, 166, 157, 253, 216, 103, 74, + 152, 68, 179, 21, 124, 56, 98, 2, 13, 56, 133, 185, 239, 108, 246, 173, + 114, 194, 183, 157, 166, 170, 61, 249, 240, 253, 78, 107, 244, 251, 114, + 90, 201, 3, 64, 5, 68, 164, 70, 2, 139, 27, 75, 229, 60, 168, 15, 109, + 217, 93, 38, 14, 122, 225, 245, 113, 185, 37, 61, 8, 153, 60, 225, 6, + 49, 248, 101, 16, 162, 55, 41, 79, 191, 79, 0, 104, 167, 171, 175, 96, + 69, 116, 225, 44, 4, 117, 255, 82, 168, 255, 95, 62, 39, 77, 251, 211, + 42, 221, 90, 192, 142, 52, 240, 119, 4, 26, 0, 136, 187, 8, 92, 46, 69, + 217, 107, 92, 192, 206, 122, 228, 115, 123, 224, 235, 27, 204, 72, 15, + 246, 243, 172, 141, 129, 129, 96, 120, 167, 208, 186, 170, 16, 3, 10, + 146, 100, 95, 28, 41, 163, 211, 40, 77, 187, 217, 141, 147, 141, 215, + 101, 50, 10, 225, 22, 102, 148, 115, 220, 235, 159, 136, 0, 245, 201, + 45, 174, 140, 128, 60, 57, 238, 33, 71, 145, 195, 187, 98, 115, 79, 70, + 85, 11, 10, 37, 89, 30, 59, 241, 150, 21, 20, 158, 15, 111, 55, 227, + 138, 234, 113, 237, 16, 92, 32, 85, 173, 79, 80, 151, 1, 202, 148, 4, + 247, 4, 19, 114, 17, 83, 60, 174, 13, 242, 255, 77, 103, 112, 220, 175, + 143, 73, 255, 164, 32, 209, 165, 7, 17, 51, 95, 98, 98, 9, 170, 136, + 179, 179, 122, 180, 115, 60, 76, 92, 124, 97, 134, 34, 209, 138, 173, + 52, 144, 198, 210, 65, 240, 232, 194, 102, 215, 57, 209, 249, 162, 186, + 251, 107, 194, 55, 93, 49, 158, 141, 151, 29, 85, 178, 187, 73, 174, + 206, 197, 135, 7, 117, 76, 208, 59, 37, 168, 196, 150, 125, 82, 32, 101, + 229, 47, 20, 231, 224, 208, 205, 103, 39, 136, 197, 8, 66, 25, 19, 91, + 157, 123, 213, 142, 207, 53, 34, 100, 146, 196, 181, 54, 115, 242, 134, + 71, 153, 64, 32, 151, 37, 181, 179, 131, + ]), + 128: new Uint8Array([ + 172, 222, 17, 53, 142, 131, 16, 112, 148, 160, 79, 191, 5, 172, 129, + 112, 79, 90, 10, 162, 240, 209, 201, 207, 100, 52, 153, 61, 37, 216, + 137, 35, 142, 99, 209, 82, 244, 65, 66, 25, 82, 51, 177, 215, 205, 186, + 26, 231, 35, 77, 183, 158, 2, 85, 85, 54, 45, 173, 171, 64, 55, 163, 85, + 156, 195, 233, 202, 181, 242, 4, 201, 192, 184, 81, 229, 4, 65, 89, 83, + 58, 140, 233, 220, 30, 221, 24, 104, 155, 113, 179, 164, 194, 143, 100, + 108, 255, 133, 158, 186, 81, 246, 19, 213, 152, 20, 181, 156, 221, 80, + 155, 52, 165, 110, 110, 51, 98, 218, 67, 126, 70, 74, 25, 101, 181, 54, + 32, 62, 22, 38, 243, 218, 217, 224, 49, 15, 181, 96, 177, 93, 36, 218, + 19, 142, 25, 12, 20, 66, 122, 72, 96, 182, 69, 194, 143, 173, 72, 132, + 40, 97, 0, 98, 206, 214, 118, 234, 32, 185, 173, 65, 104, 220, 81, 128, + 207, 186, 60, 227, 171, 80, 196, 67, 237, 218, 103, 16, 154, 18, 58, 29, + 124, 86, 161, 216, 59, 205, 122, 23, 166, 22, 136, 80, 67, 228, 132, 20, + 100, 235, 125, 56, 231, 10, 29, 111, 249, 1, 125, 59, 173, 25, 60, 107, + 118, 35, 211, 93, 252, 189, 135, 5, 251, 160, 170, 121, 198, 203, 242, + 108, 154, 143, 143, 167, 77, 27, 202, 162, 58, 219, 159, 208, 74, 116, + 146, 8, 227, 145, 32, 231, 145, 78, 29, 110, 79, 246, 106, 218, 5, 202, + 4, 79, 69, 112, 139, 36, 137, 77, 132, 15, 26, 125, 187, 3, 98, 149, + 172, 11, 201, 242, 212, 5, 244, 210, 63, 197, 160, 216, 194, 35, 74, + 116, 53, 127, 11, 70, 69, 25, 195, 157, 75, 169, 240, 184, 236, 131, + 104, 243, 12, 32, 139, 246, 20, 22, 149, 253, 137, 103, 11, 199, 85, + 145, 88, 152, 31, 102, 8, 226, 185, 115, 210, 153, 241, 105, 41, 164, + 65, 210, 247, 28, 185, 216, 26, 74, 32, 208, 20, 254, 201, 173, 45, 192, + 243, 151, 156, 22, 29, 4, 250, 59, 15, 125, 112, 38, 218, 230, 89, 182, + 216, 251, 141, 86, 65, 147, 78, 171, 220, 123, 79, 14, 28, 73, 35, 227, + 214, 61, 118, 91, 56, 182, 171, 190, 0, 196, 183, 205, 224, 179, 29, + 123, 79, 67, 248, 156, 250, 173, 92, 32, 89, 252, 20, 112, 250, 219, + 187, 51, 109, 173, 20, 19, 88, 149, 206, 102, 150, 251, 139, 137, 104, + 179, 29, 128, 165, 228, 14, 55, 184, 85, 73, 78, 198, 112, 137, 133, + 132, 223, 49, 171, 100, 40, 177, 97, 153, 153, 50, 86, 82, 153, 23, 227, + 55, 16, 239, 224, 74, 239, 208, 80, 64, 238, 36, 64, + ]), + }, + 256: { + 64: new Uint8Array([ + 42, 122, 195, 47, 242, 151, 101, 162, 101, 255, 99, 154, 224, 195, 92, + 248, 62, 224, 73, 134, 218, 18, 207, 64, 34, 188, 37, 139, 135, 132, + 178, 80, 244, 149, 22, 190, 205, 14, 120, 36, 241, 73, 196, 230, 144, + 48, 10, 52, 227, 132, 142, 37, 199, 193, 167, 242, 146, 172, 125, 190, + 111, 107, 29, 218, 95, 10, 24, 162, 250, 237, 42, 240, 107, 214, 253, + 11, 18, 236, 167, 248, 233, 98, 122, 74, 94, 29, 90, 98, 107, 98, 178, + 148, 102, 238, 93, 28, 197, 119, 140, 62, 205, 204, 229, 84, 198, 168, + 170, 47, 97, 127, 232, 162, 156, 85, 46, 2, 81, 96, 153, 67, 23, 223, + 201, 64, 215, 8, 152, 238, 39, 205, 242, 222, 161, 125, 81, 100, 166, + 103, 191, 70, 4, 24, 126, 204, 204, 216, 77, 210, 39, 126, 68, 208, 31, + 221, 153, 21, 166, 245, 12, 139, 238, 215, 21, 68, 91, 59, 106, 205, 20, + 138, 164, 216, 235, 18, 139, 238, 23, 220, 166, 247, 54, 166, 185, 102, + 218, 77, 20, 69, 145, 81, 157, 32, 62, 167, 232, 193, 81, 221, 5, 138, + 93, 240, 94, 9, 223, 96, 46, 65, 167, 231, 28, 47, 16, 48, 87, 239, 185, + 72, 21, 132, 227, 206, 251, 37, 166, 50, 118, 197, 248, 64, 129, 84, 25, + 184, 74, 102, 126, 62, 175, 219, 69, 233, 83, 180, 112, 231, 104, 17, + 162, 120, 19, 146, 230, 211, 181, 187, 121, 151, 110, 83, 152, 88, 224, + 81, 234, 167, 191, 180, 145, 69, 42, 97, 189, 59, 32, 36, 121, 23, 106, + 2, 198, 208, 200, 232, 197, 127, 104, 238, 30, 49, 37, 220, 153, 25, 36, + 96, 53, 253, 20, 59, 122, 72, 50, 197, 16, 9, 102, 190, 188, 95, 113, + 255, 253, 136, 247, 39, 35, 43, 124, 93, 159, 52, 248, 12, 4, 233, 216, + 253, 170, 123, 111, 76, 224, 35, 113, 53, 126, 194, 172, 229, 216, 163, + 177, 55, 225, 31, 242, 219, 59, 104, 84, 95, 230, 173, 139, 102, 217, + 206, 170, 79, 220, 33, 216, 100, 24, 54, 225, 138, 241, 184, 180, 190, + 65, 101, 64, 209, 84, 82, 107, 99, 199, 188, 126, 85, 237, 106, 85, 97, + 109, 152, 114, 68, 214, 13, 215, 208, 77, 228, 125, 36, 113, 143, 40, + 104, 105, 42, 160, 138, 201, 58, 173, 97, 31, 73, 96, 220, 218, 63, 101, + 131, 161, 99, 36, 107, 70, 232, 143, 233, 64, 109, 3, 89, 80, 79, 147, + 223, 186, 180, 232, 99, 137, 47, 130, 130, 227, 174, 161, 131, 211, 5, + 6, 169, 210, 68, 49, 152, 210, 70, 210, 75, 46, 133, 24, 138, 63, 41, + 254, 46, 92, 29, 148, 139, 150, 124, 53, 154, 40, 125, 184, + ]), + 96: new Uint8Array([ + 8, 102, 85, 24, 18, 25, 224, 27, 71, 136, 174, 49, 44, 70, 3, 134, 50, + 142, 118, 190, 26, 134, 96, 28, 29, 151, 90, 212, 124, 33, 86, 73, 247, + 172, 101, 73, 99, 51, 28, 123, 101, 20, 186, 236, 249, 17, 89, 105, 48, + 128, 151, 50, 93, 151, 46, 113, 98, 89, 193, 181, 91, 95, 77, 224, 62, + 103, 85, 227, 225, 150, 74, 186, 111, 210, 191, 96, 139, 219, 197, 202, + 185, 156, 118, 95, 230, 43, 186, 92, 133, 85, 90, 107, 176, 121, 164, + 25, 232, 22, 79, 98, 21, 37, 150, 122, 151, 22, 49, 221, 149, 228, 165, + 53, 163, 157, 218, 40, 128, 247, 125, 116, 42, 252, 80, 143, 44, 79, 52, + 153, 221, 254, 115, 231, 255, 29, 249, 235, 60, 149, 212, 14, 103, 143, + 239, 39, 57, 183, 23, 139, 190, 146, 207, 84, 170, 117, 27, 160, 109, + 217, 118, 197, 56, 14, 228, 108, 59, 11, 166, 84, 46, 207, 87, 109, 212, + 113, 6, 158, 49, 252, 112, 38, 95, 253, 59, 18, 195, 124, 108, 60, 230, + 138, 103, 199, 158, 34, 140, 2, 60, 104, 93, 15, 127, 13, 213, 72, 82, + 242, 70, 51, 188, 219, 123, 148, 125, 0, 226, 119, 218, 135, 74, 219, 0, + 116, 129, 230, 49, 133, 186, 228, 114, 170, 152, 222, 231, 60, 85, 229, + 146, 76, 34, 92, 57, 161, 211, 106, 223, 251, 16, 31, 42, 163, 190, 19, + 67, 237, 78, 82, 242, 135, 152, 140, 12, 34, 232, 215, 56, 117, 225, 92, + 29, 56, 249, 12, 136, 44, 195, 115, 175, 86, 176, 251, 246, 149, 17, 67, + 18, 226, 215, 52, 126, 140, 119, 205, 9, 138, 185, 11, 21, 210, 215, 52, + 234, 13, 171, 13, 168, 71, 178, 24, 175, 209, 164, 182, 90, 132, 104, + 88, 175, 129, 25, 53, 51, 132, 43, 225, 82, 12, 125, 177, 8, 68, 184, + 168, 135, 79, 127, 160, 112, 18, 117, 137, 175, 135, 23, 122, 238, 110, + 224, 32, 177, 162, 2, 200, 170, 62, 139, 183, 96, 210, 132, 22, 230, + 197, 166, 4, 127, 186, 4, 11, 147, 125, 123, 31, 71, 220, 206, 25, 91, + 135, 176, 55, 150, 148, 159, 73, 142, 137, 109, 184, 172, 143, 223, 118, + 220, 21, 92, 22, 144, 145, 204, 222, 164, 40, 56, 144, 253, 200, 219, + 70, 159, 251, 89, 13, 27, 62, 211, 44, 4, 89, 34, 6, 81, 123, 142, 144, + 63, 122, 74, 121, 66, 98, 160, 226, 178, 184, 13, 56, 212, 177, 162, + 214, 107, 239, 112, 67, 97, 211, 100, 38, 48, 89, 55, 43, 173, 74, 81, + 247, 72, 196, 31, 152, 132, 167, 132, 232, 240, 73, 225, 252, 186, 103, + 65, 197, 95, 79, 190, 202, 199, 182, 30, + ]), + 128: new Uint8Array([ + 247, 183, 56, 230, 246, 46, 162, 70, 247, 246, 214, 170, 243, 1, 197, + 73, 188, 188, 253, 79, 5, 63, 235, 32, 61, 2, 135, 174, 66, 13, 110, 77, + 89, 249, 180, 203, 225, 161, 112, 6, 217, 62, 96, 222, 238, 42, 76, 81, + 41, 12, 187, 140, 225, 49, 193, 165, 51, 125, 79, 95, 79, 140, 193, 53, + 147, 58, 73, 206, 75, 28, 178, 255, 124, 220, 141, 248, 11, 130, 211, + 148, 36, 115, 66, 133, 114, 219, 41, 90, 201, 225, 240, 25, 233, 239, + 110, 175, 233, 207, 223, 13, 129, 245, 124, 77, 173, 19, 62, 7, 22, 55, + 79, 56, 148, 81, 213, 239, 255, 23, 132, 225, 207, 130, 195, 45, 115, + 237, 36, 105, 106, 95, 62, 250, 183, 23, 62, 172, 87, 15, 139, 60, 13, + 8, 12, 60, 212, 69, 2, 137, 206, 157, 5, 5, 208, 88, 239, 38, 66, 209, + 89, 249, 233, 204, 234, 243, 150, 62, 39, 239, 6, 147, 24, 223, 89, 200, + 28, 71, 113, 82, 111, 158, 97, 80, 166, 158, 193, 37, 61, 243, 226, 36, + 74, 98, 100, 80, 23, 116, 2, 197, 166, 215, 15, 212, 200, 39, 158, 192, + 97, 41, 120, 126, 200, 10, 14, 201, 47, 150, 155, 118, 5, 119, 69, 169, + 122, 101, 0, 53, 174, 213, 241, 113, 111, 45, 227, 192, 153, 57, 59, + 148, 204, 203, 4, 114, 173, 122, 35, 128, 86, 74, 117, 43, 249, 245, + 245, 189, 222, 38, 98, 160, 211, 192, 65, 35, 5, 104, 72, 228, 83, 6, + 63, 157, 104, 226, 100, 205, 173, 67, 195, 174, 136, 151, 121, 2, 185, + 9, 32, 177, 78, 69, 118, 135, 126, 133, 188, 174, 167, 71, 145, 26, 48, + 23, 115, 144, 53, 124, 5, 36, 76, 244, 32, 116, 35, 155, 107, 193, 161, + 41, 81, 122, 111, 52, 74, 213, 130, 0, 60, 106, 213, 206, 3, 31, 163, + 46, 89, 163, 125, 9, 166, 34, 140, 58, 197, 28, 161, 107, 214, 237, 192, + 235, 113, 62, 222, 48, 124, 237, 102, 8, 215, 70, 116, 112, 201, 21, + 188, 99, 168, 0, 245, 141, 97, 163, 240, 234, 230, 42, 134, 77, 250, 9, + 30, 73, 136, 108, 100, 91, 54, 193, 19, 242, 218, 174, 129, 149, 149, + 56, 220, 168, 136, 149, 165, 196, 193, 214, 9, 189, 178, 121, 125, 238, + 225, 150, 81, 114, 215, 244, 2, 171, 123, 45, 83, 175, 65, 120, 125, 65, + 98, 66, 122, 8, 253, 183, 81, 93, 13, 71, 147, 163, 245, 198, 78, 141, + 200, 3, 1, 1, 60, 34, 46, 52, 46, 213, 222, 143, 177, 236, 188, 27, 12, + 196, 226, 219, 63, 126, 245, 17, 169, 83, 29, 86, 47, 251, 205, 223, 97, + 164, 34, 187, 82, 137, 186, + ]), + }, + }; + + var tag = { + 128: { + 64: new Uint8Array([85, 92, 121, 149, 117, 105, 131, 236]), + 96: new Uint8Array([ + 39, 4, 154, 219, 88, 182, 182, 27, 184, 126, 226, 69, + ]), + 128: new Uint8Array([ + 190, 170, 111, 11, 63, 177, 149, 125, 124, 144, 202, 221, 51, 245, 203, + 188, + ]), + }, + 192: { + 64: new Uint8Array([100, 170, 171, 3, 209, 173, 29, 9]), + 96: new Uint8Array([ + 235, 102, 97, 102, 35, 247, 179, 20, 48, 178, 86, 104, + ]), + 128: new Uint8Array([ + 228, 42, 50, 235, 55, 252, 87, 200, 249, 71, 204, 140, 90, 9, 38, 109, + ]), + }, + 256: { + 64: new Uint8Array([88, 161, 48, 15, 218, 241, 79, 9]), + 96: new Uint8Array([ + 123, 79, 227, 34, 149, 144, 168, 116, 29, 123, 134, 54, + ]), + 128: new Uint8Array([ + 143, 242, 94, 93, 210, 173, 212, 13, 233, 94, 15, 187, 5, 111, 216, 142, + ]), + }, + }; + + var tag_with_empty_ad = { + 128: { + 64: new Uint8Array([29, 208, 61, 213, 245, 103, 78, 0]), + 96: new Uint8Array([ + 111, 136, 222, 155, 216, 184, 123, 247, 168, 80, 240, 223, + ]), + 128: new Uint8Array([ + 246, 38, 43, 75, 191, 191, 88, 145, 108, 190, 216, 71, 41, 68, 90, 105, + ]), + }, + 192: { + 64: new Uint8Array([169, 228, 25, 72, 206, 76, 237, 60]), + 96: new Uint8Array([38, 40, 211, 45, 60, 22, 67, 33, 0, 223, 249, 228]), + 128: new Uint8Array([ + 41, 100, 128, 160, 40, 29, 167, 253, 201, 42, 99, 0, 110, 206, 121, 229, + ]), + }, + 256: { + 64: new Uint8Array([207, 100, 186, 166, 40, 99, 3, 95]), + 96: new Uint8Array([ + 236, 138, 105, 139, 103, 2, 228, 34, 208, 41, 194, 207, + ]), + 128: new Uint8Array([ + 24, 55, 212, 244, 32, 63, 152, 91, 36, 12, 75, 66, 69, 145, 236, 130, + ]), + }, + }; + + return { + plaintext, + keyBytes, + iv, + additionalData, + tag, + tag_with_empty_ad, + ciphertext, + }; +} diff --git a/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/aes_ocb_vectors.js b/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/aes_ocb_vectors.js new file mode 100644 index 00000000000000..eba4ecfcc5d72c --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/aes_ocb_vectors.js @@ -0,0 +1,142 @@ +// aes_ocb_vectors.js + +// The following function returns an array of test vectors +// for the subtleCrypto encrypt method. +// +// Each test vector has the following fields: +// name - a unique name for this vector +// keyBuffer - an arrayBuffer with the key data in raw form +// key - a CryptoKey object for the keyBuffer. INITIALLY null! You must fill this in first to use it! +// algorithm - the value of the AlgorithmIdentifier parameter to provide to encrypt +// plaintext - the text to encrypt +// result - the expected result (usually just ciphertext, sometimes with added authentication) +function getTestVectors() { + const { + plaintext, + keyBytes, + iv, + additionalData, + tag, + tag_with_empty_ad, + ciphertext, + } = getFixtures(); + + var keyLengths = [128, 192, 256]; + var tagLengths = [64, 96, 128]; + + // All the scenarios that should succeed, if the key has "encrypt" usage + var passing = []; + keyLengths.forEach(function (keyLength) { + tagLengths.forEach(function (tagLength) { + var byteCount = tagLength / 8; + + var result = new Uint8Array( + ciphertext[keyLength][tagLength].byteLength + byteCount + ); + result.set(ciphertext[keyLength][tagLength], 0); + result.set( + tag[keyLength][tagLength].slice(0, byteCount), + ciphertext[keyLength][tagLength].byteLength + ); + passing.push({ + name: + 'AES-OCB ' + + keyLength.toString() + + '-bit key, ' + + tagLength.toString() + + '-bit tag, ' + + (iv.byteLength << 3).toString() + + '-bit iv', + keyBuffer: keyBytes[keyLength], + key: null, + algorithm: { + name: 'AES-OCB', + iv: iv, + additionalData: additionalData, + tagLength: tagLength, + }, + plaintext: plaintext, + result: result, + }); + + var noadresult = new Uint8Array( + ciphertext[keyLength][tagLength].byteLength + byteCount + ); + noadresult.set(ciphertext[keyLength][tagLength], 0); + noadresult.set( + tag_with_empty_ad[keyLength][tagLength].slice(0, byteCount), + ciphertext[keyLength][tagLength].byteLength + ); + passing.push({ + name: + 'AES-OCB ' + + keyLength.toString() + + '-bit key, no additional data, ' + + tagLength.toString() + + '-bit tag, ' + + (iv.byteLength << 3).toString() + + '-bit iv', + keyBuffer: keyBytes[keyLength], + key: null, + algorithm: { name: 'AES-OCB', iv: iv, tagLength: tagLength }, + plaintext: plaintext, + result: noadresult, + }); + }); + }); + + // Scenarios that should fail because of a bad tag length, causing an OperationError + var failing = []; + keyLengths.forEach(function (keyLength) { + // First, make some tests for bad tag lengths + [24, 48, 72, 95, 129].forEach(function (badTagLength) { + failing.push({ + name: + 'AES-OCB ' + + keyLength.toString() + + '-bit key, ' + + (iv.byteLength << 3).toString() + + '-bit iv, ' + + 'illegal tag length ' + + badTagLength.toString() + + '-bits', + keyBuffer: keyBytes[keyLength], + key: null, + algorithm: { + name: 'AES-OCB', + iv: iv, + additionalData: additionalData, + tagLength: badTagLength, + }, + plaintext: plaintext, + result: ciphertext[keyLength][128], + }); + }); + + // Add tests for bad IV lengths + [0, 16].forEach(function (badIvLength) { + var badIv = new Uint8Array(badIvLength); + failing.push({ + name: + 'AES-OCB ' + + keyLength.toString() + + '-bit key, ' + + 'illegal iv length ' + + (badIvLength << 3).toString() + + '-bits', + keyBuffer: keyBytes[keyLength], + key: null, + algorithm: { + name: 'AES-OCB', + iv: badIv, + additionalData: additionalData, + tagLength: 128, + }, + plaintext: plaintext, + result: ciphertext[keyLength][128], + }); + }); + }); + + return { passing: passing, failing: failing, decryptionFailing: [] }; +} diff --git a/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/chacha20_poly1305.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/chacha20_poly1305.tentative.https.any.js new file mode 100644 index 00000000000000..ed21fb5d7260e3 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/encrypt_decrypt/chacha20_poly1305.tentative.https.any.js @@ -0,0 +1,340 @@ +// META: title=WebCryptoAPI: encrypt()/decrypt() ChaCha20-Poly1305 +// META: timeout=long + +var subtle = crypto.subtle; // Change to test prefixed implementations + +var sourceData = { + empty: new Uint8Array(0), + short: new Uint8Array([ + 21, 110, 234, 124, 193, 76, 86, 203, 148, 219, 3, 10, 74, 157, 149, 255, + ]), + medium: new Uint8Array([ + 182, 200, 249, 223, 100, 140, 208, 136, 183, 15, 56, 231, 65, 151, 177, 140, + 184, 30, 30, 67, 80, 213, 11, 204, 184, 251, 90, 115, 121, 200, 123, 178, + 227, 214, 237, 84, 97, 237, 30, 159, 54, 243, 64, 163, 150, 42, 68, 107, + 129, 91, 121, 75, 75, 212, 58, 68, 3, 80, 32, 119, 178, 37, 108, 200, 7, + 131, 127, 58, 172, 209, 24, 235, 75, 156, 43, 174, 184, 151, 6, 134, 37, + 171, 172, 161, 147, + ]), + long: new Uint8Array( + Array(65) + .fill(0) + .map((_, i) => i % 256) + ), +}; + +var additionalData = { + empty: new Uint8Array(0), + short: new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]), + medium: new Uint8Array([ + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + ]), +}; + +var iv = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]); // 96-bit IV (only valid size for ChaCha20-Poly1305) + +var keyBytes = new Uint8Array([ + 52, 138, 105, 103, 105, 3, 94, 254, 59, 241, 159, 138, 189, 254, 153, 191, + 228, 172, 165, 239, 117, 172, 19, 206, 219, 9, 205, 138, 45, 87, 166, 89, +]); + +var encryptedData = { + empty_ad: { + empty: new Uint8Array([ + 202, 31, 160, 169, 169, 221, 162, 53, 252, 126, 127, 237, 158, 98, 86, 41, + ]), + short: new Uint8Array([ + 226, 238, 222, 234, 202, 96, 116, 202, 205, 199, 126, 40, 167, 93, 65, + 172, 87, 45, 146, 68, 245, 236, 87, 162, 200, 89, 228, 51, 2, 249, 103, + 255, + ]), + medium: new Uint8Array([ + 65, 72, 205, 73, 111, 160, 242, 137, 238, 19, 69, 197, 172, 87, 101, 223, + 97, 245, 255, 57, 226, 43, 36, 125, 205, 218, 211, 252, 102, 45, 234, 179, + 23, 71, 87, 156, 145, 16, 106, 98, 75, 140, 67, 249, 230, 124, 37, 127, + 192, 145, 40, 129, 203, 31, 15, 182, 15, 226, 211, 111, 132, 132, 114, + 204, 73, 36, 245, 199, 212, 187, 239, 33, 46, 203, 124, 134, 76, 21, 242, + 233, 119, 179, 216, 193, 210, 145, 43, 48, 105, 153, 28, 62, 49, 175, 154, + 142, 222, 68, 219, 229, 66, + ]), + long: new Uint8Array([ + 247, 129, 54, 149, 15, 41, 36, 6, 81, 21, 119, 41, 225, 205, 218, 92, 201, + 250, 243, 105, 166, 235, 57, 166, 109, 56, 147, 148, 3, 248, 143, 30, 212, + 176, 152, 235, 212, 216, 82, 218, 85, 86, 41, 113, 92, 123, 79, 59, 113, + 251, 99, 249, 180, 254, 3, 197, 52, 139, 201, 35, 10, 156, 32, 59, 14, + 225, 117, 48, 100, 126, 58, 112, 157, 195, 18, 185, 178, 97, 215, 233, + 113, + ]), + }, + short_ad: { + empty: new Uint8Array([ + 0, 176, 175, 37, 156, 39, 141, 93, 198, 224, 223, 214, 239, 212, 50, 215, + ]), + short: new Uint8Array([ + 226, 238, 222, 234, 202, 96, 116, 202, 205, 199, 126, 40, 167, 93, 65, + 172, 40, 45, 199, 67, 109, 80, 99, 203, 246, 137, 82, 206, 183, 23, 175, + 176, + ]), + medium: new Uint8Array([ + 65, 72, 205, 73, 111, 160, 242, 137, 238, 19, 69, 197, 172, 87, 101, 223, + 97, 245, 255, 57, 226, 43, 36, 125, 205, 218, 211, 252, 102, 45, 234, 179, + 23, 71, 87, 156, 145, 16, 106, 98, 75, 140, 67, 249, 230, 124, 37, 127, + 192, 145, 40, 129, 203, 31, 15, 182, 15, 226, 211, 111, 132, 132, 114, + 204, 73, 36, 245, 199, 212, 187, 239, 33, 46, 203, 124, 134, 76, 21, 242, + 233, 119, 179, 216, 193, 210, 199, 121, 7, 153, 245, 137, 122, 100, 72, + 102, 113, 169, 244, 218, 111, 105, + ]), + long: new Uint8Array([ + 247, 129, 54, 149, 15, 41, 36, 6, 81, 21, 119, 41, 225, 205, 218, 92, 201, + 250, 243, 105, 166, 235, 57, 166, 109, 56, 147, 148, 3, 248, 143, 30, 212, + 176, 152, 235, 212, 216, 82, 218, 85, 86, 41, 113, 92, 123, 79, 59, 113, + 251, 99, 249, 180, 254, 3, 197, 52, 139, 201, 35, 10, 156, 32, 59, 14, + 137, 0, 55, 193, 166, 74, 124, 251, 91, 36, 191, 112, 236, 204, 35, 102, + ]), + }, + medium_ad: { + empty: new Uint8Array([ + 163, 122, 139, 166, 205, 190, 132, 236, 17, 19, 31, 4, 16, 47, 13, 242, + ]), + short: new Uint8Array([ + 226, 238, 222, 234, 202, 96, 116, 202, 205, 199, 126, 40, 167, 93, 65, + 172, 18, 242, 253, 220, 52, 138, 67, 162, 201, 38, 125, 119, 44, 53, 147, + 119, + ]), + medium: new Uint8Array([ + 65, 72, 205, 73, 111, 160, 242, 137, 238, 19, 69, 197, 172, 87, 101, 223, + 97, 245, 255, 57, 226, 43, 36, 125, 205, 218, 211, 252, 102, 45, 234, 179, + 23, 71, 87, 156, 145, 16, 106, 98, 75, 140, 67, 249, 230, 124, 37, 127, + 192, 145, 40, 129, 203, 31, 15, 182, 15, 226, 211, 111, 132, 132, 114, + 204, 73, 36, 245, 199, 212, 187, 239, 33, 46, 203, 124, 134, 76, 21, 242, + 233, 119, 179, 216, 193, 210, 161, 250, 192, 51, 193, 133, 185, 55, 148, + 21, 194, 168, 212, 203, 252, 184, + ]), + long: new Uint8Array([ + 247, 129, 54, 149, 15, 41, 36, 6, 81, 21, 119, 41, 225, 205, 218, 92, 201, + 250, 243, 105, 166, 235, 57, 166, 109, 56, 147, 148, 3, 248, 143, 30, 212, + 176, 152, 235, 212, 216, 82, 218, 85, 86, 41, 113, 92, 123, 79, 59, 113, + 251, 99, 249, 180, 254, 3, 197, 52, 139, 201, 35, 10, 156, 32, 59, 14, 88, + 20, 159, 185, 145, 230, 1, 242, 106, 255, 55, 7, 60, 85, 179, 184, + ]), + }, +}; + +function equalBuffers(a, b) { + if (a.byteLength !== b.byteLength) { + return false; + } + var aBytes = new Uint8Array(a); + var bBytes = new Uint8Array(b); + for (var i = 0; i < a.byteLength; i++) { + if (aBytes[i] !== bBytes[i]) { + return false; + } + } + return true; +} + +// Test ChaCha20-Poly1305 encryption/decryption +var algorithmName = 'ChaCha20-Poly1305'; + +// Test with different additional data combinations +Object.keys(additionalData).forEach(function (adName) { + var ad = additionalData[adName]; + + Object.keys(sourceData).forEach(function (dataName) { + var plaintext = sourceData[dataName]; + var ciphertext = encryptedData[adName + '_ad'][dataName]; + + promise_test(function (test) { + var operation = subtle + .importKey('raw-secret', keyBytes, { name: algorithmName }, false, [ + 'encrypt', + 'decrypt', + ]) + .then( + function (key) { + return subtle.encrypt( + { name: algorithmName, iv: iv, additionalData: ad }, + key, + plaintext + ); + }, + function (err) { + assert_unreached( + 'importKey failed unexpectedly: ' + err.toString() + ); + } + ) + .then( + function (result) { + assert_true( + equalBuffers(result, ciphertext), + 'Encrypted data should match expected result' + ); + return result; + }, + function (err) { + assert_unreached('encrypt failed unexpectedly: ' + err.toString()); + } + ); + + return operation; + }, algorithmName + + ' encryption with ' + + adName + + ' additional data, ' + + dataName + + ' data'); + + promise_test(function (test) { + var operation = subtle + .importKey('raw-secret', keyBytes, { name: algorithmName }, false, [ + 'encrypt', + 'decrypt', + ]) + .then( + function (key) { + return subtle.decrypt( + { name: algorithmName, iv: iv, additionalData: ad }, + key, + ciphertext + ); + }, + function (err) { + assert_unreached( + 'importKey failed unexpectedly: ' + err.toString() + ); + } + ) + .then( + function (result) { + assert_true( + equalBuffers(result, plaintext), + 'Decrypted data should match original plaintext' + ); + }, + function (err) { + assert_unreached('decrypt failed unexpectedly: ' + err.toString()); + } + ); + + return operation; + }, algorithmName + + ' decryption with ' + + adName + + ' additional data, ' + + dataName + + ' data'); + }); +}); + +// Test round-trip encryption/decryption without fixed vectors +promise_test(function (test) { + var key; + var plaintext = sourceData.medium; + var ad = additionalData.short; + + return subtle + .generateKey({ name: algorithmName }, false, ['encrypt', 'decrypt']) + .then(function (result) { + key = result; + return subtle.encrypt( + { name: algorithmName, iv: iv, additionalData: ad }, + key, + plaintext + ); + }) + .then(function (encrypted) { + return subtle.decrypt( + { name: algorithmName, iv: iv, additionalData: ad }, + key, + encrypted + ); + }) + .then(function (decrypted) { + assert_true( + equalBuffers(decrypted, plaintext), + 'Round-trip encryption/decryption should return original plaintext' + ); + }); +}, algorithmName + ' round-trip encrypt/decrypt'); + +// Test decryption with wrong additional data should fail +promise_test(function (test) { + var key; + var plaintext = sourceData.short; + var correctAd = additionalData.short; + var wrongAd = additionalData.medium; + + return subtle + .generateKey({ name: algorithmName }, false, ['encrypt', 'decrypt']) + .then(function (result) { + key = result; + return subtle.encrypt( + { name: algorithmName, iv: iv, additionalData: correctAd }, + key, + plaintext + ); + }) + .then(function (encrypted) { + return promise_rejects_dom( + test, + 'OperationError', + subtle.decrypt( + { name: algorithmName, iv: iv, additionalData: wrongAd }, + key, + encrypted + ) + ); + }); +}, algorithmName + ' decryption with wrong additional data should fail'); + +// Test decryption with wrong IV should fail +promise_test(function (test) { + var key; + var correctIv = iv; + var wrongIv = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]); // Different 96-bit IV + var plaintext = sourceData.short; + var ad = additionalData.empty; + + return subtle + .generateKey({ name: algorithmName }, false, ['encrypt', 'decrypt']) + .then(function (result) { + key = result; + return subtle.encrypt( + { name: algorithmName, iv: correctIv, additionalData: ad }, + key, + plaintext + ); + }) + .then(function (encrypted) { + return promise_rejects_dom( + test, + 'OperationError', + subtle.decrypt( + { name: algorithmName, iv: wrongIv, additionalData: ad }, + key, + encrypted + ) + ); + }); +}, algorithmName + ' decryption with wrong IV should fail'); + +// Test invalid IV size should fail +promise_test(function (test) { + var invalidIv = new Uint8Array(16); // 128-bit IV is invalid for ChaCha20-Poly1305 + + return subtle + .generateKey({ name: algorithmName }, false, ['encrypt']) + .then(function (key) { + return promise_rejects_dom( + test, + 'OperationError', + subtle.encrypt( + { name: algorithmName, iv: invalidIv }, + key, + sourceData.short + ) + ); + }); +}, algorithmName + ' encryption with invalid IV size should fail'); diff --git a/test/fixtures/wpt/WebCryptoAPI/generateKey/failures.js b/test/fixtures/wpt/WebCryptoAPI/generateKey/failures.js index deaac636a99be5..a3258ae0dd7788 100644 --- a/test/fixtures/wpt/WebCryptoAPI/generateKey/failures.js +++ b/test/fixtures/wpt/WebCryptoAPI/generateKey/failures.js @@ -25,6 +25,8 @@ function run_test(algorithmNames) { {name: "AES-CTR", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, {name: "AES-CBC", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, {name: "AES-GCM", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, + {name: "AES-OCB", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, + {name: "ChaCha20-Poly1305", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, {name: "AES-KW", resultType: CryptoKey, usages: ["wrapKey", "unwrapKey"], mandatoryUsages: []}, {name: "HMAC", resultType: CryptoKey, usages: ["sign", "verify"], mandatoryUsages: []}, {name: "RSASSA-PKCS1-v1_5", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, @@ -34,8 +36,16 @@ function run_test(algorithmNames) { {name: "ECDH", resultType: "CryptoKeyPair", usages: ["deriveKey", "deriveBits"], mandatoryUsages: ["deriveKey", "deriveBits"]}, {name: "Ed25519", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, {name: "Ed448", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, + {name: "ML-DSA-44", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, + {name: "ML-DSA-65", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, + {name: "ML-DSA-87", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, + {name: "ML-KEM-512", resultType: "CryptoKeyPair", usages: ["decapsulateBits", "decapsulateKey", "encapsulateBits", "encapsulateKey"], mandatoryUsages: ["decapsulateBits", "decapsulateKey"]}, + {name: "ML-KEM-768", resultType: "CryptoKeyPair", usages: ["decapsulateBits", "decapsulateKey", "encapsulateBits", "encapsulateKey"], mandatoryUsages: ["decapsulateBits", "decapsulateKey"]}, + {name: "ML-KEM-1024", resultType: "CryptoKeyPair", usages: ["decapsulateBits", "decapsulateKey", "encapsulateBits", "encapsulateKey"], mandatoryUsages: ["decapsulateBits", "decapsulateKey"]}, {name: "X25519", resultType: "CryptoKeyPair", usages: ["deriveKey", "deriveBits"], mandatoryUsages: ["deriveKey", "deriveBits"]}, {name: "X448", resultType: "CryptoKeyPair", usages: ["deriveKey", "deriveBits"], mandatoryUsages: ["deriveKey", "deriveBits"]}, + {name: "KMAC128", resultType: CryptoKey, usages: ["sign", "verify"], mandatoryUsages: []}, + {name: "KMAC256", resultType: CryptoKey, usages: ["sign", "verify"], mandatoryUsages: []}, ]; var testVectors = []; diff --git a/test/fixtures/wpt/WebCryptoAPI/generateKey/failures_AES-OCB.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/generateKey/failures_AES-OCB.tentative.https.any.js new file mode 100644 index 00000000000000..d4a2cd868ff51a --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/generateKey/failures_AES-OCB.tentative.https.any.js @@ -0,0 +1,5 @@ +// META: title=WebCryptoAPI: generateKey() for Failures +// META: timeout=long +// META: script=../util/helpers.js +// META: script=failures.js +run_test(["AES-OCB"]); diff --git a/test/fixtures/wpt/WebCryptoAPI/generateKey/failures_ML-DSA.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/generateKey/failures_ML-DSA.tentative.https.any.js new file mode 100644 index 00000000000000..91e20bc6148fa3 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/generateKey/failures_ML-DSA.tentative.https.any.js @@ -0,0 +1,5 @@ +// META: title=WebCryptoAPI: generateKey() for Failures +// META: timeout=long +// META: script=../util/helpers.js +// META: script=failures.js +run_test(["ML-DSA-44", "ML-DSA-65", "ML-DSA-87"]); diff --git a/test/fixtures/wpt/WebCryptoAPI/generateKey/failures_ML-KEM.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/generateKey/failures_ML-KEM.tentative.https.any.js new file mode 100644 index 00000000000000..9cd347d00f815c --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/generateKey/failures_ML-KEM.tentative.https.any.js @@ -0,0 +1,5 @@ +// META: title=WebCryptoAPI: generateKey() for Failures +// META: timeout=long +// META: script=../util/helpers.js +// META: script=failures.js +run_test(["ML-KEM-512", "ML-KEM-768", "ML-KEM-1024"]); diff --git a/test/fixtures/wpt/WebCryptoAPI/generateKey/failures_chacha20_poly1305.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/generateKey/failures_chacha20_poly1305.tentative.https.any.js new file mode 100644 index 00000000000000..c9a278cdfc2b18 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/generateKey/failures_chacha20_poly1305.tentative.https.any.js @@ -0,0 +1,5 @@ +// META: title=WebCryptoAPI: generateKey() for Failures +// META: timeout=long +// META: script=../util/helpers.js +// META: script=failures.js +run_test(["ChaCha20-Poly1305"]); diff --git a/test/fixtures/wpt/WebCryptoAPI/generateKey/failures_kmac.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/generateKey/failures_kmac.tentative.https.any.js new file mode 100644 index 00000000000000..f906038c7d3f4a --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/generateKey/failures_kmac.tentative.https.any.js @@ -0,0 +1,5 @@ +// META: title=WebCryptoAPI: generateKey() for Failures +// META: timeout=long +// META: script=../util/helpers.js +// META: script=failures.js +run_test(["KMAC128", "KMAC256"]); diff --git a/test/fixtures/wpt/WebCryptoAPI/generateKey/successes.js b/test/fixtures/wpt/WebCryptoAPI/generateKey/successes.js index 13c96b7c735fcb..c72384b7b93bf4 100644 --- a/test/fixtures/wpt/WebCryptoAPI/generateKey/successes.js +++ b/test/fixtures/wpt/WebCryptoAPI/generateKey/successes.js @@ -21,6 +21,8 @@ function run_test(algorithmNames, slowTest) { {name: "AES-CTR", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, {name: "AES-CBC", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, {name: "AES-GCM", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, + {name: "AES-OCB", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, + {name: "ChaCha20-Poly1305", resultType: CryptoKey, usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"], mandatoryUsages: []}, {name: "AES-KW", resultType: CryptoKey, usages: ["wrapKey", "unwrapKey"], mandatoryUsages: []}, {name: "HMAC", resultType: CryptoKey, usages: ["sign", "verify"], mandatoryUsages: []}, {name: "RSASSA-PKCS1-v1_5", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, @@ -30,8 +32,16 @@ function run_test(algorithmNames, slowTest) { {name: "ECDH", resultType: "CryptoKeyPair", usages: ["deriveKey", "deriveBits"], mandatoryUsages: ["deriveKey", "deriveBits"]}, {name: "Ed25519", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, {name: "Ed448", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, + {name: "ML-DSA-44", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, + {name: "ML-DSA-65", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, + {name: "ML-DSA-87", resultType: "CryptoKeyPair", usages: ["sign", "verify"], mandatoryUsages: ["sign"]}, + {name: "ML-KEM-512", resultType: "CryptoKeyPair", usages: ["decapsulateBits", "decapsulateKey", "encapsulateBits", "encapsulateKey"], mandatoryUsages: ["decapsulateBits", "decapsulateKey"]}, + {name: "ML-KEM-768", resultType: "CryptoKeyPair", usages: ["decapsulateBits", "decapsulateKey", "encapsulateBits", "encapsulateKey"], mandatoryUsages: ["decapsulateBits", "decapsulateKey"]}, + {name: "ML-KEM-1024", resultType: "CryptoKeyPair", usages: ["decapsulateBits", "decapsulateKey", "encapsulateBits", "encapsulateKey"], mandatoryUsages: ["decapsulateBits", "decapsulateKey"]}, {name: "X25519", resultType: "CryptoKeyPair", usages: ["deriveKey", "deriveBits"], mandatoryUsages: ["deriveKey", "deriveBits"]}, {name: "X448", resultType: "CryptoKeyPair", usages: ["deriveKey", "deriveBits"], mandatoryUsages: ["deriveKey", "deriveBits"]}, + {name: "KMAC128", resultType: CryptoKey, usages: ["sign", "verify"], mandatoryUsages: []}, + {name: "KMAC256", resultType: CryptoKey, usages: ["sign", "verify"], mandatoryUsages: []}, ]; var testVectors = []; @@ -74,16 +84,47 @@ function run_test(algorithmNames, slowTest) { assert_unreached("generateKey threw an unexpected error: " + err.toString()); }) .then(async function (result) { - if (resultType === "CryptoKeyPair") { - const [jwkPub,,, jwkPriv] = await Promise.all([ + // TODO: remove this block to enable ML-KEM JWK when its definition is done in IETF JOSE WG + if (result.publicKey?.algorithm.name.startsWith('ML-KEM')) { + const promises = [ + subtle.exportKey('spki', result.publicKey), + extractable ? subtle.exportKey('pkcs8', result.privateKey) : undefined, + subtle.exportKey('raw-public', result.publicKey), + ]; + if (extractable) + promises.push(subtle.exportKey('raw-seed', result.privateKey)); + } else if (resultType === "CryptoKeyPair") { + const promises = [ subtle.exportKey('jwk', result.publicKey), + extractable ? subtle.exportKey('jwk', result.privateKey) : undefined, subtle.exportKey('spki', result.publicKey), - result.publicKey.algorithm.name.startsWith('RSA') ? undefined : subtle.exportKey('raw', result.publicKey), - ...(extractable ? [ - subtle.exportKey('jwk', result.privateKey), - subtle.exportKey('pkcs8', result.privateKey), - ] : []) - ]); + extractable ? subtle.exportKey('pkcs8', result.privateKey) : undefined, + ]; + + switch (result.publicKey.algorithm.name.substring(0, 2)) { + case 'ML': + promises.push(subtle.exportKey('raw-public', result.publicKey)); + if (extractable) + promises.push(subtle.exportKey('raw-seed', result.privateKey)); + break; + case 'SL': + promises.push(subtle.exportKey('raw-public', result.publicKey)); + if (extractable) + promises.push(subtle.exportKey('raw-private', result.privateKey)); + break; + case 'EC': + case 'Ed': + case 'X2': + case 'X4': + promises.push(subtle.exportKey('raw', result.publicKey)); + break; + case 'RS': + break; + default: + throw new Error('not implemented'); + } + + const [jwkPub, jwkPriv] = await Promise.all(promises); if (extractable) { // Test that the JWK public key is a superset of the JWK private key. @@ -96,7 +137,7 @@ function run_test(algorithmNames, slowTest) { } else { if (extractable) { await Promise.all([ - subtle.exportKey('raw', result), + subtle.exportKey(/cha|ocb|kmac/i.test(result.algorithm.name) ? 'raw-secret' : 'raw', result), subtle.exportKey('jwk', result), ]); } diff --git a/test/fixtures/wpt/WebCryptoAPI/generateKey/successes_AES-OCB.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/generateKey/successes_AES-OCB.tentative.https.any.js new file mode 100644 index 00000000000000..b43abc4edb41c4 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/generateKey/successes_AES-OCB.tentative.https.any.js @@ -0,0 +1,6 @@ +// META: title=WebCryptoAPI: generateKey() Successful Calls +// META: timeout=long +// META: script=../util/helpers.js +// META: script=/common/subset-tests.js +// META: script=successes.js +run_test(["AES-OCB"]); diff --git a/test/fixtures/wpt/WebCryptoAPI/generateKey/successes_ML-DSA.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/generateKey/successes_ML-DSA.tentative.https.any.js new file mode 100644 index 00000000000000..15d52f2a5059f5 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/generateKey/successes_ML-DSA.tentative.https.any.js @@ -0,0 +1,6 @@ +// META: title=WebCryptoAPI: generateKey() Successful Calls +// META: timeout=long +// META: script=../util/helpers.js +// META: script=/common/subset-tests.js +// META: script=successes.js +run_test(["ML-DSA-44", "ML-DSA-65", "ML-DSA-87"]); diff --git a/test/fixtures/wpt/WebCryptoAPI/generateKey/successes_ML-KEM.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/generateKey/successes_ML-KEM.tentative.https.any.js new file mode 100644 index 00000000000000..68a0d97b975537 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/generateKey/successes_ML-KEM.tentative.https.any.js @@ -0,0 +1,6 @@ +// META: title=WebCryptoAPI: generateKey() Successful Calls +// META: timeout=long +// META: script=../util/helpers.js +// META: script=/common/subset-tests.js +// META: script=successes.js +run_test(["ML-KEM-512", "ML-KEM-768", "ML-KEM-1024"]); diff --git a/test/fixtures/wpt/WebCryptoAPI/generateKey/successes_chacha20_poly1305.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/generateKey/successes_chacha20_poly1305.tentative.https.any.js new file mode 100644 index 00000000000000..a1cef25c2f24fb --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/generateKey/successes_chacha20_poly1305.tentative.https.any.js @@ -0,0 +1,6 @@ +// META: title=WebCryptoAPI: generateKey() Successful Calls +// META: timeout=long +// META: script=../util/helpers.js +// META: script=/common/subset-tests.js +// META: script=successes.js +run_test(["ChaCha20-Poly1305"]); diff --git a/test/fixtures/wpt/WebCryptoAPI/generateKey/successes_kmac.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/generateKey/successes_kmac.tentative.https.any.js new file mode 100644 index 00000000000000..9f881f92bc17cc --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/generateKey/successes_kmac.tentative.https.any.js @@ -0,0 +1,6 @@ +// META: title=WebCryptoAPI: generateKey() Successful Calls +// META: timeout=long +// META: script=../util/helpers.js +// META: script=/common/subset-tests.js +// META: script=successes.js +run_test(["KMAC128", "KMAC256"]); diff --git a/test/fixtures/wpt/WebCryptoAPI/getPublicKey.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/getPublicKey.tentative.https.any.js new file mode 100644 index 00000000000000..5c610752d96dff --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/getPublicKey.tentative.https.any.js @@ -0,0 +1,266 @@ +// META: title=WebCryptoAPI: getPublicKey() method +// META: timeout=long +// META: script=util/helpers.js + +"use strict"; + +const algorithms = [ + { + name: "ECDH", + generateKeyParams: { name: "ECDH", namedCurve: "P-256" }, + usages: ["deriveKey", "deriveBits"], + publicKeyUsages: [] + }, + { + name: "ECDSA", + generateKeyParams: { name: "ECDSA", namedCurve: "P-256" }, + usages: ["sign", "verify"], + publicKeyUsages: ["verify"] + }, + { + name: "Ed25519", + generateKeyParams: { name: "Ed25519" }, + usages: ["sign", "verify"], + publicKeyUsages: ["verify"] + }, + { + name: "RSA-OAEP", + generateKeyParams: { + name: "RSA-OAEP", + modulusLength: 2048, + publicExponent: new Uint8Array([1, 0, 1]), + hash: "SHA-256" + }, + usages: ["encrypt", "decrypt"], + publicKeyUsages: ["encrypt"] + }, + { + name: "RSA-PSS", + generateKeyParams: { + name: "RSA-PSS", + modulusLength: 2048, + publicExponent: new Uint8Array([1, 0, 1]), + hash: "SHA-256" + }, + usages: ["sign", "verify"], + publicKeyUsages: ["verify"] + }, + { + name: "RSASSA-PKCS1-v1_5", + generateKeyParams: { + name: "RSASSA-PKCS1-v1_5", + modulusLength: 2048, + publicExponent: new Uint8Array([1, 0, 1]), + hash: "SHA-256" + }, + usages: ["sign", "verify"], + publicKeyUsages: ["verify"] + }, + { + name: "X25519", + generateKeyParams: { name: "X25519" }, + usages: ["deriveKey", "deriveBits"], + publicKeyUsages: [] + } +]; + +// Test basic functionality for supported algorithms +algorithms.forEach(function(algorithm) { + promise_test(async function(t) { + // Generate a key pair + const keyPair = await crypto.subtle.generateKey( + algorithm.generateKeyParams, + false, // extractable + algorithm.usages + ); + + assert_true(keyPair.privateKey instanceof CryptoKey, "Generated private key"); + assert_equals(keyPair.privateKey.type, "private", "Private key type"); + + // Test getPublicKey with valid usages + const publicKey = await crypto.subtle.getPublicKey( + keyPair.privateKey, + algorithm.publicKeyUsages + ); + + // Verify the returned public key + assert_true(publicKey instanceof CryptoKey, "getPublicKey returns a CryptoKey"); + assert_equals(publicKey.type, "public", "Returned key is public"); + assert_equals(publicKey.algorithm.name, algorithm.name, "Algorithm name matches"); + assert_true(publicKey.extractable, "Public key is extractable"); + + // Verify usages + assert_equals(publicKey.usages.length, algorithm.publicKeyUsages.length, "Usage count matches"); + algorithm.publicKeyUsages.forEach(function(usage) { + assert_true(publicKey.usages.includes(usage), `Has ${usage} usage`); + }); + + // Verify that the derived public key matches the original public key + // by comparing their exported forms + const originalExported = await crypto.subtle.exportKey("spki", keyPair.publicKey); + const derivedExported = await crypto.subtle.exportKey("spki", publicKey); + + assert_array_equals( + new Uint8Array(originalExported), + new Uint8Array(derivedExported), + "Exported public keys match" + ); + + }, `getPublicKey works for ${algorithm.name}`); +}); + +// Test functional equivalence - ensure derived public key works for crypto operations +promise_test(async function(t) { + const keyPair = await crypto.subtle.generateKey( + { name: "ECDSA", namedCurve: "P-256" }, + false, + ["sign", "verify"] + ); + + const derivedPublicKey = await crypto.subtle.getPublicKey( + keyPair.privateKey, + ["verify"] + ); + + // Create test data + const data = new TextEncoder().encode("test message"); + + // Sign with private key + const signature = await crypto.subtle.sign( + { name: "ECDSA", hash: "SHA-256" }, + keyPair.privateKey, + data + ); + + // Verify with both original and derived public keys + const verifyOriginal = await crypto.subtle.verify( + { name: "ECDSA", hash: "SHA-256" }, + keyPair.publicKey, + signature, + data + ); + + const verifyDerived = await crypto.subtle.verify( + { name: "ECDSA", hash: "SHA-256" }, + derivedPublicKey, + signature, + data + ); + + assert_true(verifyOriginal, "Original public key verifies signature"); + assert_true(verifyDerived, "Derived public key verifies signature"); + +}, "Derived public key is functionally equivalent to original public key"); + +// Test with empty usages array +algorithms.forEach(function(algorithm) { + promise_test(async function(t) { + // Skip X25519 if not supported + if (algorithm.name === "X25519") { + try { + await crypto.subtle.generateKey(algorithm.generateKeyParams, false, algorithm.usages); + } catch (e) { + if (e.name === "NotSupportedError") { + return; + } + throw e; + } + } + + const keyPair = await crypto.subtle.generateKey( + algorithm.generateKeyParams, + false, + algorithm.usages + ); + + // Test with empty usages array + const publicKey = await crypto.subtle.getPublicKey( + keyPair.privateKey, + [] + ); + + assert_true(publicKey instanceof CryptoKey, "getPublicKey returns a CryptoKey"); + assert_equals(publicKey.type, "public", "Returned key is public"); + assert_equals(publicKey.usages.length, 0, "Public key has no usages"); + + }, `getPublicKey works with empty usages for ${algorithm.name}`); +}); + +// Test error cases + +// Test with non-private key (should throw InvalidAccessError) +promise_test(async function(t) { + const keyPair = await crypto.subtle.generateKey( + { name: "ECDSA", namedCurve: "P-256" }, + false, + ["sign", "verify"] + ); + + await promise_rejects_dom(t, "InvalidAccessError", + crypto.subtle.getPublicKey(keyPair.publicKey, ["verify"]), + "getPublicKey should reject when called with a public key" + ); +}, "getPublicKey rejects with InvalidAccessError when given a public key"); + +// Test with symmetric keys (should throw NotSupportedError for non-private keys) +promise_test(async function(t) { + const aesKey = await crypto.subtle.generateKey( + { name: "AES-GCM", length: 256 }, + false, + ["encrypt", "decrypt"] + ); + + await promise_rejects_dom(t, "NotSupportedError", + crypto.subtle.getPublicKey(aesKey, []), + "getPublicKey should reject AES-GCM keys" + ); +}, "getPublicKey rejects with NotSupportedError for AES-GCM symmetric keys"); + +promise_test(async function(t) { + const hmacKey = await crypto.subtle.generateKey( + { name: "HMAC", hash: "SHA-256" }, + false, + ["sign", "verify"] + ); + + await promise_rejects_dom(t, "NotSupportedError", + crypto.subtle.getPublicKey(hmacKey, []), + "getPublicKey should reject HMAC keys" + ); +}, "getPublicKey rejects with NotSupportedError for HMAC symmetric keys"); + +// Test with invalid usages for the algorithm +promise_test(async function(t) { + const keyPair = await crypto.subtle.generateKey( + { name: "ECDSA", namedCurve: "P-256" }, + false, + ["sign", "verify"] + ); + + // Try to use "encrypt" usage with ECDSA (not supported for ECDSA public keys) + await promise_rejects_dom(t, "SyntaxError", + crypto.subtle.getPublicKey(keyPair.privateKey, ["encrypt"]), + "getPublicKey should reject invalid usages for the algorithm" + ); +}, "getPublicKey rejects with SyntaxError for invalid usages"); + +// Test with mixed valid and invalid usages +promise_test(async function(t) { + const keyPair = await crypto.subtle.generateKey( + { name: "ECDSA", namedCurve: "P-256" }, + false, + ["sign", "verify"] + ); + + // Mix valid ("verify") and invalid ("encrypt") usages + await promise_rejects_dom(t, "SyntaxError", + crypto.subtle.getPublicKey(keyPair.privateKey, ["verify", "encrypt"]), + "getPublicKey should reject when any usage is invalid" + ); +}, "getPublicKey rejects with SyntaxError when any usage is invalid for the algorithm"); + +// Test that the method exists +test(function() { + assert_true("getPublicKey" in crypto.subtle, "getPublicKey method exists on SubtleCrypto"); + assert_equals(typeof crypto.subtle.getPublicKey, "function", "getPublicKey is a function"); +}, "getPublicKey method is available"); diff --git a/test/fixtures/wpt/WebCryptoAPI/import_export/AES-OCB_importKey.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/import_export/AES-OCB_importKey.tentative.https.any.js new file mode 100644 index 00000000000000..7fa028aa5a03f0 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/import_export/AES-OCB_importKey.tentative.https.any.js @@ -0,0 +1,6 @@ +// META: title=WebCryptoAPI: importKey() for symmetric keys +// META: timeout=long +// META: script=../util/helpers.js +// META: script=symmetric_importKey.js + +runTests("AES-OCB"); diff --git a/test/fixtures/wpt/WebCryptoAPI/import_export/Argon2_importKey.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/import_export/Argon2_importKey.tentative.https.any.js new file mode 100644 index 00000000000000..a3edc3896308e3 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/import_export/Argon2_importKey.tentative.https.any.js @@ -0,0 +1,8 @@ +// META: title=WebCryptoAPI: importKey() for symmetric keys +// META: timeout=long +// META: script=../util/helpers.js +// META: script=symmetric_importKey.js + +runTests("Argon2i"); +runTests("Argon2d"); +runTests("Argon2id"); diff --git a/test/fixtures/wpt/WebCryptoAPI/import_export/ChaCha20-Poly1305_importKey.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/import_export/ChaCha20-Poly1305_importKey.tentative.https.any.js new file mode 100644 index 00000000000000..620f22d4aecc35 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/import_export/ChaCha20-Poly1305_importKey.tentative.https.any.js @@ -0,0 +1,6 @@ +// META: title=WebCryptoAPI: importKey() for symmetric keys +// META: timeout=long +// META: script=../util/helpers.js +// META: script=symmetric_importKey.js + +runTests("ChaCha20-Poly1305"); diff --git a/test/fixtures/wpt/WebCryptoAPI/import_export/KMAC_importKey.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/import_export/KMAC_importKey.tentative.https.any.js new file mode 100644 index 00000000000000..83995bca37acb6 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/import_export/KMAC_importKey.tentative.https.any.js @@ -0,0 +1,7 @@ +// META: title=WebCryptoAPI: importKey() for symmetric keys +// META: timeout=long +// META: script=../util/helpers.js +// META: script=symmetric_importKey.js + +runTests("KMAC128"); +runTests("KMAC256"); diff --git a/test/fixtures/wpt/WebCryptoAPI/import_export/ML-DSA_importKey.js b/test/fixtures/wpt/WebCryptoAPI/import_export/ML-DSA_importKey.js new file mode 100644 index 00000000000000..3723b321e542d5 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/import_export/ML-DSA_importKey.js @@ -0,0 +1,222 @@ +var subtle = crypto.subtle; + +function runTests(algorithmName) { + var algorithm = { name: algorithmName }; + var data = keyData[algorithmName]; + var jwkData = { + jwk: { kty: data.jwk.kty, alg: data.jwk.alg, pub: data.jwk.pub }, + }; + + [true, false].forEach(function (extractable) { + // Test public keys first + allValidUsages(data.publicUsages, true).forEach(function (usages) { + ['spki', 'jwk', 'raw-public'].forEach(function (format) { + if (format === 'jwk') { + // Not all fields used for public keys + testFormat( + format, + algorithm, + jwkData, + algorithmName, + usages, + extractable + ); + } else { + testFormat( + format, + algorithm, + data, + algorithmName, + usages, + extractable + ); + } + }); + }); + + // Next, test private keys + allValidUsages(data.privateUsages).forEach(function (usages) { + ['pkcs8', 'jwk', 'raw-seed'].forEach(function (format) { + testFormat(format, algorithm, data, algorithmName, usages, extractable); + }); + }); + }); +} + +// Test importKey with a given key format and other parameters. If +// extrable is true, export the key and verify that it matches the input. +function testFormat(format, algorithm, keyData, keySize, usages, extractable) { + [algorithm, algorithm.name].forEach((alg) => { + promise_test(function (test) { + return subtle + .importKey(format, keyData[format], alg, extractable, usages) + .then( + function (key) { + assert_equals( + key.constructor, + CryptoKey, + 'Imported a CryptoKey object' + ); + assert_goodCryptoKey( + key, + algorithm, + extractable, + usages, + format === 'pkcs8' || + format === 'raw-seed' || + (format === 'jwk' && keyData[format].priv) + ? 'private' + : 'public' + ); + if (!extractable) { + return; + } + + return subtle.exportKey(format, key).then( + function (result) { + if (format !== 'jwk') { + assert_true( + equalBuffers(keyData[format], result), + 'Round trip works' + ); + } else { + assert_true( + equalJwk(keyData[format], result), + 'Round trip works' + ); + } + }, + function (err) { + assert_unreached( + 'Threw an unexpected error: ' + err.toString() + ); + } + ); + }, + function (err) { + assert_unreached('Threw an unexpected error: ' + err.toString()); + } + ); + }, 'Good parameters: ' + + keySize.toString() + + ' bits ' + + parameterString(format, keyData[format], alg, extractable, usages)); + }); +} + +// Helper methods follow: + +// Are two array buffers the same? +function equalBuffers(a, b) { + if (a.byteLength !== b.byteLength) { + return false; + } + + var aBytes = new Uint8Array(a); + var bBytes = new Uint8Array(b); + + for (var i = 0; i < a.byteLength; i++) { + if (aBytes[i] !== bBytes[i]) { + return false; + } + } + + return true; +} + +// Are two Jwk objects "the same"? That is, does the object returned include +// matching values for each property that was expected? It's okay if the +// returned object has extra methods; they aren't checked. +function equalJwk(expected, got) { + var fields = Object.keys(expected); + var fieldName; + + for (var i = 0; i < fields.length; i++) { + fieldName = fields[i]; + if (!(fieldName in got)) { + return false; + } + if (expected[fieldName] !== got[fieldName]) { + return false; + } + } + + return true; +} + +// Convert method parameters to a string to uniquely name each test +function parameterString(format, data, algorithm, extractable, usages) { + if ('byteLength' in data) { + data = 'buffer(' + data.byteLength.toString() + ')'; + } else { + data = 'object(' + Object.keys(data).join(', ') + ')'; + } + var result = + '(' + + objectToString(format) + + ', ' + + objectToString(data) + + ', ' + + objectToString(algorithm) + + ', ' + + objectToString(extractable) + + ', ' + + objectToString(usages) + + ')'; + + return result; +} + +// Character representation of any object we may use as a parameter. +function objectToString(obj) { + var keyValuePairs = []; + + if (Array.isArray(obj)) { + return ( + '[' + + obj + .map(function (elem) { + return objectToString(elem); + }) + .join(', ') + + ']' + ); + } else if (typeof obj === 'object') { + Object.keys(obj) + .sort() + .forEach(function (keyName) { + keyValuePairs.push(keyName + ': ' + objectToString(obj[keyName])); + }); + return '{' + keyValuePairs.join(', ') + '}'; + } else if (typeof obj === 'undefined') { + return 'undefined'; + } else { + return obj.toString(); + } + + var keyValuePairs = []; + + Object.keys(obj) + .sort() + .forEach(function (keyName) { + var value = obj[keyName]; + if (typeof value === 'object') { + value = objectToString(value); + } else if (typeof value === 'array') { + value = + '[' + + value + .map(function (elem) { + return objectToString(elem); + }) + .join(', ') + + ']'; + } else { + value = value.toString(); + } + + keyValuePairs.push(keyName + ': ' + value); + }); + + return '{' + keyValuePairs.join(', ') + '}'; +} diff --git a/test/fixtures/wpt/WebCryptoAPI/import_export/ML-DSA_importKey.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/import_export/ML-DSA_importKey.tentative.https.any.js new file mode 100644 index 00000000000000..5ce13d858d6fff --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/import_export/ML-DSA_importKey.tentative.https.any.js @@ -0,0 +1,9 @@ +// META: title=WebCryptoAPI: importKey() for ML-DSA keys +// META: timeout=long +// META: script=../util/helpers.js +// META: script=ML-DSA_importKey_fixtures.js +// META: script=ML-DSA_importKey.js + +runTests("ML-DSA-44"); +runTests("ML-DSA-65"); +runTests("ML-DSA-87"); diff --git a/test/fixtures/wpt/WebCryptoAPI/import_export/ML-DSA_importKey_fixtures.js b/test/fixtures/wpt/WebCryptoAPI/import_export/ML-DSA_importKey_fixtures.js new file mode 100644 index 00000000000000..ef1f5a1f51a944 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/import_export/ML-DSA_importKey_fixtures.js @@ -0,0 +1,449 @@ +var keyData = { + 'ML-DSA-44': { + privateUsages: ['sign'], + publicUsages: ['verify'], + pkcs8: new Uint8Array([ + 48, 52, 2, 1, 0, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 3, 17, 4, 34, + 128, 32, 153, 21, 95, 99, 48, 150, 218, 124, 190, 8, 122, 137, 72, 184, + 79, 118, 123, 16, 249, 1, 200, 35, 194, 64, 177, 221, 43, 200, 112, 5, + 201, 62, + ]), + spki: new Uint8Array([ + 48, 130, 5, 50, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 3, 17, 3, 130, 5, + 33, 0, 85, 152, 213, 68, 198, 20, 177, 84, 200, 188, 33, 104, 36, 161, + 193, 127, 226, 151, 48, 107, 122, 191, 89, 86, 188, 3, 245, 199, 18, 79, + 168, 192, 218, 218, 223, 227, 84, 133, 41, 187, 9, 183, 14, 222, 155, 137, + 84, 111, 138, 97, 234, 152, 52, 15, 163, 47, 227, 218, 19, 20, 229, 93, + 99, 252, 155, 213, 30, 241, 158, 211, 213, 191, 155, 73, 211, 145, 59, + 194, 75, 140, 3, 161, 149, 139, 48, 172, 155, 172, 120, 234, 142, 79, 78, + 116, 215, 184, 50, 182, 162, 192, 93, 221, 179, 216, 70, 186, 92, 93, 51, + 190, 61, 173, 105, 206, 9, 208, 52, 54, 208, 252, 115, 176, 146, 118, 23, + 0, 5, 41, 151, 121, 241, 246, 193, 206, 212, 160, 181, 7, 99, 220, 78, 96, + 123, 142, 35, 107, 37, 218, 138, 139, 228, 207, 166, 132, 87, 36, 116, + 251, 174, 10, 41, 196, 171, 26, 212, 90, 213, 223, 141, 87, 232, 59, 46, + 173, 16, 247, 173, 4, 219, 165, 234, 8, 217, 233, 163, 13, 10, 160, 22, + 87, 232, 2, 9, 92, 177, 35, 67, 55, 104, 51, 204, 231, 81, 209, 62, 31, + 117, 56, 141, 78, 109, 148, 118, 191, 93, 193, 59, 30, 88, 237, 19, 169, + 14, 11, 150, 102, 215, 144, 69, 246, 32, 159, 110, 49, 75, 78, 225, 121, + 184, 206, 234, 126, 171, 164, 43, 237, 244, 63, 83, 70, 136, 213, 244, + 121, 184, 34, 201, 249, 95, 64, 165, 99, 14, 195, 231, 18, 121, 20, 156, + 80, 231, 133, 197, 0, 94, 195, 22, 251, 255, 174, 213, 103, 75, 88, 58, + 138, 66, 37, 85, 162, 15, 242, 29, 49, 147, 191, 163, 170, 109, 195, 22, + 63, 197, 149, 117, 100, 36, 81, 115, 203, 126, 62, 86, 103, 193, 182, 69, + 238, 233, 162, 62, 248, 132, 158, 212, 208, 187, 127, 212, 198, 169, 245, + 26, 153, 28, 207, 85, 65, 145, 200, 23, 196, 38, 64, 49, 54, 233, 185, 72, + 156, 86, 230, 127, 152, 108, 184, 240, 109, 8, 103, 228, 206, 142, 73, 74, + 214, 52, 182, 203, 82, 201, 175, 188, 111, 42, 232, 8, 177, 131, 47, 237, + 92, 120, 210, 124, 48, 185, 215, 137, 36, 70, 162, 164, 119, 0, 155, 20, + 57, 33, 27, 220, 77, 254, 233, 190, 106, 135, 21, 194, 57, 238, 95, 162, + 78, 164, 33, 210, 215, 43, 100, 96, 232, 87, 19, 43, 65, 240, 183, 17, + 131, 247, 97, 241, 7, 111, 159, 40, 252, 45, 228, 76, 71, 46, 85, 181, 54, + 41, 135, 162, 144, 227, 128, 121, 173, 207, 119, 54, 19, 197, 23, 231, + 176, 125, 190, 32, 76, 60, 34, 24, 160, 42, 73, 190, 124, 99, 5, 9, 214, + 6, 220, 177, 206, 79, 222, 10, 142, 250, 63, 179, 67, 21, 159, 57, 126, + 239, 28, 238, 240, 107, 79, 185, 174, 232, 168, 146, 128, 229, 119, 19, + 21, 33, 239, 193, 42, 178, 152, 124, 24, 203, 131, 193, 93, 162, 2, 208, + 231, 20, 203, 232, 47, 54, 114, 255, 236, 97, 99, 156, 15, 160, 75, 60, + 111, 59, 35, 25, 230, 43, 91, 170, 161, 74, 70, 179, 180, 251, 71, 197, + 240, 104, 42, 39, 202, 206, 12, 115, 249, 138, 55, 252, 216, 61, 185, 121, + 76, 137, 172, 166, 88, 92, 130, 18, 52, 67, 13, 187, 49, 147, 212, 77, 74, + 56, 59, 123, 99, 205, 36, 137, 96, 111, 148, 121, 157, 2, 83, 246, 86, + 156, 152, 98, 172, 77, 244, 214, 225, 184, 240, 121, 144, 56, 213, 161, + 43, 67, 4, 161, 104, 202, 91, 134, 247, 108, 24, 46, 187, 63, 216, 50, + 125, 120, 17, 216, 22, 228, 156, 253, 7, 180, 15, 130, 180, 72, 71, 169, + 3, 236, 247, 11, 170, 32, 76, 236, 225, 133, 250, 20, 235, 200, 143, 89, + 25, 158, 49, 158, 164, 213, 221, 81, 120, 241, 150, 210, 19, 79, 165, 24, + 35, 170, 182, 242, 255, 143, 171, 148, 140, 41, 207, 186, 98, 224, 16, + 152, 224, 38, 110, 175, 169, 111, 132, 201, 178, 114, 25, 196, 50, 149, + 158, 193, 180, 101, 183, 92, 109, 131, 102, 119, 123, 78, 107, 223, 4, 1, + 206, 140, 130, 237, 205, 36, 18, 180, 197, 154, 26, 236, 140, 173, 230, + 101, 35, 189, 121, 104, 21, 75, 81, 224, 186, 212, 81, 107, 66, 244, 235, + 64, 90, 206, 39, 44, 43, 162, 187, 63, 229, 217, 154, 185, 157, 24, 125, + 252, 91, 136, 59, 47, 182, 200, 73, 19, 137, 132, 81, 16, 234, 227, 210, + 32, 16, 160, 188, 250, 27, 190, 164, 53, 244, 219, 199, 177, 146, 117, 50, + 99, 72, 235, 37, 154, 72, 51, 203, 61, 39, 230, 34, 132, 117, 217, 167, + 201, 42, 17, 76, 72, 103, 172, 93, 169, 29, 76, 88, 178, 226, 32, 53, 190, + 60, 210, 132, 113, 198, 26, 70, 179, 47, 34, 184, 88, 178, 208, 1, 196, + 89, 136, 167, 33, 38, 9, 255, 89, 202, 27, 93, 229, 100, 192, 24, 234, + 200, 186, 125, 231, 212, 188, 11, 29, 51, 189, 70, 147, 176, 231, 81, 16, + 114, 152, 159, 21, 124, 185, 208, 50, 74, 211, 113, 207, 35, 54, 173, 205, + 133, 52, 167, 199, 87, 158, 120, 33, 204, 163, 146, 233, 21, 61, 28, 102, + 48, 232, 184, 15, 219, 238, 240, 215, 222, 239, 3, 110, 180, 95, 103, 147, + 236, 10, 57, 195, 159, 231, 50, 92, 145, 165, 44, 204, 121, 187, 9, 210, + 80, 86, 251, 169, 132, 236, 248, 23, 207, 222, 227, 13, 53, 1, 88, 69, + 105, 13, 238, 202, 251, 194, 245, 14, 38, 1, 245, 157, 212, 162, 182, 217, + 230, 115, 139, 175, 219, 199, 74, 124, 186, 158, 3, 220, 87, 220, 177, 85, + 13, 58, 168, 223, 6, 238, 156, 80, 121, 44, 166, 176, 0, 48, 98, 70, 93, + 78, 50, 192, 16, 186, 2, 233, 105, 105, 120, 195, 17, 100, 141, 214, 158, + 144, 63, 4, 88, 190, 101, 209, 55, 119, 46, 128, 117, 225, 121, 204, 195, + 19, 61, 170, 116, 251, 225, 230, 28, 27, 249, 84, 195, 224, 190, 60, 212, + 83, 3, 148, 204, 4, 103, 50, 233, 175, 207, 47, 51, 216, 79, 251, 150, 81, + 171, 7, 145, 55, 188, 187, 217, 200, 155, 246, 85, 42, 123, 18, 112, 192, + 116, 163, 40, 187, 132, 192, 210, 188, 106, 117, 217, 185, 183, 202, 33, + 11, 205, 10, 61, 52, 15, 66, 131, 121, 112, 26, 96, 166, 241, 1, 68, 206, + 80, 92, 132, 83, 89, 126, 135, 157, 4, 202, 16, 5, 131, 112, 62, 56, 234, + 176, 213, 119, 205, 203, 17, 106, 156, 117, 251, 135, 21, 73, 219, 238, 3, + 88, 21, 71, 136, 118, 0, 7, 106, 151, 200, 221, 179, 206, 50, 198, 27, + 118, 181, 27, 85, 35, 248, 44, 57, 15, 221, 97, 121, 4, 167, 111, 182, + 207, 195, 52, 134, 195, 128, 173, 111, 98, 152, 29, 138, 197, 175, 171, + 247, 194, 20, 134, 209, 232, 94, 17, 203, 139, 30, 237, 187, 243, 16, 180, + 43, 105, 236, 66, 175, 170, 139, 24, 99, 28, 225, 141, 96, 250, 119, 0, + 111, 212, 34, 217, 42, 134, 88, 78, 76, 126, 169, 168, 59, 154, 93, 54, + 43, 161, 29, 111, 124, 59, 225, 52, 86, 147, 38, 151, 161, 36, 119, 204, + 164, 121, 46, 186, 65, 84, 70, 38, 15, 203, 48, 168, 235, 231, 30, 55, 95, + 36, 10, 20, 166, 109, 8, 18, 109, 251, 213, 82, 142, 240, 49, 249, 180, + 78, 69, + ]), + 'raw-public': hexStringToUint8Array( + '5598d544c614b154c8bc216824a1c17fe297306b7abf5956bc03f5c7124fa8c0dadadfe3548529bb09b70ede9b89546f8a61ea98340fa32fe3da1314e55d63fc9bd51ef19ed3d5bf9b49d3913bc24b8c03a1958b30ac9bac78ea8e4f4e74d7b832b6a2c05dddb3d846ba5c5d33be3dad69ce09d03436d0fc73b09276170005299779f1f6c1ced4a0b50763dc4e607b8e236b25da8a8be4cfa684572474fbae0a29c4ab1ad45ad5df8d57e83b2ead10f7ad04dba5ea08d9e9a30d0aa01657e802095cb12343376833cce751d13e1f75388d4e6d9476bf5dc13b1e58ed13a90e0b9666d79045f6209f6e314b4ee179b8ceea7eaba42bedf43f534688d5f479b822c9f95f40a5630ec3e71279149c50e785c5005ec316fbffaed5674b583a8a422555a20ff21d3193bfa3aa6dc3163fc5957564245173cb7e3e5667c1b645eee9a23ef8849ed4d0bb7fd4c6a9f51a991ccf554191c817c426403136e9b9489c56e67f986cb8f06d0867e4ce8e494ad634b6cb52c9afbc6f2ae808b1832fed5c78d27c30b9d7892446a2a477009b1439211bdc4dfee9be6a8715c239ee5fa24ea421d2d72b6460e857132b41f0b71183f761f1076f9f28fc2de44c472e55b5362987a290e38079adcf773613c517e7b07dbe204c3c2218a02a49be7c630509d606dcb1ce4fde0a8efa3fb343159f397eef1ceef06b4fb9aee8a89280e577131521efc12ab2987c18cb83c15da202d0e714cbe82f3672ffec61639c0fa04b3c6f3b2319e62b5baaa14a46b3b4fb47c5f0682a27cace0c73f98a37fcd83db9794c89aca6585c821234430dbb3193d44d4a383b7b63cd2489606f94799d0253f6569c9862ac4df4d6e1b8f0799038d5a12b4304a168ca5b86f76c182ebb3fd8327d7811d816e49cfd07b40f82b44847a903ecf70baa204cece185fa14ebc88f59199e319ea4d5dd5178f196d2134fa51823aab6f2ff8fab948c29cfba62e01098e0266eafa96f84c9b27219c432959ec1b465b75c6d8366777b4e6bdf0401ce8c82edcd2412b4c59a1aec8cade66523bd7968154b51e0bad4516b42f4eb405ace272c2ba2bb3fe5d99ab99d187dfc5b883b2fb6c8491389845110eae3d22010a0bcfa1bbea435f4dbc7b19275326348eb259a4833cb3d27e6228475d9a7c92a114c4867ac5da91d4c58b2e22035be3cd28471c61a46b32f22b858b2d001c45988a7212609ff59ca1b5de564c018eac8ba7de7d4bc0b1d33bd4693b0e7511072989f157cb9d0324ad371cf2336adcd8534a7c7579e7821cca392e9153d1c6630e8b80fdbeef0d7deef036eb45f6793ec0a39c39fe7325c91a52ccc79bb09d25056fba984ecf817cfdee30d35015845690deecafbc2f50e2601f59dd4a2b6d9e6738bafdbc74a7cba9e03dc57dcb1550d3aa8df06ee9c50792ca6b0003062465d4e32c010ba02e9696978c311648dd69e903f0458be65d137772e8075e179ccc3133daa74fbe1e61c1bf954c3e0be3cd4530394cc046732e9afcf2f33d84ffb9651ab079137bcbbd9c89bf6552a7b1270c074a328bb84c0d2bc6a75d9b9b7ca210bcd0a3d340f428379701a60a6f10144ce505c8453597e879d04ca100583703e38eab0d577cdcb116a9c75fb871549dbee03581547887600076a97c8ddb3ce32c61b76b51b5523f82c390fdd617904a76fb6cfc33486c380ad6f62981d8ac5afabf7c21486d1e85e11cb8b1eedbbf310b42b69ec42afaa8b18631ce18d60fa77006fd422d92a86584e4c7ea9a83b9a5d362ba11d6f7c3be13456932697a12477cca4792eba415446260fcb30a8ebe71e375f240a14a66d08126dfbd5528ef031f9b44e45' + ), + 'raw-seed': new Uint8Array([ + 153, 21, 95, 99, 48, 150, 218, 124, 190, 8, 122, 137, 72, 184, 79, 118, + 123, 16, 249, 1, 200, 35, 194, 64, 177, 221, 43, 200, 112, 5, 201, 62, + ]), + jwk: { + priv: 'mRVfYzCW2ny-CHqJSLhPdnsQ-QHII8JAsd0ryHAFyT4', + kty: 'AKP', + alg: 'ML-DSA-44', + pub: 'VZjVRMYUsVTIvCFoJKHBf-KXMGt6v1lWvAP1xxJPqMDa2t_jVIUpuwm3Dt6biVRvimHqmDQPoy_j2hMU5V1j_JvVHvGe09W_m0nTkTvCS4wDoZWLMKybrHjqjk9OdNe4MraiwF3ds9hGulxdM749rWnOCdA0NtD8c7CSdhcABSmXefH2wc7UoLUHY9xOYHuOI2sl2oqL5M-mhFckdPuuCinEqxrUWtXfjVfoOy6tEPetBNul6gjZ6aMNCqAWV-gCCVyxI0M3aDPM51HRPh91OI1ObZR2v13BOx5Y7ROpDguWZteQRfYgn24xS07hebjO6n6rpCvt9D9TRojV9Hm4Isn5X0ClYw7D5xJ5FJxQ54XFAF7DFvv_rtVnS1g6ikIlVaIP8h0xk7-jqm3DFj_FlXVkJFFzy34-VmfBtkXu6aI--ISe1NC7f9TGqfUamRzPVUGRyBfEJkAxNum5SJxW5n-YbLjwbQhn5M6OSUrWNLbLUsmvvG8q6Aixgy_tXHjSfDC514kkRqKkdwCbFDkhG9xN_um-aocVwjnuX6JOpCHS1ytkYOhXEytB8LcRg_dh8Qdvnyj8LeRMRy5VtTYph6KQ44B5rc93NhPFF-ewfb4gTDwiGKAqSb58YwUJ1gbcsc5P3gqO-j-zQxWfOX7vHO7wa0-5ruiokoDldxMVIe_BKrKYfBjLg8FdogLQ5xTL6C82cv_sYWOcD6BLPG87IxnmK1uqoUpGs7T7R8XwaConys4Mc_mKN_zYPbl5TImsplhcghI0Qw27MZPUTUo4O3tjzSSJYG-UeZ0CU_ZWnJhirE301uG48HmQONWhK0MEoWjKW4b3bBguuz_YMn14EdgW5Jz9B7QPgrRIR6kD7PcLqiBM7OGF-hTryI9ZGZ4xnqTV3VF48ZbSE0-lGCOqtvL_j6uUjCnPumLgEJjgJm6vqW-EybJyGcQylZ7BtGW3XG2DZnd7TmvfBAHOjILtzSQStMWaGuyMreZlI715aBVLUeC61FFrQvTrQFrOJywrors_5dmauZ0YffxbiDsvtshJE4mEURDq49IgEKC8-hu-pDX028exknUyY0jrJZpIM8s9J-YihHXZp8kqEUxIZ6xdqR1MWLLiIDW-PNKEccYaRrMvIrhYstABxFmIpyEmCf9Zyhtd5WTAGOrIun3n1LwLHTO9RpOw51EQcpifFXy50DJK03HPIzatzYU0p8dXnnghzKOS6RU9HGYw6LgP2-7w197vA260X2eT7Ao5w5_nMlyRpSzMebsJ0lBW-6mE7PgXz97jDTUBWEVpDe7K-8L1DiYB9Z3UorbZ5nOLr9vHSny6ngPcV9yxVQ06qN8G7pxQeSymsAAwYkZdTjLAELoC6WlpeMMRZI3WnpA_BFi-ZdE3dy6AdeF5zMMTPap0--HmHBv5VMPgvjzUUwOUzARnMumvzy8z2E_7llGrB5E3vLvZyJv2VSp7EnDAdKMou4TA0rxqddm5t8ohC80KPTQPQoN5cBpgpvEBRM5QXIRTWX6HnQTKEAWDcD446rDVd83LEWqcdfuHFUnb7gNYFUeIdgAHapfI3bPOMsYbdrUbVSP4LDkP3WF5BKdvts_DNIbDgK1vYpgdisWvq_fCFIbR6F4Ry4se7bvzELQraexCr6qLGGMc4Y1g-ncAb9Qi2SqGWE5MfqmoO5pdNiuhHW98O-E0VpMml6Ekd8ykeS66QVRGJg_LMKjr5x43XyQKFKZtCBJt-9VSjvAx-bRORQ', + }, + }, + 'ML-DSA-65': { + privateUsages: ['sign'], + publicUsages: ['verify'], + pkcs8: new Uint8Array([ + 48, 52, 2, 1, 0, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 3, 18, 4, 34, + 128, 32, 132, 164, 137, 75, 123, 70, 164, 178, 3, 156, 206, 16, 195, 26, + 133, 186, 176, 195, 102, 48, 254, 35, 29, 66, 103, 17, 67, 152, 38, 7, + 130, 139, + ]), + spki: new Uint8Array([ + 48, 130, 7, 178, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 3, 18, 3, 130, + 7, 161, 0, 216, 177, 233, 60, 151, 24, 246, 66, 175, 161, 192, 118, 9, + 177, 87, 232, 5, 216, 49, 254, 251, 160, 51, 216, 250, 171, 229, 104, 149, + 117, 135, 107, 5, 239, 244, 167, 83, 57, 49, 153, 29, 135, 108, 138, 117, + 236, 120, 65, 89, 65, 17, 201, 127, 147, 246, 103, 238, 204, 25, 83, 240, + 29, 173, 127, 140, 1, 88, 40, 43, 134, 51, 19, 125, 131, 224, 50, 167, 82, + 20, 217, 215, 162, 41, 95, 215, 56, 130, 226, 177, 216, 20, 169, 133, 85, + 140, 9, 105, 172, 54, 121, 0, 87, 202, 18, 93, 96, 147, 103, 127, 164, 63, + 197, 97, 49, 230, 125, 53, 80, 64, 20, 239, 29, 90, 118, 102, 221, 177, 6, + 220, 220, 170, 107, 107, 18, 138, 125, 138, 70, 66, 60, 185, 232, 209, 4, + 100, 17, 118, 24, 181, 110, 241, 50, 250, 138, 209, 19, 84, 220, 61, 96, + 80, 128, 81, 101, 160, 9, 5, 53, 33, 112, 60, 59, 195, 79, 115, 190, 101, + 93, 56, 171, 146, 51, 82, 233, 66, 225, 226, 211, 72, 58, 9, 74, 222, 185, + 175, 211, 156, 164, 68, 188, 119, 46, 14, 64, 160, 13, 207, 60, 81, 68, + 108, 148, 59, 88, 88, 92, 88, 171, 249, 204, 160, 137, 222, 234, 168, 233, + 3, 86, 224, 174, 105, 224, 1, 177, 184, 230, 236, 30, 85, 249, 56, 105, + 211, 50, 83, 168, 139, 28, 175, 181, 22, 89, 166, 215, 152, 218, 184, 111, + 65, 24, 82, 71, 185, 100, 172, 66, 178, 6, 215, 164, 252, 56, 40, 198, + 207, 152, 110, 186, 207, 39, 235, 179, 38, 215, 88, 105, 109, 177, 130, + 91, 5, 223, 164, 78, 241, 176, 125, 197, 94, 100, 40, 214, 251, 239, 253, + 88, 154, 14, 75, 254, 94, 210, 86, 244, 51, 95, 168, 139, 213, 73, 87, + 151, 209, 150, 126, 88, 69, 251, 116, 157, 122, 96, 212, 206, 42, 218, 38, + 85, 184, 50, 246, 188, 35, 72, 60, 226, 155, 246, 86, 209, 110, 133, 161, + 129, 126, 80, 154, 238, 64, 64, 170, 156, 177, 225, 52, 87, 42, 88, 154, + 174, 246, 30, 84, 143, 221, 51, 27, 65, 60, 40, 22, 120, 42, 145, 34, 82, + 235, 79, 20, 215, 211, 231, 151, 108, 119, 53, 116, 190, 13, 139, 199, + 189, 84, 54, 186, 222, 90, 116, 253, 227, 207, 104, 209, 118, 42, 144, 94, + 22, 219, 198, 211, 216, 171, 75, 245, 61, 240, 157, 108, 81, 19, 238, 39, + 120, 210, 242, 63, 126, 6, 15, 18, 97, 232, 207, 184, 84, 239, 72, 115, + 90, 95, 112, 78, 45, 201, 13, 102, 208, 151, 146, 253, 153, 177, 115, 14, + 194, 184, 107, 118, 120, 63, 105, 89, 144, 60, 242, 80, 106, 32, 11, 204, + 170, 165, 221, 182, 31, 187, 159, 216, 118, 218, 207, 182, 107, 136, 211, + 162, 231, 196, 128, 83, 251, 192, 189, 149, 1, 245, 36, 146, 159, 11, 116, + 30, 191, 141, 182, 157, 227, 91, 88, 72, 224, 55, 195, 96, 245, 135, 249, + 142, 16, 229, 237, 27, 60, 2, 91, 138, 82, 197, 210, 40, 8, 123, 172, 202, + 207, 119, 199, 190, 102, 40, 141, 174, 93, 211, 219, 134, 105, 26, 103, + 100, 102, 62, 130, 224, 135, 173, 82, 224, 200, 213, 76, 211, 38, 181, 16, + 97, 99, 75, 14, 42, 162, 223, 237, 141, 1, 29, 140, 191, 146, 49, 236, + 179, 88, 202, 220, 124, 239, 231, 131, 101, 134, 111, 28, 54, 151, 172, + 67, 167, 113, 96, 204, 63, 76, 169, 95, 14, 175, 149, 189, 173, 39, 177, + 102, 23, 158, 102, 236, 224, 70, 203, 190, 132, 230, 136, 3, 28, 201, 131, + 148, 164, 219, 181, 208, 26, 239, 111, 86, 35, 102, 133, 114, 113, 180, + 184, 82, 180, 106, 124, 248, 126, 87, 177, 165, 176, 204, 128, 141, 179, + 141, 34, 119, 160, 57, 206, 168, 95, 197, 110, 79, 60, 48, 170, 125, 206, + 147, 137, 156, 85, 46, 7, 193, 228, 150, 22, 46, 147, 51, 153, 157, 248, + 151, 253, 114, 58, 126, 38, 127, 19, 225, 99, 183, 235, 175, 90, 166, 8, + 233, 141, 10, 85, 232, 147, 7, 20, 137, 240, 84, 231, 86, 134, 50, 212, + 201, 6, 253, 18, 150, 114, 160, 140, 2, 254, 189, 152, 14, 68, 110, 50, + 134, 199, 73, 237, 56, 116, 110, 135, 36, 40, 14, 167, 50, 71, 81, 9, 178, + 54, 182, 247, 64, 32, 204, 116, 92, 131, 40, 30, 246, 188, 236, 182, 187, + 132, 239, 124, 136, 238, 146, 137, 247, 87, 52, 15, 78, 108, 135, 178, + 101, 70, 199, 193, 192, 144, 196, 106, 186, 141, 42, 101, 214, 196, 67, + 175, 38, 8, 189, 148, 166, 253, 221, 144, 119, 81, 1, 232, 175, 81, 237, + 13, 188, 220, 230, 47, 115, 184, 179, 0, 51, 118, 39, 22, 114, 232, 88, + 15, 121, 216, 130, 107, 173, 108, 175, 225, 113, 40, 223, 185, 6, 244, + 227, 73, 38, 64, 84, 10, 200, 53, 81, 179, 217, 106, 172, 59, 161, 70, + 180, 70, 48, 56, 46, 233, 133, 245, 57, 120, 154, 167, 49, 109, 188, 152, + 245, 181, 1, 159, 247, 44, 167, 152, 6, 191, 246, 38, 120, 141, 57, 241, + 168, 60, 38, 6, 82, 248, 87, 85, 0, 10, 22, 19, 44, 178, 63, 38, 78, 1, + 210, 166, 140, 3, 199, 112, 135, 155, 36, 13, 204, 124, 47, 5, 190, 103, + 91, 205, 147, 248, 115, 177, 196, 180, 234, 85, 35, 24, 182, 16, 207, 107, + 167, 10, 54, 193, 146, 71, 95, 45, 109, 184, 43, 101, 155, 184, 55, 171, + 196, 136, 89, 227, 84, 183, 31, 0, 137, 230, 146, 250, 6, 27, 225, 241, + 11, 95, 124, 248, 133, 171, 149, 67, 73, 19, 110, 104, 173, 86, 6, 246, + 195, 196, 200, 175, 53, 18, 198, 223, 140, 85, 208, 253, 204, 220, 255, + 232, 88, 238, 20, 97, 24, 52, 13, 3, 179, 62, 151, 101, 67, 33, 79, 253, + 157, 253, 233, 197, 109, 130, 78, 11, 165, 214, 200, 41, 157, 63, 46, 175, + 251, 246, 225, 227, 199, 92, 107, 216, 58, 124, 226, 202, 153, 92, 31, + 250, 182, 92, 99, 0, 110, 18, 78, 228, 166, 190, 67, 88, 245, 155, 139, + 82, 152, 39, 204, 74, 140, 95, 82, 82, 160, 147, 144, 33, 0, 242, 200, 22, + 102, 160, 233, 102, 224, 42, 205, 240, 56, 95, 197, 226, 175, 235, 240, + 125, 10, 51, 12, 246, 150, 234, 173, 95, 132, 173, 174, 1, 161, 23, 39, + 52, 168, 87, 54, 4, 66, 201, 34, 155, 82, 133, 170, 76, 52, 226, 109, 163, + 19, 34, 184, 226, 39, 20, 75, 72, 201, 70, 188, 71, 182, 230, 6, 19, 255, + 8, 145, 193, 63, 81, 150, 24, 72, 89, 168, 74, 98, 173, 133, 67, 227, 44, + 252, 252, 227, 192, 125, 20, 227, 144, 24, 31, 48, 67, 67, 48, 94, 163, + 52, 219, 163, 225, 214, 214, 109, 211, 122, 213, 198, 90, 204, 40, 97, + 211, 121, 17, 28, 132, 246, 110, 230, 51, 197, 42, 162, 143, 199, 158, + 215, 210, 133, 60, 65, 127, 1, 153, 193, 22, 171, 250, 114, 204, 246, 255, + 126, 25, 96, 44, 164, 102, 172, 211, 23, 245, 122, 48, 221, 249, 138, 148, + 134, 206, 135, 246, 42, 235, 198, 89, 189, 45, 125, 204, 69, 193, 48, 29, + 144, 125, 224, 127, 66, 1, 134, 141, 224, 211, 193, 141, 69, 128, 75, 167, + 244, 160, 120, 54, 191, 214, 29, 40, 249, 15, 46, 68, 141, 91, 242, 91, + 80, 252, 109, 122, 154, 64, 153, 56, 65, 254, 106, 18, 4, 172, 171, 136, + 80, 98, 79, 133, 255, 4, 100, 191, 144, 171, 219, 46, 132, 181, 130, 228, + 107, 68, 32, 123, 201, 17, 67, 35, 144, 180, 160, 30, 125, 9, 55, 184, + 172, 0, 159, 250, 232, 83, 168, 162, 102, 158, 121, 208, 177, 116, 163, + 160, 80, 241, 46, 156, 58, 203, 240, 67, 176, 244, 170, 160, 115, 122, + 141, 154, 101, 218, 178, 119, 130, 195, 32, 207, 51, 149, 98, 51, 219, 57, + 121, 216, 156, 101, 218, 184, 220, 204, 41, 181, 149, 63, 80, 194, 11, + 143, 164, 219, 23, 123, 141, 119, 43, 94, 78, 175, 89, 165, 48, 167, 44, + 45, 219, 197, 15, 202, 118, 116, 245, 151, 218, 14, 199, 96, 27, 102, 206, + 198, 123, 222, 178, 210, 20, 200, 38, 25, 124, 58, 102, 92, 197, 107, 51, + 5, 236, 125, 173, 198, 113, 144, 108, 177, 22, 104, 223, 165, 39, 9, 84, + 87, 124, 80, 153, 8, 212, 76, 2, 28, 12, 90, 212, 129, 148, 212, 229, 63, + 29, 200, 113, 171, 154, 107, 189, 202, 22, 147, 7, 32, 253, 70, 37, 224, + 98, 199, 129, 21, 54, 49, 52, 124, 84, 40, 190, 194, 108, 73, 26, 15, 124, + 87, 87, 198, 217, 122, 127, 82, 167, 131, 59, 8, 172, 49, 162, 61, 64, 79, + 196, 205, 65, 110, 75, 130, 128, 197, 182, 251, 110, 141, 197, 184, 166, + 244, 246, 217, 20, 105, 85, 42, 80, 251, 77, 59, 204, 247, 179, 218, 181, + 124, 209, 4, 28, 118, 234, 145, 237, 140, 106, 54, 88, 82, 28, 235, 68, + 221, 109, 139, 11, 166, 182, 63, 142, 194, 255, 213, 219, 116, 158, 31, + 224, 119, 126, 232, 160, 144, 1, 177, 92, 219, 162, 49, 181, 116, 163, + 104, 245, 193, 188, 26, 172, 15, 190, 135, 207, 106, 246, 13, 132, 76, + 189, 160, 25, 123, 26, 20, 48, 203, 59, 209, 69, 235, 103, 253, 160, 108, + 83, 206, 70, 98, 0, 2, 57, 162, 202, 63, 45, 89, 173, 201, 254, 254, 253, + 143, 21, 77, 131, 184, 234, 37, 68, 206, 69, 186, 179, 145, 147, 135, 42, + 137, 152, 253, 213, 240, 13, 122, 161, 218, 186, 180, 213, 162, 150, 231, + 63, 112, 182, 233, 86, 12, 225, 195, 133, 37, 28, 22, 147, 201, 200, 197, + 115, 3, 138, 194, 86, 79, 247, 27, 241, 149, 128, 197, 8, 11, 134, 53, + 118, 175, 248, 253, 114, 91, 31, 192, 253, 209, 111, 31, 228, 244, 184, + 179, 146, 145, 167, 137, 155, 184, 218, 38, 62, 187, 22, 181, 193, 93, 16, + 9, 195, 42, 198, 225, 100, 144, 148, 223, 184, 40, 117, 32, 131, 94, 93, + 83, 88, 125, 95, 220, 20, 206, 7, 228, 78, 54, 238, 178, 196, 38, 245, 95, + 8, 235, 106, 17, 175, 142, 193, 60, 179, 53, 244, 92, 147, 244, 218, 95, + 127, 251, 128, 42, 105, 82, 243, 224, 213, 25, 91, 151, 22, 201, 18, 25, + 230, 165, 85, 25, 249, 170, 160, 171, 210, 209, 32, 154, 124, 245, 60, 30, + 255, 138, 154, 29, 85, 156, 232, 177, 78, 14, 137, 52, 215, 247, 26, 211, + 115, 72, 20, 133, 232, 1, 151, 251, 63, 45, 120, 69, 49, 209, 130, 255, 2, + 218, 21, 251, 16, 86, 30, 62, 136, 92, 149, 60, 6, 125, 129, 145, 235, + 102, 190, 144, 248, 1, 53, 135, 21, 158, 44, 158, 230, 246, 172, 249, 161, + 105, 204, 49, 60, 70, 63, 127, 163, 231, 175, 174, 234, 147, 185, 62, 5, + 244, 156, 4, 31, 39, 156, 176, 154, 251, 166, 143, 212, 43, 30, 97, 50, + 37, 176, 155, 77, 149, 102, + ]), + 'raw-public': hexStringToUint8Array( + 'd8b1e93c9718f642afa1c07609b157e805d831fefba033d8faabe5689575876b05eff4a7533931991d876c8a75ec7841594111c97f93f667eecc1953f01dad7f8c0158282b8633137d83e032a75214d9d7a2295fd73882e2b1d814a985558c0969ac36790057ca125d6093677fa43fc56131e67d35504014ef1d5a7666ddb106dcdcaa6b6b128a7d8a46423cb9e8d10464117618b56ef132fa8ad11354dc3d6050805165a009053521703c3bc34f73be655d38ab923352e942e1e2d3483a094adeb9afd39ca444bc772e0e40a00dcf3c51446c943b58585c58abf9cca089deeaa8e90356e0ae69e001b1b8e6ec1e55f93869d33253a88b1cafb51659a6d798dab86f41185247b964ac42b206d7a4fc3828c6cf986ebacf27ebb326d758696db1825b05dfa44ef1b07dc55e6428d6fbeffd589a0e4bfe5ed256f4335fa88bd5495797d1967e5845fb749d7a60d4ce2ada2655b832f6bc23483ce29bf656d16e85a1817e509aee4040aa9cb1e134572a589aaef61e548fdd331b413c2816782a912252eb4f14d7d3e7976c773574be0d8bc7bd5436bade5a74fde3cf68d1762a905e16dbc6d3d8ab4bf53df09d6c5113ee2778d2f23f7e060f1261e8cfb854ef48735a5f704e2dc90d66d09792fd99b1730ec2b86b76783f6959903cf2506a200bccaaa5ddb61fbb9fd876dacfb66b88d3a2e7c48053fbc0bd9501f524929f0b741ebf8db69de35b5848e037c360f587f98e10e5ed1b3c025b8a52c5d228087baccacf77c7be66288dae5dd3db86691a6764663e82e087ad52e0c8d54cd326b51061634b0e2aa2dfed8d011d8cbf9231ecb358cadc7cefe78365866f1c3697ac43a77160cc3f4ca95f0eaf95bdad27b166179e66ece046cbbe84e688031cc98394a4dbb5d01aef6f562366857271b4b852b46a7cf87e57b1a5b0cc808db38d2277a039cea85fc56e4f3c30aa7dce93899c552e07c1e496162e9333999df897fd723a7e267f13e163b7ebaf5aa608e98d0a55e893071489f054e7568632d4c906fd129672a08c02febd980e446e3286c749ed38746e8724280ea732475109b236b6f74020cc745c83281ef6bcecb6bb84ef7c88ee9289f757340f4e6c87b26546c7c1c090c46aba8d2a65d6c443af2608bd94a6fddd90775101e8af51ed0dbcdce62f73b8b3003376271672e8580f79d8826bad6cafe17128dfb906f4e3492640540ac83551b3d96aac3ba146b44630382ee985f539789aa7316dbc98f5b5019ff72ca79806bff626788d39f1a83c260652f85755000a16132cb23f264e01d2a68c03c770879b240dcc7c2f05be675bcd93f873b1c4b4ea552318b610cf6ba70a36c192475f2d6db82b659bb837abc48859e354b71f0089e692fa061be1f10b5f7cf885ab954349136e68ad5606f6c3c4c8af3512c6df8c55d0fdccdcffe858ee146118340d03b33e976543214ffd9dfde9c56d824e0ba5d6c8299d3f2eaffbf6e1e3c75c6bd83a7ce2ca995c1ffab65c63006e124ee4a6be4358f59b8b529827cc4a8c5f5252a093902100f2c81666a0e966e02acdf0385fc5e2afebf07d0a330cf696eaad5f84adae01a1172734a857360442c9229b5285aa4c34e26da31322b8e227144b48c946bc47b6e60613ff0891c13f5196184859a84a62ad8543e32cfcfce3c07d14e390181f304343305ea334dba3e1d6d66dd37ad5c65acc2861d379111c84f66ee633c52aa28fc79ed7d2853c417f0199c116abfa72ccf6ff7e19602ca466acd317f57a30ddf98a9486ce87f62aebc659bd2d7dcc45c1301d907de07f4201868de0d3c18d45804ba7f4a07836bfd61d28f90f2e448d5bf25b50fc6d7a9a40993841fe6a1204acab8850624f85ff0464bf90abdb2e84b582e46b44207bc911432390b4a01e7d0937b8ac009ffae853a8a2669e79d0b174a3a050f12e9c3acbf043b0f4aaa0737a8d9a65dab27782c320cf33956233db3979d89c65dab8dccc29b5953f50c20b8fa4db177b8d772b5e4eaf59a530a72c2ddbc50fca7674f597da0ec7601b66cec67bdeb2d214c826197c3a665cc56b3305ec7dadc671906cb11668dfa5270954577c509908d44c021c0c5ad48194d4e53f1dc871ab9a6bbdca16930720fd4625e062c781153631347c5428bec26c491a0f7c5757c6d97a7f52a7833b08ac31a23d404fc4cd416e4b8280c5b6fb6e8dc5b8a6f4f6d91469552a50fb4d3bccf7b3dab57cd1041c76ea91ed8c6a3658521ceb44dd6d8b0ba6b63f8ec2ffd5db749e1fe0777ee8a09001b15cdba231b574a368f5c1bc1aac0fbe87cf6af60d844cbda0197b1a1430cb3bd145eb67fda06c53ce4662000239a2ca3f2d59adc9fefefd8f154d83b8ea2544ce45bab39193872a8998fdd5f00d7aa1dabab4d5a296e73f70b6e9560ce1c385251c1693c9c8c573038ac2564ff71bf19580c5080b863576aff8fd725b1fc0fdd16f1fe4f4b8b39291a7899bb8da263ebb16b5c15d1009c32ac6e1649094dfb8287520835e5d53587d5fdc14ce07e44e36eeb2c426f55f08eb6a11af8ec13cb335f45c93f4da5f7ffb802a6952f3e0d5195b9716c91219e6a55519f9aaa0abd2d1209a7cf53c1eff8a9a1d559ce8b14e0e8934d7f71ad373481485e80197fb3f2d784531d182ff02da15fb10561e3e885c953c067d8191eb66be90f8013587159e2c9ee6f6acf9a169cc313c463f7fa3e7afaeea93b93e05f49c041f279cb09afba68fd42b1e613225b09b4d9566' + ), + 'raw-seed': new Uint8Array([ + 132, 164, 137, 75, 123, 70, 164, 178, 3, 156, 206, 16, 195, 26, 133, 186, + 176, 195, 102, 48, 254, 35, 29, 66, 103, 17, 67, 152, 38, 7, 130, 139, + ]), + jwk: { + priv: 'hKSJS3tGpLIDnM4QwxqFurDDZjD-Ix1CZxFDmCYHgos', + kty: 'AKP', + alg: 'ML-DSA-65', + pub: '2LHpPJcY9kKvocB2CbFX6AXYMf77oDPY-qvlaJV1h2sF7_SnUzkxmR2HbIp17HhBWUERyX-T9mfuzBlT8B2tf4wBWCgrhjMTfYPgMqdSFNnXoilf1ziC4rHYFKmFVYwJaaw2eQBXyhJdYJNnf6Q_xWEx5n01UEAU7x1admbdsQbc3KpraxKKfYpGQjy56NEEZBF2GLVu8TL6itETVNw9YFCAUWWgCQU1IXA8O8NPc75lXTirkjNS6ULh4tNIOglK3rmv05ykRLx3Lg5AoA3PPFFEbJQ7WFhcWKv5zKCJ3uqo6QNW4K5p4AGxuObsHlX5OGnTMlOoixyvtRZZpteY2rhvQRhSR7lkrEKyBtek_Dgoxs-YbrrPJ-uzJtdYaW2xglsF36RO8bB9xV5kKNb77_1Ymg5L_l7SVvQzX6iL1UlXl9GWflhF-3SdemDUziraJlW4Mva8I0g84pv2VtFuhaGBflCa7kBAqpyx4TRXKliarvYeVI_dMxtBPCgWeCqRIlLrTxTX0-eXbHc1dL4Ni8e9VDa63lp0_ePPaNF2KpBeFtvG09irS_U98J1sURPuJ3jS8j9-Bg8SYejPuFTvSHNaX3BOLckNZtCXkv2ZsXMOwrhrdng_aVmQPPJQaiALzKql3bYfu5_YdtrPtmuI06LnxIBT-8C9lQH1JJKfC3Qev422neNbWEjgN8Ng9Yf5jhDl7Rs8AluKUsXSKAh7rMrPd8e-ZiiNrl3T24ZpGmdkZj6C4IetUuDI1UzTJrUQYWNLDiqi3-2NAR2Mv5Ix7LNYytx87-eDZYZvHDaXrEOncWDMP0ypXw6vlb2tJ7FmF55m7OBGy76E5ogDHMmDlKTbtdAa729WI2aFcnG0uFK0anz4flexpbDMgI2zjSJ3oDnOqF_Fbk88MKp9zpOJnFUuB8HklhYukzOZnfiX_XI6fiZ_E-Fjt-uvWqYI6Y0KVeiTBxSJ8FTnVoYy1MkG_RKWcqCMAv69mA5EbjKGx0ntOHRuhyQoDqcyR1EJsja290AgzHRcgyge9rzstruE73yI7pKJ91c0D05sh7JlRsfBwJDEarqNKmXWxEOvJgi9lKb93ZB3UQHor1HtDbzc5i9zuLMAM3YnFnLoWA952IJrrWyv4XEo37kG9ONJJkBUCsg1UbPZaqw7oUa0RjA4LumF9Tl4mqcxbbyY9bUBn_csp5gGv_YmeI058ag8JgZS-FdVAAoWEyyyPyZOAdKmjAPHcIebJA3MfC8FvmdbzZP4c7HEtOpVIxi2EM9rpwo2wZJHXy1tuCtlm7g3q8SIWeNUtx8AieaS-gYb4fELX3z4hauVQ0kTbmitVgb2w8TIrzUSxt-MVdD9zNz_6FjuFGEYNA0Dsz6XZUMhT_2d_enFbYJOC6XWyCmdPy6v-_bh48dca9g6fOLKmVwf-rZcYwBuEk7kpr5DWPWbi1KYJ8xKjF9SUqCTkCEA8sgWZqDpZuAqzfA4X8Xir-vwfQozDPaW6q1fhK2uAaEXJzSoVzYEQskim1KFqkw04m2jEyK44icUS0jJRrxHtuYGE_8IkcE_UZYYSFmoSmKthUPjLPz848B9FOOQGB8wQ0MwXqM026Ph1tZt03rVxlrMKGHTeREchPZu5jPFKqKPx57X0oU8QX8BmcEWq_pyzPb_fhlgLKRmrNMX9Xow3fmKlIbOh_Yq68ZZvS19zEXBMB2QfeB_QgGGjeDTwY1FgEun9KB4Nr_WHSj5Dy5EjVvyW1D8bXqaQJk4Qf5qEgSsq4hQYk-F_wRkv5Cr2y6EtYLka0Qge8kRQyOQtKAefQk3uKwAn_roU6iiZp550LF0o6BQ8S6cOsvwQ7D0qqBzeo2aZdqyd4LDIM8zlWIz2zl52Jxl2rjczCm1lT9QwguPpNsXe413K15Or1mlMKcsLdvFD8p2dPWX2g7HYBtmzsZ73rLSFMgmGXw6ZlzFazMF7H2txnGQbLEWaN-lJwlUV3xQmQjUTAIcDFrUgZTU5T8dyHGrmmu9yhaTByD9RiXgYseBFTYxNHxUKL7CbEkaD3xXV8bZen9Sp4M7CKwxoj1AT8TNQW5LgoDFtvtujcW4pvT22RRpVSpQ-007zPez2rV80QQcduqR7YxqNlhSHOtE3W2LC6a2P47C_9XbdJ4f4Hd-6KCQAbFc26IxtXSjaPXBvBqsD76Hz2r2DYRMvaAZexoUMMs70UXrZ_2gbFPORmIAAjmiyj8tWa3J_v79jxVNg7jqJUTORbqzkZOHKomY_dXwDXqh2rq01aKW5z9wtulWDOHDhSUcFpPJyMVzA4rCVk_3G_GVgMUIC4Y1dq_4_XJbH8D90W8f5PS4s5KRp4mbuNomPrsWtcFdEAnDKsbhZJCU37godSCDXl1TWH1f3BTOB-RONu6yxCb1XwjrahGvjsE8szX0XJP02l9_-4AqaVLz4NUZW5cWyRIZ5qVVGfmqoKvS0SCafPU8Hv-Kmh1VnOixTg6JNNf3GtNzSBSF6AGX-z8teEUx0YL_AtoV-xBWHj6IXJU8Bn2BketmvpD4ATWHFZ4snub2rPmhacwxPEY_f6Pnr67qk7k-BfScBB8nnLCa-6aP1CseYTIlsJtNlWY', + }, + }, + 'ML-DSA-87': { + privateUsages: ['sign'], + publicUsages: ['verify'], + pkcs8: new Uint8Array([ + 48, 52, 2, 1, 0, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 3, 19, 4, 34, + 128, 32, 161, 80, 109, 145, 76, 109, 101, 140, 117, 39, 228, 51, 151, 221, + 109, 76, 37, 246, 164, 121, 116, 51, 90, 76, 208, 59, 254, 105, 131, 68, + 18, 81, + ]), + spki: new Uint8Array([ + 48, 130, 10, 50, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 3, 19, 3, 130, + 10, 33, 0, 146, 184, 67, 40, 172, 27, 204, 27, 135, 22, 109, 223, 127, 23, + 97, 130, 198, 228, 199, 62, 178, 21, 173, 20, 88, 180, 205, 168, 17, 164, + 135, 92, 85, 146, 76, 194, 152, 80, 239, 157, 33, 21, 239, 182, 176, 254, + 124, 80, 135, 138, 87, 169, 103, 99, 87, 5, 91, 161, 239, 59, 18, 246, + 148, 20, 32, 60, 117, 245, 182, 156, 196, 230, 82, 117, 228, 211, 81, 45, + 115, 217, 23, 95, 138, 95, 103, 124, 32, 89, 187, 48, 251, 103, 81, 234, + 76, 4, 57, 197, 71, 48, 125, 169, 195, 147, 183, 142, 166, 8, 147, 7, 77, + 240, 111, 44, 168, 23, 89, 107, 95, 220, 75, 202, 44, 25, 244, 200, 160, + 0, 174, 111, 107, 204, 22, 36, 122, 191, 101, 33, 52, 252, 14, 47, 25, + 109, 135, 48, 131, 253, 195, 237, 60, 86, 14, 119, 85, 28, 182, 139, 136, + 191, 59, 187, 90, 126, 207, 168, 238, 184, 83, 77, 254, 208, 21, 57, 104, + 188, 228, 134, 82, 249, 190, 249, 163, 120, 111, 68, 225, 210, 131, 29, + 151, 153, 146, 71, 163, 104, 225, 194, 33, 64, 213, 92, 145, 253, 42, 32, + 233, 95, 224, 72, 184, 119, 192, 113, 253, 177, 153, 246, 240, 49, 103, + 170, 229, 82, 69, 186, 36, 252, 29, 124, 255, 25, 148, 5, 160, 159, 105, + 157, 185, 25, 158, 122, 145, 30, 245, 51, 205, 62, 56, 154, 23, 52, 0, + 225, 177, 105, 195, 131, 177, 151, 197, 114, 110, 128, 227, 127, 176, 28, + 252, 217, 56, 61, 136, 148, 190, 124, 108, 129, 62, 243, 235, 37, 70, 228, + 233, 10, 67, 124, 120, 58, 164, 83, 57, 80, 39, 204, 98, 28, 199, 136, 75, + 12, 51, 255, 24, 130, 127, 19, 239, 160, 94, 137, 75, 15, 82, 158, 252, + 163, 43, 236, 193, 234, 27, 74, 69, 14, 179, 171, 10, 169, 27, 138, 172, + 213, 189, 222, 167, 110, 24, 11, 118, 151, 223, 94, 154, 125, 9, 21, 137, + 70, 128, 51, 102, 52, 105, 104, 157, 54, 186, 75, 217, 226, 169, 71, 125, + 177, 253, 218, 85, 236, 242, 25, 215, 147, 181, 104, 242, 82, 75, 50, 165, + 49, 102, 128, 82, 237, 170, 134, 162, 196, 56, 247, 199, 138, 102, 118, + 37, 66, 114, 165, 177, 156, 251, 39, 199, 12, 167, 246, 169, 150, 108, 91, + 192, 42, 68, 192, 244, 255, 107, 18, 191, 7, 73, 19, 174, 28, 116, 66, + 131, 96, 173, 60, 131, 190, 249, 219, 246, 71, 182, 124, 183, 129, 101, + 109, 95, 180, 78, 17, 140, 182, 62, 80, 195, 184, 253, 176, 169, 153, 1, + 29, 83, 39, 252, 150, 41, 219, 176, 48, 151, 108, 60, 255, 239, 0, 85, + 101, 193, 110, 204, 12, 254, 22, 136, 15, 154, 217, 88, 13, 28, 252, 232, + 48, 32, 33, 41, 221, 103, 227, 228, 177, 54, 175, 195, 106, 174, 140, 54, + 128, 108, 214, 228, 215, 118, 226, 206, 171, 21, 155, 162, 152, 135, 203, + 16, 170, 130, 100, 173, 155, 243, 80, 40, 98, 157, 248, 7, 101, 88, 199, + 218, 224, 141, 82, 238, 121, 92, 82, 97, 49, 31, 155, 61, 63, 84, 227, 90, + 143, 164, 59, 216, 101, 19, 35, 134, 2, 20, 18, 197, 97, 215, 169, 85, + 220, 75, 254, 91, 125, 144, 43, 65, 128, 29, 66, 77, 184, 172, 89, 123, + 203, 231, 254, 59, 18, 249, 204, 249, 220, 153, 84, 166, 63, 23, 108, 120, + 145, 216, 67, 223, 123, 248, 15, 253, 63, 191, 126, 84, 95, 98, 141, 66, + 200, 129, 194, 174, 30, 80, 48, 75, 113, 14, 102, 101, 218, 249, 14, 203, + 24, 6, 11, 89, 99, 56, 49, 17, 148, 160, 242, 101, 191, 102, 227, 115, 33, + 107, 71, 235, 6, 141, 68, 161, 162, 165, 227, 159, 82, 253, 54, 157, 214, + 255, 141, 151, 154, 134, 150, 93, 141, 97, 158, 244, 180, 135, 42, 10, 3, + 148, 9, 152, 149, 20, 18, 237, 253, 180, 136, 165, 13, 80, 195, 220, 43, + 3, 178, 10, 127, 144, 2, 207, 209, 246, 40, 110, 38, 133, 9, 22, 180, 11, + 223, 116, 236, 205, 186, 25, 183, 155, 165, 77, 206, 101, 255, 106, 223, + 70, 10, 22, 176, 119, 142, 163, 197, 178, 251, 216, 112, 237, 63, 201, 77, + 219, 196, 2, 176, 48, 15, 207, 91, 74, 236, 21, 8, 205, 126, 77, 28, 13, + 26, 28, 202, 250, 100, 79, 134, 209, 193, 78, 202, 58, 248, 124, 215, 64, + 143, 244, 17, 23, 163, 162, 241, 249, 49, 210, 168, 203, 213, 135, 77, 14, + 29, 35, 193, 234, 58, 12, 106, 165, 163, 251, 192, 115, 251, 7, 198, 189, + 93, 207, 178, 246, 50, 189, 185, 51, 45, 84, 140, 194, 34, 46, 92, 90, + 136, 81, 81, 53, 52, 253, 128, 247, 131, 243, 21, 207, 245, 141, 49, 178, + 213, 214, 211, 8, 17, 234, 133, 225, 104, 197, 186, 224, 117, 1, 173, 104, + 17, 177, 161, 223, 71, 195, 159, 194, 45, 177, 116, 26, 187, 193, 161, + 213, 179, 158, 8, 122, 186, 122, 191, 158, 5, 12, 178, 235, 78, 132, 78, + 189, 16, 86, 110, 73, 51, 129, 255, 242, 110, 63, 6, 53, 209, 110, 132, + 236, 43, 239, 192, 221, 138, 1, 128, 176, 0, 113, 85, 119, 201, 36, 188, + 202, 9, 223, 98, 196, 42, 130, 158, 149, 200, 150, 202, 132, 118, 153, 97, + 54, 195, 154, 15, 45, 246, 129, 144, 255, 231, 75, 25, 56, 47, 178, 98, + 10, 106, 84, 56, 113, 161, 227, 37, 246, 1, 245, 129, 173, 70, 186, 11, + 28, 125, 198, 243, 225, 113, 130, 5, 138, 52, 251, 194, 152, 105, 48, 214, + 13, 246, 228, 75, 236, 194, 223, 177, 64, 150, 97, 167, 20, 27, 74, 76, + 166, 199, 239, 91, 240, 8, 22, 54, 41, 63, 35, 112, 255, 251, 88, 252, + 147, 173, 185, 43, 98, 83, 155, 230, 176, 55, 161, 8, 83, 15, 110, 151, + 241, 110, 168, 203, 190, 198, 218, 152, 144, 150, 58, 123, 11, 123, 250, + 104, 113, 198, 93, 1, 152, 51, 172, 140, 246, 115, 113, 229, 218, 166, + 200, 35, 123, 16, 133, 169, 191, 59, 103, 12, 114, 15, 60, 37, 4, 92, 208, + 54, 31, 79, 56, 225, 6, 11, 74, 107, 79, 225, 239, 16, 73, 249, 234, 197, + 129, 230, 97, 39, 115, 49, 96, 141, 41, 242, 225, 177, 214, 18, 103, 34, + 229, 37, 176, 241, 99, 82, 227, 195, 77, 32, 64, 4, 120, 49, 199, 209, + 139, 2, 4, 222, 233, 45, 151, 141, 142, 252, 41, 124, 231, 13, 144, 63, + 212, 252, 145, 34, 142, 232, 152, 84, 135, 87, 175, 46, 53, 139, 60, 168, + 135, 167, 101, 253, 127, 152, 138, 154, 31, 231, 198, 77, 89, 182, 9, 54, + 103, 119, 100, 218, 245, 44, 191, 74, 30, 152, 84, 22, 62, 159, 131, 163, + 223, 3, 51, 194, 241, 49, 9, 213, 43, 214, 201, 75, 158, 198, 22, 203, + 209, 190, 199, 189, 75, 4, 6, 72, 60, 241, 113, 171, 30, 42, 143, 73, 51, + 72, 206, 110, 175, 203, 195, 199, 15, 155, 208, 166, 121, 26, 132, 59, 44, + 72, 155, 7, 48, 122, 132, 224, 142, 3, 7, 21, 207, 11, 30, 112, 18, 149, + 146, 127, 41, 104, 197, 169, 86, 213, 108, 253, 111, 160, 5, 11, 202, 172, + 233, 32, 5, 52, 92, 124, 152, 162, 11, 88, 28, 166, 248, 141, 251, 38, + 161, 53, 49, 136, 246, 183, 85, 9, 165, 115, 108, 18, 208, 218, 129, 165, + 163, 131, 34, 32, 94, 226, 121, 93, 24, 87, 226, 105, 25, 242, 128, 198, + 78, 26, 237, 21, 92, 33, 121, 8, 119, 131, 140, 193, 14, 60, 139, 130, 19, + 65, 96, 50, 5, 249, 12, 27, 51, 23, 195, 89, 255, 47, 23, 109, 62, 202, + 190, 5, 131, 92, 91, 39, 27, 209, 132, 146, 95, 98, 66, 26, 230, 186, 236, + 186, 162, 149, 81, 143, 221, 21, 79, 171, 236, 21, 161, 19, 135, 10, 213, + 168, 200, 135, 19, 221, 177, 207, 106, 214, 194, 124, 220, 53, 45, 176, + 245, 178, 189, 49, 242, 22, 230, 154, 241, 146, 230, 187, 180, 244, 158, + 145, 197, 225, 51, 150, 140, 26, 175, 78, 142, 243, 232, 221, 137, 205, + 130, 178, 54, 216, 136, 118, 212, 33, 90, 206, 18, 224, 158, 44, 23, 144, + 204, 24, 184, 48, 81, 233, 124, 20, 222, 77, 119, 144, 22, 145, 241, 19, + 206, 135, 252, 164, 114, 84, 37, 175, 107, 67, 243, 183, 137, 213, 53, + 236, 41, 73, 50, 34, 146, 218, 204, 68, 235, 158, 150, 139, 133, 75, 248, + 157, 7, 0, 53, 68, 44, 156, 110, 56, 197, 209, 201, 0, 155, 225, 85, 35, + 169, 193, 231, 36, 31, 142, 101, 168, 29, 192, 31, 128, 81, 191, 253, 184, + 153, 226, 214, 1, 27, 6, 0, 192, 36, 101, 72, 105, 150, 226, 3, 21, 12, + 127, 72, 250, 223, 240, 136, 249, 157, 129, 247, 91, 178, 157, 208, 86, + 146, 23, 176, 150, 35, 211, 155, 22, 207, 119, 168, 167, 122, 180, 183, + 106, 97, 138, 87, 96, 34, 141, 110, 145, 231, 226, 35, 115, 232, 129, 54, + 186, 128, 190, 238, 37, 169, 194, 37, 24, 237, 211, 164, 111, 54, 88, 245, + 125, 67, 78, 194, 11, 194, 235, 217, 87, 203, 14, 220, 189, 107, 68, 94, + 139, 66, 230, 5, 54, 64, 28, 246, 143, 75, 127, 239, 243, 20, 251, 189, + 246, 246, 151, 90, 219, 227, 242, 223, 205, 40, 124, 245, 4, 189, 72, 39, + 145, 110, 96, 120, 164, 27, 117, 146, 177, 30, 76, 173, 106, 130, 228, + 192, 189, 59, 167, 30, 127, 178, 164, 5, 133, 80, 199, 207, 216, 189, 156, + 93, 222, 150, 129, 81, 193, 180, 38, 59, 8, 214, 210, 95, 150, 182, 175, + 148, 43, 153, 169, 66, 62, 135, 140, 159, 89, 195, 253, 3, 132, 180, 164, + 244, 243, 232, 71, 196, 200, 158, 194, 114, 115, 193, 88, 161, 185, 235, + 247, 14, 126, 225, 176, 111, 17, 79, 77, 245, 80, 229, 174, 6, 180, 156, + 217, 85, 174, 201, 255, 237, 85, 83, 53, 188, 153, 98, 91, 193, 21, 211, + 49, 145, 196, 252, 52, 66, 226, 131, 203, 214, 130, 237, 194, 208, 174, + 102, 133, 220, 235, 222, 79, 232, 36, 21, 161, 248, 51, 185, 164, 156, 95, + 121, 65, 57, 233, 183, 29, 199, 105, 104, 12, 90, 195, 186, 81, 199, 176, + 1, 87, 16, 226, 192, 206, 185, 197, 46, 34, 75, 174, 153, 238, 15, 50, 87, + 226, 96, 26, 197, 202, 73, 235, 19, 140, 9, 79, 12, 52, 83, 76, 85, 146, + 234, 24, 151, 179, 178, 118, 58, 162, 223, 103, 69, 244, 231, 135, 167, + 204, 117, 166, 60, 237, 82, 63, 11, 4, 207, 10, 146, 54, 126, 191, 79, + 133, 60, 128, 34, 136, 170, 23, 84, 81, 38, 94, 9, 130, 245, 100, 115, + 209, 34, 228, 158, 101, 216, 135, 208, 207, 191, 169, 115, 252, 144, 139, + 226, 252, 6, 44, 221, 134, 170, 87, 11, 46, 124, 58, 219, 179, 238, 6, 98, + 216, 18, 174, 42, 12, 97, 126, 85, 245, 81, 220, 232, 135, 114, 21, 125, + 135, 225, 182, 245, 228, 223, 242, 62, 158, 35, 76, 6, 110, 25, 184, 206, + 124, 237, 54, 252, 199, 44, 78, 89, 0, 135, 44, 176, 57, 168, 36, 221, + 173, 77, 214, 209, 60, 1, 202, 238, 237, 61, 90, 47, 114, 230, 92, 238, + 235, 18, 151, 220, 243, 225, 163, 159, 139, 189, 253, 62, 225, 182, 202, + 59, 7, 83, 99, 129, 118, 175, 37, 246, 85, 119, 251, 246, 69, 180, 247, + 37, 24, 194, 89, 158, 97, 230, 247, 254, 145, 102, 89, 77, 68, 245, 3, + 103, 83, 28, 45, 168, 30, 189, 151, 112, 120, 215, 84, 90, 198, 85, 85, + 129, 55, 127, 124, 28, 137, 229, 139, 54, 88, 229, 105, 81, 212, 83, 28, + 107, 250, 82, 164, 43, 24, 15, 57, 206, 156, 19, 145, 95, 57, 169, 8, 128, + 211, 29, 213, 195, 148, 27, 73, 186, 221, 242, 11, 167, 78, 246, 133, 18, + 118, 67, 236, 59, 19, 112, 254, 93, 168, 157, 118, 0, 107, 248, 57, 149, + 67, 222, 123, 225, 207, 251, 69, 218, 56, 110, 162, 19, 25, 209, 209, 213, + 200, 158, 70, 9, 100, 208, 77, 48, 255, 151, 200, 0, 68, 230, 70, 120, + 209, 29, 86, 225, 188, 189, 226, 101, 42, 176, 32, 147, 121, 72, 151, 130, + 217, 13, 66, 148, 84, 129, 215, 249, 164, 174, 187, 80, 85, 185, 245, 108, + 169, 119, 59, 178, 144, 229, 63, 194, 132, 250, 131, 82, 161, 125, 126, + 255, 252, 220, 204, 104, 231, 201, 136, 246, 116, 43, 88, 233, 0, 43, 128, + 214, 40, 59, 81, 147, 139, 132, 69, 24, 233, 21, 14, 91, 230, 241, 19, + 138, 163, 55, 13, 221, 47, 64, 140, 248, 6, 38, 164, 16, 219, 63, 33, 180, + 71, 151, 0, 234, 103, 58, 213, 222, 163, 95, 132, 1, 178, 146, 66, 124, + 242, 223, 102, 129, 192, 214, 194, 117, 162, 252, 246, 143, 42, 70, 139, + 97, 168, 64, 141, 190, 115, 126, 93, 175, 59, 49, 9, 184, 88, 201, 100, + 182, 142, 145, 244, 72, 128, 203, 49, 196, 5, 5, 18, 46, 34, 87, 171, 132, + 158, 128, 75, 194, 8, 242, 52, 156, 229, 245, 56, 245, 88, 14, 195, 110, + 166, 51, 158, 245, 195, 120, 17, 166, 66, 100, 212, 188, 243, 2, 236, 90, + 8, 16, 35, 151, 122, 175, 115, 168, 186, 191, 60, 71, 23, 81, 217, 79, + 203, 239, 61, 146, 247, 168, 112, 83, 102, 146, 222, 178, 45, 247, 63, 23, + 181, 3, 136, 208, 62, 154, 203, 35, 250, 238, 61, 98, 207, 90, 169, 175, + 36, 227, 9, 182, 78, 226, 99, 89, 67, 105, 185, 35, 242, 162, 54, 99, 60, + 148, 14, 118, 1, 26, 120, 62, 82, 62, 222, 34, 99, 58, 174, 145, 199, 190, + 21, 182, 117, 238, 13, 170, 29, 67, 149, 44, 90, 94, 181, 125, 182, 186, + 82, 55, 105, 253, 29, 212, 67, 134, 204, 227, 94, 255, 127, 72, 157, 140, + 142, 224, 77, 149, 29, 170, 45, 163, 214, 209, 46, 28, 125, 177, 111, 2, + 92, 121, 252, 166, 204, 227, 173, 51, 60, 162, 243, 202, 207, 103, 30, + 153, 182, 116, 182, 130, 98, 59, 25, 141, 239, 49, 224, 176, 27, 237, 218, + 76, 68, 189, 108, 185, 136, 255, 105, 150, 11, 153, 44, 248, 139, 199, + 178, 235, 85, 115, 121, 144, 87, 221, 50, 222, 238, 16, 20, 51, 190, 93, + 248, 228, 84, 228, 115, 31, 229, 227, 137, 180, 44, 115, 224, 119, 129, + 181, 134, 224, 144, 186, 123, 208, 118, 96, 101, 177, 191, 232, 171, 6, + 17, 247, 187, 173, 84, 70, 249, 19, 191, 116, 172, 126, 131, 216, 123, + 225, 151, 55, 205, 177, 93, 139, 117, + ]), + 'raw-public': hexStringToUint8Array( + '92b84328ac1bcc1b87166ddf7f176182c6e4c73eb215ad1458b4cda811a4875c55924cc29850ef9d2115efb6b0fe7c50878a57a9676357055ba1ef3b12f69414203c75f5b69cc4e65275e4d3512d73d9175f8a5f677c2059bb30fb6751ea4c0439c547307da9c393b78ea60893074df06f2ca817596b5fdc4bca2c19f4c8a000ae6f6bcc16247abf652134fc0e2f196d873083fdc3ed3c560e77551cb68b88bf3bbb5a7ecfa8eeb8534dfed0153968bce48652f9bef9a3786f44e1d2831d97999247a368e1c22140d55c91fd2a20e95fe048b877c071fdb199f6f03167aae55245ba24fc1d7cff199405a09f699db9199e7a911ef533cd3e389a173400e1b169c383b197c5726e80e37fb01cfcd9383d8894be7c6c813ef3eb2546e4e90a437c783aa453395027cc621cc7884b0c33ff18827f13efa05e894b0f529efca32becc1ea1b4a450eb3ab0aa91b8aacd5bddea76e180b7697df5e9a7d091589468033663469689d36ba4bd9e2a9477db1fdda55ecf219d793b568f2524b32a531668052edaa86a2c438f7c78a6676254272a5b19cfb27c70ca7f6a9966c5bc02a44c0f4ff6b12bf074913ae1c74428360ad3c83bef9dbf647b67cb781656d5fb44e118cb63e50c3b8fdb0a999011d5327fc9629dbb030976c3cffef005565c16ecc0cfe16880f9ad9580d1cfce830202129dd67e3e4b136afc36aae8c36806cd6e4d776e2ceab159ba29887cb10aa8264ad9bf35028629df8076558c7dae08d52ee795c5261311f9b3d3f54e35a8fa43bd865132386021412c561d7a955dc4bfe5b7d902b41801d424db8ac597bcbe7fe3b12f9ccf9dc9954a63f176c7891d843df7bf80ffd3fbf7e545f628d42c881c2ae1e50304b710e6665daf90ecb18060b596338311194a0f265bf66e373216b47eb068d44a1a2a5e39f52fd369dd6ff8d979a86965d8d619ef4b4872a0a03940998951412edfdb488a50d50c3dc2b03b20a7f9002cfd1f6286e26850916b40bdf74eccdba19b79ba54dce65ff6adf460a16b0778ea3c5b2fbd870ed3fc94ddbc402b0300fcf5b4aec1508cd7e4d1c0d1a1ccafa644f86d1c14eca3af87cd7408ff41117a3a2f1f931d2a8cbd5874d0e1d23c1ea3a0c6aa5a3fbc073fb07c6bd5dcfb2f632bdb9332d548cc2222e5c5a8851513534fd80f783f315cff58d31b2d5d6d30811ea85e168c5bae07501ad6811b1a1df47c39fc22db1741abbc1a1d5b39e087aba7abf9e050cb2eb4e844ebd10566e493381fff26e3f0635d16e84ec2befc0dd8a0180b000715577c924bcca09df62c42a829e95c896ca8476996136c39a0f2df68190ffe74b19382fb2620a6a543871a1e325f601f581ad46ba0b1c7dc6f3e17182058a34fbc2986930d60df6e44becc2dfb1409661a7141b4a4ca6c7ef5bf0081636293f2370fffb58fc93adb92b62539be6b037a108530f6e97f16ea8cbbec6da9890963a7b0b7bfa6871c65d019833ac8cf67371e5daa6c8237b1085a9bf3b670c720f3c25045cd0361f4f38e1060b4a6b4fe1ef1049f9eac581e661277331608d29f2e1b1d6126722e525b0f16352e3c34d2040047831c7d18b0204dee92d978d8efc297ce70d903fd4fc91228ee898548757af2e358b3ca887a765fd7f988a9a1fe7c64d59b60936677764daf52cbf4a1e9854163e9f83a3df0333c2f13109d52bd6c94b9ec616cbd1bec7bd4b0406483cf171ab1e2a8f493348ce6eafcbc3c70f9bd0a6791a843b2c489b07307a84e08e030715cf0b1e701295927f2968c5a956d56cfd6fa0050bcaace92005345c7c98a20b581ca6f88dfb26a1353188f6b75509a5736c12d0da81a5a38322205ee2795d1857e26919f280c64e1aed155c21790877838cc10e3c8b821341603205f90c1b3317c359ff2f176d3ecabe05835c5b271bd184925f62421ae6baecbaa295518fdd154fabec15a113870ad5a8c88713ddb1cf6ad6c27cdc352db0f5b2bd31f216e69af192e6bbb4f49e91c5e133968c1aaf4e8ef3e8dd89cd82b236d88876d4215ace12e09e2c1790cc18b83051e97c14de4d77901691f113ce87fca4725425af6b43f3b789d535ec2949322292dacc44eb9e968b854bf89d070035442c9c6e38c5d1c9009be15523a9c1e7241f8e65a81dc01f8051bffdb899e2d6011b0600c02465486996e203150c7f48fadff088f99d81f75bb29dd0569217b09623d39b16cf77a8a77ab4b76a618a5760228d6e91e7e22373e88136ba80beee25a9c22518edd3a46f3658f57d434ec20bc2ebd957cb0edcbd6b445e8b42e60536401cf68f4b7feff314fbbdf6f6975adbe3f2dfcd287cf504bd4827916e6078a41b7592b11e4cad6a82e4c0bd3ba71e7fb2a4058550c7cfd8bd9c5dde968151c1b4263b08d6d25f96b6af942b99a9423e878c9f59c3fd0384b4a4f4f3e847c4c89ec27273c158a1b9ebf70e7ee1b06f114f4df550e5ae06b49cd955aec9ffed555335bc99625bc115d33191c4fc3442e283cbd682edc2d0ae6685dcebde4fe82415a1f833b9a49c5f794139e9b71dc769680c5ac3ba51c7b0015710e2c0ceb9c52e224bae99ee0f3257e2601ac5ca49eb138c094f0c34534c5592ea1897b3b2763aa2df6745f4e787a7cc75a63ced523f0b04cf0a92367ebf4f853c802288aa175451265e0982f56473d122e49e65d887d0cfbfa973fc908be2fc062cdd86aa570b2e7c3adbb3ee0662d812ae2a0c617e55f551dce88772157d87e1b6f5e4dff23e9e234c066e19b8ce7ced36fcc72c4e5900872cb039a824ddad4dd6d13c01caeeed3d5a2f72e65ceeeb1297dcf3e1a39f8bbdfd3ee1b6ca3b0753638176af25f65577fbf645b4f72518c2599e61e6f7fe9166594d44f50367531c2da81ebd977078d7545ac6555581377f7c1c89e58b3658e56951d4531c6bfa52a42b180f39ce9c13915f39a90880d31dd5c3941b49baddf20ba74ef685127643ec3b1370fe5da89d76006bf8399543de7be1cffb45da386ea21319d1d1d5c89e460964d04d30ff97c80044e64678d11d56e1bcbde2652ab0209379489782d90d42945481d7f9a4aebb5055b9f56ca9773bb290e53fc284fa8352a17d7efffcdccc68e7c988f6742b58e9002b80d6283b51938b844518e9150e5be6f1138aa3370ddd2f408cf80626a410db3f21b4479700ea673ad5dea35f8401b292427cf2df6681c0d6c275a2fcf68f2a468b61a8408dbe737e5daf3b3109b858c964b68e91f44880cb31c40505122e2257ab849e804bc208f2349ce5f538f5580ec36ea6339ef5c37811a64264d4bcf302ec5a081023977aaf73a8babf3c471751d94fcbef3d92f7a870536692deb22df73f17b50388d03e9acb23faee3d62cf5aa9af24e309b64ee263594369b923f2a236633c940e76011a783e523ede22633aae91c7be15b675ee0daa1d43952c5a5eb57db6ba523769fd1dd44386cce35eff7f489d8c8ee04d951daa2da3d6d12e1c7db16f025c79fca6cce3ad333ca2f3cacf671e99b674b682623b198def31e0b01bedda4c44bd6cb988ff69960b992cf88bc7b2eb5573799057dd32deee101433be5df8e454e4731fe5e389b42c73e07781b586e090ba7bd0766065b1bfe8ab0611f7bbad5446f913bf74ac7e83d87be19737cdb15d8b75' + ), + 'raw-seed': new Uint8Array([ + 161, 80, 109, 145, 76, 109, 101, 140, 117, 39, 228, 51, 151, 221, 109, 76, + 37, 246, 164, 121, 116, 51, 90, 76, 208, 59, 254, 105, 131, 68, 18, 81, + ]), + jwk: { + priv: 'oVBtkUxtZYx1J-Qzl91tTCX2pHl0M1pM0Dv-aYNEElE', + kty: 'AKP', + alg: 'ML-DSA-87', + pub: 'krhDKKwbzBuHFm3ffxdhgsbkxz6yFa0UWLTNqBGkh1xVkkzCmFDvnSEV77aw_nxQh4pXqWdjVwVboe87EvaUFCA8dfW2nMTmUnXk01Etc9kXX4pfZ3wgWbsw-2dR6kwEOcVHMH2pw5O3jqYIkwdN8G8sqBdZa1_cS8osGfTIoACub2vMFiR6v2UhNPwOLxlthzCD_cPtPFYOd1UctouIvzu7Wn7PqO64U03-0BU5aLzkhlL5vvmjeG9E4dKDHZeZkkejaOHCIUDVXJH9KiDpX-BIuHfAcf2xmfbwMWeq5VJFuiT8HXz_GZQFoJ9pnbkZnnqRHvUzzT44mhc0AOGxacODsZfFcm6A43-wHPzZOD2IlL58bIE-8-slRuTpCkN8eDqkUzlQJ8xiHMeISwwz_xiCfxPvoF6JSw9SnvyjK-zB6htKRQ6zqwqpG4qs1b3ep24YC3aX316afQkViUaAM2Y0aWidNrpL2eKpR32x_dpV7PIZ15O1aPJSSzKlMWaAUu2qhqLEOPfHimZ2JUJypbGc-yfHDKf2qZZsW8AqRMD0_2sSvwdJE64cdEKDYK08g7752_ZHtny3gWVtX7ROEYy2PlDDuP2wqZkBHVMn_JYp27Awl2w8_-8AVWXBbswM_haID5rZWA0c_OgwICEp3Wfj5LE2r8Nqrow2gGzW5Nd24s6rFZuimIfLEKqCZK2b81AoYp34B2VYx9rgjVLueVxSYTEfmz0_VONaj6Q72GUTI4YCFBLFYdepVdxL_lt9kCtBgB1CTbisWXvL5_47EvnM-dyZVKY_F2x4kdhD33v4D_0_v35UX2KNQsiBwq4eUDBLcQ5mZdr5DssYBgtZYzgxEZSg8mW_ZuNzIWtH6waNRKGipeOfUv02ndb_jZeahpZdjWGe9LSHKgoDlAmYlRQS7f20iKUNUMPcKwOyCn-QAs_R9ihuJoUJFrQL33TszboZt5ulTc5l_2rfRgoWsHeOo8Wy-9hw7T_JTdvEArAwD89bSuwVCM1-TRwNGhzK-mRPhtHBTso6-HzXQI_0ERejovH5MdKoy9WHTQ4dI8HqOgxqpaP7wHP7B8a9Xc-y9jK9uTMtVIzCIi5cWohRUTU0_YD3g_MVz_WNMbLV1tMIEeqF4WjFuuB1Aa1oEbGh30fDn8ItsXQau8Gh1bOeCHq6er-eBQyy606ETr0QVm5JM4H_8m4_BjXRboTsK-_A3YoBgLAAcVV3ySS8ygnfYsQqgp6VyJbKhHaZYTbDmg8t9oGQ_-dLGTgvsmIKalQ4caHjJfYB9YGtRroLHH3G8-FxggWKNPvCmGkw1g325Evswt-xQJZhpxQbSkymx-9b8AgWNik_I3D_-1j8k625K2JTm-awN6EIUw9ul_FuqMu-xtqYkJY6ewt7-mhxxl0BmDOsjPZzceXapsgjexCFqb87ZwxyDzwlBFzQNh9POOEGC0prT-HvEEn56sWB5mEnczFgjSny4bHWEmci5SWw8WNS48NNIEAEeDHH0YsCBN7pLZeNjvwpfOcNkD_U_JEijuiYVIdXry41izyoh6dl_X-Yipof58ZNWbYJNmd3ZNr1LL9KHphUFj6fg6PfAzPC8TEJ1SvWyUuexhbL0b7HvUsEBkg88XGrHiqPSTNIzm6vy8PHD5vQpnkahDssSJsHMHqE4I4DBxXPCx5wEpWSfyloxalW1Wz9b6AFC8qs6SAFNFx8mKILWBym-I37JqE1MYj2t1UJpXNsEtDagaWjgyIgXuJ5XRhX4mkZ8oDGThrtFVwheQh3g4zBDjyLghNBYDIF-QwbMxfDWf8vF20-yr4Fg1xbJxvRhJJfYkIa5rrsuqKVUY_dFU-r7BWhE4cK1ajIhxPdsc9q1sJ83DUtsPWyvTHyFuaa8ZLmu7T0npHF4TOWjBqvTo7z6N2JzYKyNtiIdtQhWs4S4J4sF5DMGLgwUel8FN5Nd5AWkfETzof8pHJUJa9rQ_O3idU17ClJMiKS2sxE656Wi4VL-J0HADVELJxuOMXRyQCb4VUjqcHnJB-OZagdwB-AUb_9uJni1gEbBgDAJGVIaZbiAxUMf0j63_CI-Z2B91uyndBWkhewliPTmxbPd6inerS3amGKV2AijW6R5-Ijc-iBNrqAvu4lqcIlGO3TpG82WPV9Q07CC8Lr2VfLDty9a0Rei0LmBTZAHPaPS3_v8xT7vfb2l1rb4_LfzSh89QS9SCeRbmB4pBt1krEeTK1qguTAvTunHn-ypAWFUMfP2L2cXd6WgVHBtCY7CNbSX5a2r5QrmalCPoeMn1nD_QOEtKT08-hHxMiewnJzwVihuev3Dn7hsG8RT031UOWuBrSc2VWuyf_tVVM1vJliW8EV0zGRxPw0QuKDy9aC7cLQrmaF3OveT-gkFaH4M7mknF95QTnptx3HaWgMWsO6UcewAVcQ4sDOucUuIkuume4PMlfiYBrFyknrE4wJTww0U0xVkuoYl7Oydjqi32dF9OeHp8x1pjztUj8LBM8KkjZ-v0-FPIAiiKoXVFEmXgmC9WRz0SLknmXYh9DPv6lz_JCL4vwGLN2GqlcLLnw627PuBmLYEq4qDGF-VfVR3OiHchV9h-G29eTf8j6eI0wGbhm4znztNvzHLE5ZAIcssDmoJN2tTdbRPAHK7u09Wi9y5lzu6xKX3PPho5-Lvf0-4bbKOwdTY4F2ryX2VXf79kW09yUYwlmeYeb3_pFmWU1E9QNnUxwtqB69l3B411RaxlVVgTd_fByJ5Ys2WOVpUdRTHGv6UqQrGA85zpwTkV85qQiA0x3Vw5QbSbrd8gunTvaFEnZD7DsTcP5dqJ12AGv4OZVD3nvhz_tF2jhuohMZ0dHVyJ5GCWTQTTD_l8gAROZGeNEdVuG8veJlKrAgk3lIl4LZDUKUVIHX-aSuu1BVufVsqXc7spDlP8KE-oNSoX1-__zczGjnyYj2dCtY6QArgNYoO1GTi4RFGOkVDlvm8ROKozcN3S9AjPgGJqQQ2z8htEeXAOpnOtXeo1-EAbKSQnzy32aBwNbCdaL89o8qRothqECNvnN-Xa87MQm4WMlkto6R9EiAyzHEBQUSLiJXq4SegEvCCPI0nOX1OPVYDsNupjOe9cN4EaZCZNS88wLsWggQI5d6r3Oour88RxdR2U_L7z2S96hwU2aS3rIt9z8XtQOI0D6ayyP67j1iz1qpryTjCbZO4mNZQ2m5I_KiNmM8lA52ARp4PlI-3iJjOq6Rx74VtnXuDaodQ5UsWl61fba6Ujdp_R3UQ4bM417_f0idjI7gTZUdqi2j1tEuHH2xbwJcefymzOOtMzyi88rPZx6ZtnS2gmI7GY3vMeCwG-3aTES9bLmI_2mWC5ks-IvHsutVc3mQV90y3u4QFDO-XfjkVORzH-XjibQsc-B3gbWG4JC6e9B2YGWxv-irBhH3u61URvkTv3SsfoPYe-GXN82xXYt1', + }, + }, +}; diff --git a/test/fixtures/wpt/WebCryptoAPI/import_export/ML-KEM_importKey.js b/test/fixtures/wpt/WebCryptoAPI/import_export/ML-KEM_importKey.js new file mode 100644 index 00000000000000..c264a163148438 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/import_export/ML-KEM_importKey.js @@ -0,0 +1,222 @@ +var subtle = crypto.subtle; + +function runTests(algorithmName) { + var algorithm = { name: algorithmName }; + var data = keyData[algorithmName]; + // var jwkData = {jwk: {kty: data.jwk.kty, alg: data.jwk.alg, pub: data.jwk.pub}}; + + // TODO: add JWK when its definition is done in IETF JOSE WG + + [true, false].forEach(function (extractable) { + // Test public keys first + allValidUsages(data.publicUsages, true).forEach(function (usages) { + ['spki', /*'jwk',*/ 'raw-public'].forEach(function (format) { + if (format === 'jwk') { + // Not all fields used for public keys + testFormat( + format, + algorithm, + jwkData, + algorithmName, + usages, + extractable + ); + } else { + testFormat( + format, + algorithm, + data, + algorithmName, + usages, + extractable + ); + } + }); + }); + + // Next, test private keys + allValidUsages(data.privateUsages).forEach(function (usages) { + ['pkcs8', /*'jwk',*/ 'raw-seed'].forEach(function (format) { + testFormat(format, algorithm, data, algorithmName, usages, extractable); + }); + }); + }); +} + +// Test importKey with a given key format and other parameters. If +// extrable is true, export the key and verify that it matches the input. +function testFormat(format, algorithm, keyData, keySize, usages, extractable) { + [algorithm, algorithm.name].forEach((alg) => { + promise_test(function (test) { + return subtle + .importKey(format, keyData[format], alg, extractable, usages) + .then( + function (key) { + assert_equals( + key.constructor, + CryptoKey, + 'Imported a CryptoKey object' + ); + assert_goodCryptoKey( + key, + algorithm, + extractable, + usages, + format === 'pkcs8' || + format === 'raw-seed' || + (format === 'jwk' && keyData[format].priv) + ? 'private' + : 'public' + ); + if (!extractable) { + return; + } + + return subtle.exportKey(format, key).then( + function (result) { + if (format !== 'jwk') { + assert_true( + equalBuffers(keyData[format], result), + 'Round trip works' + ); + } else { + assert_true( + equalJwk(keyData[format], result), + 'Round trip works' + ); + } + }, + function (err) { + assert_unreached( + 'Threw an unexpected error: ' + err.toString() + ); + } + ); + }, + function (err) { + assert_unreached('Threw an unexpected error: ' + err.toString()); + } + ); + }, 'Good parameters: ' + + keySize.toString() + + ' bits ' + + parameterString(format, keyData[format], alg, extractable, usages)); + }); +} + +// Helper methods follow: + +// Are two array buffers the same? +function equalBuffers(a, b) { + if (a.byteLength !== b.byteLength) { + return false; + } + + var aBytes = new Uint8Array(a); + var bBytes = new Uint8Array(b); + + for (var i = 0; i < a.byteLength; i++) { + if (aBytes[i] !== bBytes[i]) { + return false; + } + } + + return true; +} + +// Are two Jwk objects "the same"? That is, does the object returned include +// matching values for each property that was expected? It's okay if the +// returned object has extra methods; they aren't checked. +function equalJwk(expected, got) { + var fields = Object.keys(expected); + var fieldName; + + for (var i = 0; i < fields.length; i++) { + fieldName = fields[i]; + if (!(fieldName in got)) { + return false; + } + if (expected[fieldName] !== got[fieldName]) { + return false; + } + } + + return true; +} + +// Convert method parameters to a string to uniquely name each test +function parameterString(format, data, algorithm, extractable, usages) { + if ('byteLength' in data) { + data = 'buffer(' + data.byteLength.toString() + ')'; + } else { + data = 'object(' + Object.keys(data).join(', ') + ')'; + } + var result = + '(' + + objectToString(format) + + ', ' + + objectToString(data) + + ', ' + + objectToString(algorithm) + + ', ' + + objectToString(extractable) + + ', ' + + objectToString(usages) + + ')'; + + return result; +} + +// Character representation of any object we may use as a parameter. +function objectToString(obj) { + var keyValuePairs = []; + + if (Array.isArray(obj)) { + return ( + '[' + + obj + .map(function (elem) { + return objectToString(elem); + }) + .join(', ') + + ']' + ); + } else if (typeof obj === 'object') { + Object.keys(obj) + .sort() + .forEach(function (keyName) { + keyValuePairs.push(keyName + ': ' + objectToString(obj[keyName])); + }); + return '{' + keyValuePairs.join(', ') + '}'; + } else if (typeof obj === 'undefined') { + return 'undefined'; + } else { + return obj.toString(); + } + + var keyValuePairs = []; + + Object.keys(obj) + .sort() + .forEach(function (keyName) { + var value = obj[keyName]; + if (typeof value === 'object') { + value = objectToString(value); + } else if (typeof value === 'array') { + value = + '[' + + value + .map(function (elem) { + return objectToString(elem); + }) + .join(', ') + + ']'; + } else { + value = value.toString(); + } + + keyValuePairs.push(keyName + ': ' + value); + }); + + return '{' + keyValuePairs.join(', ') + '}'; +} diff --git a/test/fixtures/wpt/WebCryptoAPI/import_export/ML-KEM_importKey.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/import_export/ML-KEM_importKey.tentative.https.any.js new file mode 100644 index 00000000000000..8b459c17e2d329 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/import_export/ML-KEM_importKey.tentative.https.any.js @@ -0,0 +1,9 @@ +// META: title=WebCryptoAPI: importKey() for ML-KEM keys +// META: timeout=long +// META: script=../util/helpers.js +// META: script=ML-KEM_importKey_fixtures.js +// META: script=ML-KEM_importKey.js + +runTests("ML-KEM-512"); +runTests("ML-KEM-768"); +runTests("ML-KEM-1024"); diff --git a/test/fixtures/wpt/WebCryptoAPI/import_export/ML-KEM_importKey_fixtures.js b/test/fixtures/wpt/WebCryptoAPI/import_export/ML-KEM_importKey_fixtures.js new file mode 100644 index 00000000000000..1c25d37614e92e --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/import_export/ML-KEM_importKey_fixtures.js @@ -0,0 +1,76 @@ +var keyData = { + 'ML-KEM-512': { + privateUsages: ['decapsulateBits', 'decapsulateKey'], + publicUsages: ['encapsulateBits', 'encapsulateKey'], + pkcs8: new Uint8Array([ + 48, 84, 2, 1, 0, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 4, 1, 4, 66, + 128, 64, 165, 38, 193, 164, 132, 122, 104, 173, 83, 214, 227, 31, 231, + 183, 152, 228, 96, 140, 65, 23, 83, 131, 8, 205, 245, 192, 122, 226, 244, + 94, 134, 109, 118, 60, 173, 203, 25, 75, 189, 144, 22, 37, 163, 53, 78, + 149, 185, 80, 130, 235, 161, 49, 141, 160, 11, 40, 152, 18, 142, 30, 56, + 252, 129, 211, + ]), + spki: hexStringToUint8Array( + '30820332300b06096086480165030404010382032100366811c162b905bc1bf854094672bf9030954e19881fbc1d60c45469a51a20542864940ae5b261d3312dc85a416e8aad7192c6eed89b779c094293439e792f9876630b741997688e2e89479e340f7bb16e38f18ffc4a9217493388067b70743650f80955c56141662caa176302412c4eacab52f3a572518c8f148e74d1747bda95c566518ef1734ee76599f28674fb0ef609a729162c1ea6c39b899d5493a5461a5e648514c0f445dcaac8501ba5e42a543d5b9474faccd4e95ad7921260953f9832341022a91255ad88099170e5b1a2219dded196c0fca8ac6aa624269bb8423b65aaa3210a328179566a7bc8c44548ef97766aba1ae1933576030902258cfcf71eb7b10489e69f03ba5d3f5110eaeb49b3da180d7b2780165a3978aa73f8679b72b329051922488f03d050831379dd1306e75642d87547c280bb89a550b038b8bbd8854590a995758f65740c712a47fec072e1c1150e05be019c1e0e9216f6b2024fdc4e1f0c309af5ad34c997983674faf34dd7890719d04e3f8374f98223d67c1d930207b2429f02794355cac0d11c7e1058b1c5c4225c3abec5e05cfa063a51d47a2c341e89fa7b051c2a4e272a0583827581c9a48376a7078aef4a6e337232fe41c83e121acc206726f38a977625611b0f47c054d765b72c94b890e51fbd788da882aba97c45bfb07151150b21fbcdee6c8406b73d3a98af53f21f88e3b2fb98c0f114712c6b169e9a6a41d20d16eaaf62d127df5a1b9360959c4480ee19ce111b8cec439d53e33c32c374412966649c4037755abc5065eae3aaf05249bdfc9d52f116737bcfae707683f2a65eec2da6b39b7653bdff5256a765277a7169382943ed09cc2ad6a206658e199655e9d9885abb58f7f459d351a7fcb391bfc2685908406f6b4cad156d17d335263c748c83b98e54b1f4c815cd8b5ed7c60231308f63e27966ea3743aa3e2dd2c89e752ae9c56e81d40c8e127ff12b979ac0582075cdf4530ab6d588e9829c2d56231ecb6c5e210fd243b1e1f77891968a1fe4b7bc2225f420390625178f12b5d3ca2812963d953c47ff21824119c492f7b41f05b01dfbda8292ac0c35b3448878c401d1b18f7fc5c3cef899576d467afc70' + ), + 'raw-public': hexStringToUint8Array( + '366811c162b905bc1bf854094672bf9030954e19881fbc1d60c45469a51a20542864940ae5b261d3312dc85a416e8aad7192c6eed89b779c094293439e792f9876630b741997688e2e89479e340f7bb16e38f18ffc4a9217493388067b70743650f80955c56141662caa176302412c4eacab52f3a572518c8f148e74d1747bda95c566518ef1734ee76599f28674fb0ef609a729162c1ea6c39b899d5493a5461a5e648514c0f445dcaac8501ba5e42a543d5b9474faccd4e95ad7921260953f9832341022a91255ad88099170e5b1a2219dded196c0fca8ac6aa624269bb8423b65aaa3210a328179566a7bc8c44548ef97766aba1ae1933576030902258cfcf71eb7b10489e69f03ba5d3f5110eaeb49b3da180d7b2780165a3978aa73f8679b72b329051922488f03d050831379dd1306e75642d87547c280bb89a550b038b8bbd8854590a995758f65740c712a47fec072e1c1150e05be019c1e0e9216f6b2024fdc4e1f0c309af5ad34c997983674faf34dd7890719d04e3f8374f98223d67c1d930207b2429f02794355cac0d11c7e1058b1c5c4225c3abec5e05cfa063a51d47a2c341e89fa7b051c2a4e272a0583827581c9a48376a7078aef4a6e337232fe41c83e121acc206726f38a977625611b0f47c054d765b72c94b890e51fbd788da882aba97c45bfb07151150b21fbcdee6c8406b73d3a98af53f21f88e3b2fb98c0f114712c6b169e9a6a41d20d16eaaf62d127df5a1b9360959c4480ee19ce111b8cec439d53e33c32c374412966649c4037755abc5065eae3aaf05249bdfc9d52f116737bcfae707683f2a65eec2da6b39b7653bdff5256a765277a7169382943ed09cc2ad6a206658e199655e9d9885abb58f7f459d351a7fcb391bfc2685908406f6b4cad156d17d335263c748c83b98e54b1f4c815cd8b5ed7c60231308f63e27966ea3743aa3e2dd2c89e752ae9c56e81d40c8e127ff12b979ac0582075cdf4530ab6d588e9829c2d56231ecb6c5e210fd243b1e1f77891968a1fe4b7bc2225f420390625178f12b5d3ca2812963d953c47ff21824119c492f7b41f05b01dfbda8292ac0c35b3448878c401d1b18f7fc5c3cef899576d467afc70' + ), + 'raw-seed': new Uint8Array([ + 165, 38, 193, 164, 132, 122, 104, 173, 83, 214, 227, 31, 231, 183, 152, + 228, 96, 140, 65, 23, 83, 131, 8, 205, 245, 192, 122, 226, 244, 94, 134, + 109, 118, 60, 173, 203, 25, 75, 189, 144, 22, 37, 163, 53, 78, 149, 185, + 80, 130, 235, 161, 49, 141, 160, 11, 40, 152, 18, 142, 30, 56, 252, 129, + 211, + ]), + }, + 'ML-KEM-768': { + privateUsages: ['decapsulateBits', 'decapsulateKey'], + publicUsages: ['encapsulateBits', 'encapsulateKey'], + pkcs8: new Uint8Array([ + 48, 84, 2, 1, 0, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 4, 2, 4, 66, + 128, 64, 166, 200, 29, 100, 198, 48, 80, 164, 143, 215, 2, 108, 106, 162, + 231, 107, 111, 143, 2, 14, 183, 253, 156, 17, 91, 213, 75, 200, 112, 89, + 243, 55, 201, 9, 240, 170, 192, 86, 52, 228, 122, 16, 73, 139, 30, 11, + 224, 117, 143, 2, 124, 21, 63, 91, 210, 94, 160, 123, 99, 189, 172, 61, + 235, 191, + ]), + spki: hexStringToUint8Array( + '308204b2300b0609608648016503040402038204a100ee58686b11929e95343ba76f9dd020aca8820cbc251de30147865ab43c39958c2d3c220423d09b99faa35fb91301ca09b042a1fa88adcab1114557a0b40992842645773186563461dd8879f782a12997c63d8c949d3abc78111319f9741a576ef01062996bb310686086838760f6b4ca011f51066153ca99f2703a4db8ae35274f27cc5d7f1b608848827b767d4aa845dda7ab268cae736b8029b18f69fac277bac3b22b7314f2354d561a2960b539b972295bbc3e15ad11dc7c55845fb5a5090707ca12741236f58b6535446d3aa02503701cb990c8c4a4b678cd2839ab1760be4e42853ab7a70b840010642f72b02e89da5cb8f365f0554c0ca52c2116396a242f12c751c4971664627a854573cec795ae004cd0d16b2039297b95a06be85266081b00222f5b3212260364ce7a7ba09337e85c5e55b9070d74cd68b43e3c747ba53c2ba735029a279c7b0199e59204ea8a0f68c0bce2f77196a07e58a415da0b3fb7598edb436765c0b2a8f90634db6e78e90666524e46f85805ba8485d29db4b1786fea28f8206b1e000a44655a006a0512579208916eb02b17fda8c129092f3527495c3242f364065db9ca2f5b0af502cecd3615ff181958c5b7b5115830c592cf9c34d348abb450cd72625c51b927d011a0faf77371e638e9e39e837244dab87ef5f54bce164caba506f18ca10593289c4c7e25a9729e29c2bab6169356845627349fb710d4c30fbe72722a8957b9b58d2851a207b2b51f6986e5369f46b26f0909577d2a2771a2c7afd486af6510bf2bc634c4c661c148c670a9de5c94e366b5e7bc773b020d0dc037f4e2c3d2127b26175e54691e210a7d551b75bda3941043c5557b9720fb41a8cbbef6039f2f784d8766a2c4c08fe954ba832a587d834d09367d3bba49f35b057c426fe3ec91e73059d08622e2c69e7a85094209a8841726f486940e858095585bc4aa15d52436da3b96bd76ace5f960cb3561f8657b6e95681fe49ac2a940127c44faf5965572cc45762e87f081cb162f14f54261e4b81ae285f64a53eeb590ea033e4fe815e734bad8443baabc592fb0ce8e4a979ea79a0fba4cc5644ab78405758ba99cd81f235c2df0cc639ff0b328e3811d921d2a8a29a5223604ea66bf2bb5cdc0c95f5b276c135c2d5b4c75b05825739fd515c811758200e29fd633462d1c8e6b38656cea66b41c51b2a3b9f8babda1da6d9943b716d436dd5a90d278451de14ef32329380a761f7c22761a4541b29b60a2abb5f8c62ff917c31aa58789359c09825f3bca7bbc33972a30d4d804c7f7ba31191cfcf22c7a4832b64021b0f498734b7f02e132e71caa37f9bf24c6cb242c1a155b683d5a0a3cd47316d33562b352aed00e83430b3276b978937d0a8b4f874332c30c7329fcaf16712bf8528cafd520384c6aad9598d6015e0e8b794bdac9844acbad958023c727dad52e386320d4ba33a8ec4920ec87b001112785bb8c9439756a2c6f376c89279701ab97e1f07f5566c0c66c4d86b793d662401793b0c7538b24661316c98aa922381ec1af955a7041c0a587c6480665a22f052cb4e3b8d3504606c87695bc96526446402812ca680c3fa22e43b8409d6029ec2c8ef7655635f5cc577ca77afa6ae1af0ccc3b205e7162b0c5b1ffbc35bec7674af35fa3c1' + ), + 'raw-public': hexStringToUint8Array( + 'ee58686b11929e95343ba76f9dd020aca8820cbc251de30147865ab43c39958c2d3c220423d09b99faa35fb91301ca09b042a1fa88adcab1114557a0b40992842645773186563461dd8879f782a12997c63d8c949d3abc78111319f9741a576ef01062996bb310686086838760f6b4ca011f51066153ca99f2703a4db8ae35274f27cc5d7f1b608848827b767d4aa845dda7ab268cae736b8029b18f69fac277bac3b22b7314f2354d561a2960b539b972295bbc3e15ad11dc7c55845fb5a5090707ca12741236f58b6535446d3aa02503701cb990c8c4a4b678cd2839ab1760be4e42853ab7a70b840010642f72b02e89da5cb8f365f0554c0ca52c2116396a242f12c751c4971664627a854573cec795ae004cd0d16b2039297b95a06be85266081b00222f5b3212260364ce7a7ba09337e85c5e55b9070d74cd68b43e3c747ba53c2ba735029a279c7b0199e59204ea8a0f68c0bce2f77196a07e58a415da0b3fb7598edb436765c0b2a8f90634db6e78e90666524e46f85805ba8485d29db4b1786fea28f8206b1e000a44655a006a0512579208916eb02b17fda8c129092f3527495c3242f364065db9ca2f5b0af502cecd3615ff181958c5b7b5115830c592cf9c34d348abb450cd72625c51b927d011a0faf77371e638e9e39e837244dab87ef5f54bce164caba506f18ca10593289c4c7e25a9729e29c2bab6169356845627349fb710d4c30fbe72722a8957b9b58d2851a207b2b51f6986e5369f46b26f0909577d2a2771a2c7afd486af6510bf2bc634c4c661c148c670a9de5c94e366b5e7bc773b020d0dc037f4e2c3d2127b26175e54691e210a7d551b75bda3941043c5557b9720fb41a8cbbef6039f2f784d8766a2c4c08fe954ba832a587d834d09367d3bba49f35b057c426fe3ec91e73059d08622e2c69e7a85094209a8841726f486940e858095585bc4aa15d52436da3b96bd76ace5f960cb3561f8657b6e95681fe49ac2a940127c44faf5965572cc45762e87f081cb162f14f54261e4b81ae285f64a53eeb590ea033e4fe815e734bad8443baabc592fb0ce8e4a979ea79a0fba4cc5644ab78405758ba99cd81f235c2df0cc639ff0b328e3811d921d2a8a29a5223604ea66bf2bb5cdc0c95f5b276c135c2d5b4c75b05825739fd515c811758200e29fd633462d1c8e6b38656cea66b41c51b2a3b9f8babda1da6d9943b716d436dd5a90d278451de14ef32329380a761f7c22761a4541b29b60a2abb5f8c62ff917c31aa58789359c09825f3bca7bbc33972a30d4d804c7f7ba31191cfcf22c7a4832b64021b0f498734b7f02e132e71caa37f9bf24c6cb242c1a155b683d5a0a3cd47316d33562b352aed00e83430b3276b978937d0a8b4f874332c30c7329fcaf16712bf8528cafd520384c6aad9598d6015e0e8b794bdac9844acbad958023c727dad52e386320d4ba33a8ec4920ec87b001112785bb8c9439756a2c6f376c89279701ab97e1f07f5566c0c66c4d86b793d662401793b0c7538b24661316c98aa922381ec1af955a7041c0a587c6480665a22f052cb4e3b8d3504606c87695bc96526446402812ca680c3fa22e43b8409d6029ec2c8ef7655635f5cc577ca77afa6ae1af0ccc3b205e7162b0c5b1ffbc35bec7674af35fa3c1' + ), + 'raw-seed': new Uint8Array([ + 166, 200, 29, 100, 198, 48, 80, 164, 143, 215, 2, 108, 106, 162, 231, 107, + 111, 143, 2, 14, 183, 253, 156, 17, 91, 213, 75, 200, 112, 89, 243, 55, + 201, 9, 240, 170, 192, 86, 52, 228, 122, 16, 73, 139, 30, 11, 224, 117, + 143, 2, 124, 21, 63, 91, 210, 94, 160, 123, 99, 189, 172, 61, 235, 191, + ]), + }, + 'ML-KEM-1024': { + privateUsages: ['decapsulateBits', 'decapsulateKey'], + publicUsages: ['encapsulateBits', 'encapsulateKey'], + pkcs8: new Uint8Array([ + 48, 84, 2, 1, 0, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 4, 3, 4, 66, + 128, 64, 152, 117, 178, 230, 181, 134, 244, 129, 167, 125, 166, 8, 181, + 95, 206, 210, 136, 112, 219, 125, 6, 118, 122, 83, 38, 244, 57, 205, 50, + 98, 59, 46, 232, 66, 17, 145, 204, 252, 162, 185, 116, 116, 242, 28, 132, + 193, 251, 65, 39, 3, 101, 145, 174, 21, 195, 144, 234, 14, 158, 32, 49, + 57, 142, 113, + ]), + spki: hexStringToUint8Array( + '30820632300b060960864801650304040303820621002147b823662edff231d7365816146b4da0579bd288f2c65b75f6c15edb24f325796416b41d88a9d2a1c3ad21278845430e7803bfd36189b83e38a744805cb63446956b859b1d0c6c56b50ed75b15e4b6771f85b0ec2346ff761efb887ebd1c3407c7982522c51a8ba1311b3c438ab4661569d7023c7c83a833e717c72a5fe8ac3f84b643d930a403774df21c64fed0b9a39699f1b170ed4c8526182399c12fcda615e95ab3a2476874fb72d6358e9a0b915e6c9d7ef135463507a1d505388852cf0b87dc18189559365dca7720fcb28e748d2c1c0b2848382e500d094bc434f63a109360a7eb6813dc2a93d6a8ff4b791cfa5aa83014d1fac17bd321007baf1f70c75a5ba4c52472eeb9aa0b6b6b6bd5c26d3c69f7f411ac212cf006bde7a7c59a337fcff100184752ed0a88c5f8b8d7810214059c4e91a60b8cbe5474940b75141a3256d5e347ccb3ab93a834760a8d17017687d879e8d29d7624374b62544939806a2423e452a6b30356eb521edb8628e2a7103862a0f62a0a18f98fc990c9e57c2072187abecaaeefe70e59989177cc408ef0ab7faa220d7123b3b8bc7da119a89024566a9b7eacb2e025b96acb487df6589c1c6c724baa1f2964e95cab13c19a95ab09eb9698d9fb747de99c349879c524c1b264c726dca3da153515cc8d9dd82b2db769710a1b5dd9b25f48b79ec37a1d7c0abff88057a07a8c269325580b20dc2bd0f5bd5c768a2d7292c3d420986738eeacc28e288405956bcf12b3d28843ce57060af45aa600c66a48359c15b9e1e45bb898bb911ca791201a2b614a92e27ad04c70e4f806a41451ac5188fca55b28cc3b1a4bce3fa737174a1b1f48ae9354ceb229bdd8a2488b1ace2b6284082acc383180b433959714318431b9ed4180a7629e188c338649c73023b4f35515e08cbd74f72d7d5b3a0e55308c788c6fd73975e257eefc12547c57a9250be7637e40da41317117dd396c1da7c67b085242193749f44d5712c0aaaa56c7247100a30a2ac0441438b52ec406950745fd1c23b4d1cc04ec0911e4b2de548088b9889cb550f7ec54617599266c98f230b0538394ad2837bf481ed1c02d825037530017e435388b600e4fc60f92e4770ec78cb22ac510439cda923bb42a72e18c5d472a98f575913584c2236500b4074829a6ac95130486766923c55806a51e84d0af90f218f06c6e03fa375e5a290fc83c80196aaaaab1a9835dad054b8968c26726a35ce0702fcb9688c3924167261f3b719512774e3a83652625676459cc1586cbb3b56d7b123c072eeb813258f15881610703019400ea1d97917de5a71d9340b5a201376814b3f921aa59d742654504d58959f1eb6bf83b7cffdcb82146a2c6ac4365c65c53466268304d88a416908977c88bca17763051d8177b2060de39140c3c93136bcb158b731fe565e9a3813494c768a112114172a38156eaa9305396cdb9725e77aca088b6444ba30a5c6907673c6dd3137ffb519631cc1ae51c5fabb57a29287ae2c592984c97b5706785eb1f52e3177cc15714dcc26a7b8884875a6e4bbab8fbad3523ae4605bee5a6a37d557f05bb60c7d7a26e96477d8c38d9ea9c25476db19118811524cd5818c6d167e96ca142a8437971abcb895426b3065169a6af9c86bdb5bcbb51854bb2c84e338362f9acd642ad46911d342209202c25c90c219ff795b1873e396306ef588d7aa10b4e0463d68956809a577a714c7b42bc72dc8c9d2358e8b40e77eb53b54c7c7109ca9b10394e1b6b858b52f094b488399451c8a47fc689c7166cee187d1d0a7d8edb48e0fb01a3c74a74c4472502c45b5718f27186db50b59d1cca29e7adf21340daf6b74fec739db77390427514d69ed5f31685950ed694401947c1fc044f9c078d451167f9798b0b0b4ab51cbf1aba47b2686555976f8a8255646a01f49bac41a9a8ecf85c8949936e9c7af6b739e6717b10a8cec8715a1f73b91829ae9522c92b47caa531b677429694a0cad7720ae0f32f56977491e82ff954b21776aced0c04b9542b74924e1d98b931932c178bc84b080675c3792417457425c0be098eaa5a51d0b8ba1c25280f4197b3b28f6700800cb9359729c00ababf1e875e5da745be93915b4a24d3b505e7c4b06fe49b75ab4ed9d4237f0581d1d0b66bd248363492e9619fac82ab3ab8aa3fee708d529da39c35e3dddf42da77697a8e122a' + ), + 'raw-public': hexStringToUint8Array( + '2147b823662edff231d7365816146b4da0579bd288f2c65b75f6c15edb24f325796416b41d88a9d2a1c3ad21278845430e7803bfd36189b83e38a744805cb63446956b859b1d0c6c56b50ed75b15e4b6771f85b0ec2346ff761efb887ebd1c3407c7982522c51a8ba1311b3c438ab4661569d7023c7c83a833e717c72a5fe8ac3f84b643d930a403774df21c64fed0b9a39699f1b170ed4c8526182399c12fcda615e95ab3a2476874fb72d6358e9a0b915e6c9d7ef135463507a1d505388852cf0b87dc18189559365dca7720fcb28e748d2c1c0b2848382e500d094bc434f63a109360a7eb6813dc2a93d6a8ff4b791cfa5aa83014d1fac17bd321007baf1f70c75a5ba4c52472eeb9aa0b6b6b6bd5c26d3c69f7f411ac212cf006bde7a7c59a337fcff100184752ed0a88c5f8b8d7810214059c4e91a60b8cbe5474940b75141a3256d5e347ccb3ab93a834760a8d17017687d879e8d29d7624374b62544939806a2423e452a6b30356eb521edb8628e2a7103862a0f62a0a18f98fc990c9e57c2072187abecaaeefe70e59989177cc408ef0ab7faa220d7123b3b8bc7da119a89024566a9b7eacb2e025b96acb487df6589c1c6c724baa1f2964e95cab13c19a95ab09eb9698d9fb747de99c349879c524c1b264c726dca3da153515cc8d9dd82b2db769710a1b5dd9b25f48b79ec37a1d7c0abff88057a07a8c269325580b20dc2bd0f5bd5c768a2d7292c3d420986738eeacc28e288405956bcf12b3d28843ce57060af45aa600c66a48359c15b9e1e45bb898bb911ca791201a2b614a92e27ad04c70e4f806a41451ac5188fca55b28cc3b1a4bce3fa737174a1b1f48ae9354ceb229bdd8a2488b1ace2b6284082acc383180b433959714318431b9ed4180a7629e188c338649c73023b4f35515e08cbd74f72d7d5b3a0e55308c788c6fd73975e257eefc12547c57a9250be7637e40da41317117dd396c1da7c67b085242193749f44d5712c0aaaa56c7247100a30a2ac0441438b52ec406950745fd1c23b4d1cc04ec0911e4b2de548088b9889cb550f7ec54617599266c98f230b0538394ad2837bf481ed1c02d825037530017e435388b600e4fc60f92e4770ec78cb22ac510439cda923bb42a72e18c5d472a98f575913584c2236500b4074829a6ac95130486766923c55806a51e84d0af90f218f06c6e03fa375e5a290fc83c80196aaaaab1a9835dad054b8968c26726a35ce0702fcb9688c3924167261f3b719512774e3a83652625676459cc1586cbb3b56d7b123c072eeb813258f15881610703019400ea1d97917de5a71d9340b5a201376814b3f921aa59d742654504d58959f1eb6bf83b7cffdcb82146a2c6ac4365c65c53466268304d88a416908977c88bca17763051d8177b2060de39140c3c93136bcb158b731fe565e9a3813494c768a112114172a38156eaa9305396cdb9725e77aca088b6444ba30a5c6907673c6dd3137ffb519631cc1ae51c5fabb57a29287ae2c592984c97b5706785eb1f52e3177cc15714dcc26a7b8884875a6e4bbab8fbad3523ae4605bee5a6a37d557f05bb60c7d7a26e96477d8c38d9ea9c25476db19118811524cd5818c6d167e96ca142a8437971abcb895426b3065169a6af9c86bdb5bcbb51854bb2c84e338362f9acd642ad46911d342209202c25c90c219ff795b1873e396306ef588d7aa10b4e0463d68956809a577a714c7b42bc72dc8c9d2358e8b40e77eb53b54c7c7109ca9b10394e1b6b858b52f094b488399451c8a47fc689c7166cee187d1d0a7d8edb48e0fb01a3c74a74c4472502c45b5718f27186db50b59d1cca29e7adf21340daf6b74fec739db77390427514d69ed5f31685950ed694401947c1fc044f9c078d451167f9798b0b0b4ab51cbf1aba47b2686555976f8a8255646a01f49bac41a9a8ecf85c8949936e9c7af6b739e6717b10a8cec8715a1f73b91829ae9522c92b47caa531b677429694a0cad7720ae0f32f56977491e82ff954b21776aced0c04b9542b74924e1d98b931932c178bc84b080675c3792417457425c0be098eaa5a51d0b8ba1c25280f4197b3b28f6700800cb9359729c00ababf1e875e5da745be93915b4a24d3b505e7c4b06fe49b75ab4ed9d4237f0581d1d0b66bd248363492e9619fac82ab3ab8aa3fee708d529da39c35e3dddf42da77697a8e122a' + ), + 'raw-seed': new Uint8Array([ + 152, 117, 178, 230, 181, 134, 244, 129, 167, 125, 166, 8, 181, 95, 206, + 210, 136, 112, 219, 125, 6, 118, 122, 83, 38, 244, 57, 205, 50, 98, 59, + 46, 232, 66, 17, 145, 204, 252, 162, 185, 116, 116, 242, 28, 132, 193, + 251, 65, 39, 3, 101, 145, 174, 21, 195, 144, 234, 14, 158, 32, 49, 57, + 142, 113, + ]), + }, +}; diff --git a/test/fixtures/wpt/WebCryptoAPI/import_export/importKey_failures.js b/test/fixtures/wpt/WebCryptoAPI/import_export/importKey_failures.js index 47d12f14500dff..f45da96cf6b01c 100644 --- a/test/fixtures/wpt/WebCryptoAPI/import_export/importKey_failures.js +++ b/test/fixtures/wpt/WebCryptoAPI/import_export/importKey_failures.js @@ -19,6 +19,12 @@ function run_test(algorithmNames) { var allTestVectors = [ // Parameters that should work for importKey / exportKey {name: "Ed25519", privateUsages: ["sign"], publicUsages: ["verify"]}, + {name: "ML-DSA-44", privateUsages: ["sign"], publicUsages: ["verify"]}, + {name: "ML-DSA-65", privateUsages: ["sign"], publicUsages: ["verify"]}, + {name: "ML-DSA-87", privateUsages: ["sign"], publicUsages: ["verify"]}, + {name: "ML-KEM-512", privateUsages: ["decapsulateKey", "decapsulateBits"], publicUsages: ["encapsulateKey", "encapsulateBits"]}, + {name: "ML-KEM-768", privateUsages: ["decapsulateKey", "decapsulateBits"], publicUsages: ["encapsulateKey", "encapsulateBits"]}, + {name: "ML-KEM-1024", privateUsages: ["decapsulateKey", "decapsulateBits"], publicUsages: ["encapsulateKey", "encapsulateBits"]}, {name: "Ed448", privateUsages: ["sign"], publicUsages: ["verify"]}, {name: "ECDSA", privateUsages: ["sign"], publicUsages: ["verify"]}, {name: "X25519", privateUsages: ["deriveKey", "deriveBits"], publicUsages: []}, @@ -43,7 +49,7 @@ function run_test(algorithmNames) { var jwk_label = ""; if (format === "jwk") - jwk_label = data.d === undefined ? " (public) " : "(private)"; + jwk_label = isPublicKey(data) ? " (public) " : "(private)"; var result = "(" + objectToString(format) + jwk_label + ", " + @@ -101,18 +107,22 @@ function run_test(algorithmNames) { } function validUsages(usages, format, data) { - if (format === 'spki' || format === 'raw') return usages.publicUsages - if (format === 'pkcs8') return usages.privateUsages + if (format === 'spki' || format === 'raw' || format === 'raw-public') return usages.publicUsages + if (format === 'pkcs8' || format === 'raw-private' || format === 'raw-seed') return usages.privateUsages if (format === 'jwk') { if (data === undefined) return []; - return data.d === undefined ? usages.publicUsages : usages.privateUsages; + return isPublicKey(data) ? usages.publicUsages : usages.privateUsages; } return []; } + function isPublicKey(data) { + return data.d === undefined && data.priv === undefined; + } + function isPrivateKey(data) { - return data.d !== undefined; + return !isPublicKey(data); } // Now test for properly handling errors diff --git a/test/fixtures/wpt/WebCryptoAPI/import_export/symmetric_importKey.https.any.js b/test/fixtures/wpt/WebCryptoAPI/import_export/symmetric_importKey.https.any.js index 01b3180189db83..a1a4b5e1ea38f2 100644 --- a/test/fixtures/wpt/WebCryptoAPI/import_export/symmetric_importKey.https.any.js +++ b/test/fixtures/wpt/WebCryptoAPI/import_export/symmetric_importKey.https.any.js @@ -1,222 +1,12 @@ // META: title=WebCryptoAPI: importKey() for symmetric keys // META: timeout=long // META: script=../util/helpers.js - -// Test importKey and exportKey for non-PKC algorithms. Only "happy paths" are -// currently tested - those where the operation should succeed. - - var subtle = crypto.subtle; - - // keying material for algorithms that can use any bit string. - var rawKeyData = [ - new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]), - new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24]), - new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]) - ]; - - // combinations of algorithms, usages, parameters, and formats to test - var testVectors = [ - {name: "AES-CTR", legalUsages: ["encrypt", "decrypt"], extractable: [true, false], formats: ["raw", "jwk"]}, - {name: "AES-CBC", legalUsages: ["encrypt", "decrypt"], extractable: [true, false], formats: ["raw", "jwk"]}, - {name: "AES-GCM", legalUsages: ["encrypt", "decrypt"], extractable: [true, false], formats: ["raw", "jwk"]}, - {name: "AES-KW", legalUsages: ["wrapKey", "unwrapKey"], extractable: [true, false], formats: ["raw", "jwk"]}, - {name: "HMAC", hash: "SHA-1", legalUsages: ["sign", "verify"], extractable: [false], formats: ["raw", "jwk"]}, - {name: "HMAC", hash: "SHA-256", legalUsages: ["sign", "verify"], extractable: [false], formats: ["raw", "jwk"]}, - {name: "HMAC", hash: "SHA-384", legalUsages: ["sign", "verify"], extractable: [false], formats: ["raw", "jwk"]}, - {name: "HMAC", hash: "SHA-512", legalUsages: ["sign", "verify"], extractable: [false], formats: ["raw", "jwk"]}, - {name: "HKDF", legalUsages: ["deriveBits", "deriveKey"], extractable: [false], formats: ["raw"]}, - {name: "PBKDF2", legalUsages: ["deriveBits", "deriveKey"], extractable: [false], formats: ["raw"]} - ]; - - - - // TESTS ARE HERE: - // Test every test vector, along with all available key data - testVectors.forEach(function(vector) { - var algorithm = {name: vector.name}; - if ("hash" in vector) { - algorithm.hash = vector.hash; - } - - rawKeyData.forEach(function(keyData) { - // Try each legal value of the extractable parameter - vector.extractable.forEach(function(extractable) { - vector.formats.forEach(function(format) { - var data = keyData; - if (format === "jwk") { - data = jwkData(keyData, algorithm); - } - // Generate all combinations of valid usages for testing - allValidUsages(vector.legalUsages).forEach(function(usages) { - testFormat(format, algorithm, data, keyData.length * 8, usages, extractable); - }); - testEmptyUsages(format, algorithm, data, keyData.length * 8, extractable); - }); - }); - - }); - }); - - function hasLength(algorithm) { - return algorithm.name === 'HMAC' || algorithm.name.startsWith('AES'); - } - - // Test importKey with a given key format and other parameters. If - // extrable is true, export the key and verify that it matches the input. - function testFormat(format, algorithm, keyData, keySize, usages, extractable) { - promise_test(function(test) { - return subtle.importKey(format, keyData, algorithm, extractable, usages). - then(function(key) { - assert_equals(key.constructor, CryptoKey, "Imported a CryptoKey object"); - assert_goodCryptoKey(key, hasLength(key.algorithm) ? { length: keySize, ...algorithm } : algorithm, extractable, usages, 'secret'); - if (!extractable) { - return; - } - - return subtle.exportKey(format, key). - then(function(result) { - if (format !== "jwk") { - assert_true(equalBuffers(keyData, result), "Round trip works"); - } else { - assert_true(equalJwk(keyData, result), "Round trip works"); - } - }, function(err) { - assert_unreached("Threw an unexpected error: " + err.toString()); - }); - }, function(err) { - assert_unreached("Threw an unexpected error: " + err.toString()); - }); - }, "Good parameters: " + keySize.toString() + " bits " + parameterString(format, keyData, algorithm, extractable, usages)); - } - - // Test importKey with a given key format and other parameters but with empty usages. - // Should fail with SyntaxError - function testEmptyUsages(format, algorithm, keyData, keySize, extractable) { - const usages = []; - promise_test(function(test) { - return subtle.importKey(format, keyData, algorithm, extractable, usages). - then(function(key) { - assert_unreached("importKey succeeded but should have failed with SyntaxError"); - }, function(err) { - assert_equals(err.name, "SyntaxError", "Should throw correct error, not " + err.name + ": " + err.message); - }); - }, "Empty Usages: " + keySize.toString() + " bits " + parameterString(format, keyData, algorithm, extractable, usages)); - } - - - - // Helper methods follow: - - // Are two array buffers the same? - function equalBuffers(a, b) { - if (a.byteLength !== b.byteLength) { - return false; - } - - var aBytes = new Uint8Array(a); - var bBytes = new Uint8Array(b); - - for (var i=0; i name === algorithmName).forEach(function(vector) { + var algorithm = {name: vector.name}; + if ("hash" in vector) { + algorithm.hash = vector.hash; + } + + rawKeyData.forEach(function(keyData) { + if (vector.name === 'ChaCha20-Poly1305' && keyData.byteLength !== 32) return; + // Try each legal value of the extractable parameter + vector.extractable.forEach(function(extractable) { + vector.formats.forEach(function(format) { + var data = keyData; + if (format === "jwk") { + data = jwkData(keyData, algorithm); + } + // Generate all combinations of valid usages for testing + allValidUsages(vector.legalUsages).forEach(function(usages) { + testFormat(format, algorithm, data, keyData.length * 8, usages, extractable); + }); + testEmptyUsages(format, algorithm, data, keyData.length * 8, extractable); + }); + }); + + }); + }); + + function hasLength(algorithm) { + return algorithm.name === 'HMAC' || algorithm.name.startsWith('AES') || algorithm.name.startsWith('KMAC'); + } + + // Test importKey with a given key format and other parameters. If + // extrable is true, export the key and verify that it matches the input. + function testFormat(format, algorithm, keyData, keySize, usages, extractable) { + promise_test(function(test) { + return subtle.importKey(format, keyData, algorithm, extractable, usages). + then(function(key) { + assert_equals(key.constructor, CryptoKey, "Imported a CryptoKey object"); + assert_goodCryptoKey(key, hasLength(key.algorithm) ? { length: keySize, ...algorithm } : algorithm, extractable, usages, 'secret'); + if (!extractable) { + return; + } + + return subtle.exportKey(format, key). + then(function(result) { + if (format !== "jwk") { + assert_true(equalBuffers(keyData, result), "Round trip works"); + } else { + assert_true(equalJwk(keyData, result), "Round trip works"); + } + }, function(err) { + assert_unreached("Threw an unexpected error: " + err.toString()); + }); + }, function(err) { + assert_unreached("Threw an unexpected error: " + err.toString()); + }); + }, "Good parameters: " + keySize.toString() + " bits " + parameterString(format, keyData, algorithm, extractable, usages)); + } + + // Test importKey with a given key format and other parameters but with empty usages. + // Should fail with SyntaxError + function testEmptyUsages(format, algorithm, keyData, keySize, extractable) { + const usages = []; + promise_test(function(test) { + return subtle.importKey(format, keyData, algorithm, extractable, usages). + then(function(key) { + assert_unreached("importKey succeeded but should have failed with SyntaxError"); + }, function(err) { + assert_equals(err.name, "SyntaxError", "Should throw correct error, not " + err.name + ": " + err.message); + }); + }, "Empty Usages: " + keySize.toString() + " bits " + parameterString(format, keyData, algorithm, extractable, usages)); + } + + + + // Helper methods follow: + + // Are two array buffers the same? + function equalBuffers(a, b) { + if (a.byteLength !== b.byteLength) { + return false; + } + + var aBytes = new Uint8Array(a); + var bBytes = new Uint8Array(b); + + for (var i=0; i i)), // 0x00-0xC7 + customization: new Uint8Array([ + 77, 121, 32, 84, 97, 103, 103, 101, 100, 32, 65, 112, 112, 108, 105, 99, + 97, 116, 105, 111, 110, + ]), // "My Tagged Application" + signature: new Uint8Array([ + 0x1f, 0x5b, 0x4e, 0x6c, 0xca, 0x02, 0x20, 0x9e, 0x0d, 0xcb, 0x5c, 0xa6, + 0x35, 0xb8, 0x9a, 0x15, 0xe2, 0x71, 0xec, 0xc7, 0x60, 0x07, 0x1d, 0xfd, + 0x80, 0x5f, 0xaa, 0x38, 0xf9, 0x72, 0x92, 0x30, + ]), + }, + { + // Sample #4 - KMAC256, with customization, 512-bit output + name: "KMAC256 with customization and 512-bit output", + algorithm: "KMAC256", + length: 512, + keyBuffer: new Uint8Array([ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + ]), + key: null, + plaintext: new Uint8Array([0x00, 0x01, 0x02, 0x03]), + customization: new Uint8Array([ + 77, 121, 32, 84, 97, 103, 103, 101, 100, 32, 65, 112, 112, 108, 105, 99, + 97, 116, 105, 111, 110, + ]), // "My Tagged Application" + signature: new Uint8Array([ + 0x20, 0xc5, 0x70, 0xc3, 0x13, 0x46, 0xf7, 0x03, 0xc9, 0xac, 0x36, 0xc6, + 0x1c, 0x03, 0xcb, 0x64, 0xc3, 0x97, 0x0d, 0x0c, 0xfc, 0x78, 0x7e, 0x9b, + 0x79, 0x59, 0x9d, 0x27, 0x3a, 0x68, 0xd2, 0xf7, 0xf6, 0x9d, 0x4c, 0xc3, + 0xde, 0x9d, 0x10, 0x4a, 0x35, 0x16, 0x89, 0xf2, 0x7c, 0xf6, 0xf5, 0x95, + 0x1f, 0x01, 0x03, 0xf3, 0x3f, 0x4f, 0x24, 0x87, 0x10, 0x24, 0xd9, 0xc2, + 0x77, 0x73, 0xa8, 0xdd, + ]), + }, + { + // Sample #5 - KMAC256, large data, no customization, 512-bit output + name: "KMAC256 with large data and no customization", + algorithm: "KMAC256", + length: 512, + keyBuffer: new Uint8Array([ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + ]), + key: null, + plaintext: new Uint8Array(Array.from({ length: 200 }, (_, i) => i)), // 0x00-0xC7 + customization: undefined, + signature: new Uint8Array([ + 0x75, 0x35, 0x8c, 0xf3, 0x9e, 0x41, 0x49, 0x4e, 0x94, 0x97, 0x07, 0x92, + 0x7c, 0xee, 0x0a, 0xf2, 0x0a, 0x3f, 0xf5, 0x53, 0x90, 0x4c, 0x86, 0xb0, + 0x8f, 0x21, 0xcc, 0x41, 0x4b, 0xcf, 0xd6, 0x91, 0x58, 0x9d, 0x27, 0xcf, + 0x5e, 0x15, 0x36, 0x9c, 0xbb, 0xff, 0x8b, 0x9a, 0x4c, 0x2e, 0xb1, 0x78, + 0x00, 0x85, 0x5d, 0x02, 0x35, 0xff, 0x63, 0x5d, 0xa8, 0x25, 0x33, 0xec, + 0x6b, 0x75, 0x9b, 0x69, + ]), + }, + { + // Sample #6 - KMAC256, large data, with customization, 512-bit output + name: "KMAC256 with large data and customization", + algorithm: "KMAC256", + length: 512, + keyBuffer: new Uint8Array([ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + ]), + key: null, + plaintext: new Uint8Array(Array.from({ length: 200 }, (_, i) => i)), // 0x00-0xC7 + customization: new Uint8Array([ + 77, 121, 32, 84, 97, 103, 103, 101, 100, 32, 65, 112, 112, 108, 105, 99, + 97, 116, 105, 111, 110, + ]), // "My Tagged Application" + signature: new Uint8Array([ + 0xb5, 0x86, 0x18, 0xf7, 0x1f, 0x92, 0xe1, 0xd5, 0x6c, 0x1b, 0x8c, 0x55, + 0xdd, 0xd7, 0xcd, 0x18, 0x8b, 0x97, 0xb4, 0xca, 0x4d, 0x99, 0x83, 0x1e, + 0xb2, 0x69, 0x9a, 0x83, 0x7d, 0xa2, 0xe4, 0xd9, 0x70, 0xfb, 0xac, 0xfd, + 0xe5, 0x00, 0x33, 0xae, 0xa5, 0x85, 0xf1, 0xa2, 0x70, 0x85, 0x10, 0xc3, + 0x2d, 0x07, 0x88, 0x08, 0x01, 0xbd, 0x18, 0x28, 0x98, 0xfe, 0x47, 0x68, + 0x76, 0xfc, 0x89, 0x65, + ]), + }, + ]; + + return vectors; +} diff --git a/test/fixtures/wpt/WebCryptoAPI/sign_verify/mldsa.js b/test/fixtures/wpt/WebCryptoAPI/sign_verify/mldsa.js new file mode 100644 index 00000000000000..e31d36362b0dc9 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/sign_verify/mldsa.js @@ -0,0 +1,757 @@ +function run_test() { + setup({ explicit_done: true }); + + var subtle = self.crypto.subtle; // Change to test prefixed implementations + + // When are all these tests really done? When all the promises they use have resolved. + var all_promises = []; + + // Source file [algorithm_name]_vectors.js provides the getTestVectors method + // for the algorithm that drives these tests. + var testVectors = getTestVectors(); + var invalidTestVectors = getInvalidTestVectors(); + + // Test verification first, because signing tests rely on that working + testVectors.forEach(function (vector) { + var promise = importVectorKeys(vector, ['verify'], ['sign']).then( + function (vectors) { + var algorithm = vector.algorithmName; + promise_test(function (test) { + var operation = subtle + .verify(algorithm, vector.publicKey, vector.signature, vector.data) + .then( + function (is_verified) { + assert_true(is_verified, 'Signature verified'); + }, + function (err) { + assert_unreached( + 'Verification should not throw error ' + + vector.name + + ': ' + + err.message + + "'" + ); + } + ); + + return operation; + }, vector.name + ' verification'); + }, + function (err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested verification. + promise_test(function (test) { + assert_unreached( + 'importVectorKeys failed for ' + + vector.name + + ". Message: ''" + + err.message + + "''" + ); + }, 'importVectorKeys step: ' + vector.name + ' verification'); + } + ); + + all_promises.push(promise); + }); + + // Test verification with an altered buffer after call + testVectors.forEach(function (vector) { + var promise = importVectorKeys(vector, ['verify'], ['sign']).then( + function (vectors) { + var algorithm = vector.algorithmName; + promise_test(function (test) { + var signature = copyBuffer(vector.signature); + var operation = subtle + .verify(algorithm, vector.publicKey, signature, vector.data) + .then( + function (is_verified) { + assert_true(is_verified, 'Signature verified'); + }, + function (err) { + assert_unreached( + 'Verification should not throw error ' + + vector.name + + ': ' + + err.message + + "'" + ); + } + ); + + signature[0] = 255 - signature[0]; + return operation; + }, vector.name + ' verification with altered signature after call'); + }, + function (err) { + promise_test(function (test) { + assert_unreached( + 'importVectorKeys failed for ' + + vector.name + + ". Message: ''" + + err.message + + "''" + ); + }, 'importVectorKeys step: ' + + vector.name + + ' verification with altered signature after call'); + } + ); + + all_promises.push(promise); + }); + + // Check for successful verification even if plaintext is altered after call. + testVectors.forEach(function (vector) { + var promise = importVectorKeys(vector, ['verify'], ['sign']).then( + function (vectors) { + var algorithm = vector.algorithmName; + promise_test(function (test) { + var plaintext = copyBuffer(vector.data); + var operation = subtle + .verify(algorithm, vector.publicKey, vector.signature, plaintext) + .then( + function (is_verified) { + assert_true(is_verified, 'Signature verified'); + }, + function (err) { + assert_unreached( + 'Verification should not throw error ' + + vector.name + + ': ' + + err.message + + "'" + ); + } + ); + + plaintext[0] = 255 - plaintext[0]; + return operation; + }, vector.name + ' with altered plaintext after call'); + }, + function (err) { + promise_test(function (test) { + assert_unreached( + 'importVectorKeys failed for ' + + vector.name + + ". Message: ''" + + err.message + + "''" + ); + }, 'importVectorKeys step: ' + + vector.name + + ' with altered plaintext after call'); + } + ); + + all_promises.push(promise); + }); + + // Check for failures due to using privateKey to verify. + testVectors.forEach(function (vector) { + var promise = importVectorKeys(vector, ['verify'], ['sign']).then( + function (vectors) { + var algorithm = vector.algorithmName; + promise_test(function (test) { + return subtle + .verify(algorithm, vector.privateKey, vector.signature, vector.data) + .then( + function (plaintext) { + assert_unreached( + 'Should have thrown error for using privateKey to verify in ' + + vector.name + + ': ' + + err.message + + "'" + ); + }, + function (err) { + assert_equals( + err.name, + 'InvalidAccessError', + "Should throw InvalidAccessError instead of '" + + err.message + + "'" + ); + } + ); + }, vector.name + ' using privateKey to verify'); + }, + function (err) { + promise_test(function (test) { + assert_unreached( + 'importVectorKeys failed for ' + + vector.name + + ". Message: ''" + + err.message + + "''" + ); + }, 'importVectorKeys step: ' + + vector.name + + ' using privateKey to verify'); + } + ); + + all_promises.push(promise); + }); + + // Check for failures due to using publicKey to sign. + testVectors.forEach(function (vector) { + var promise = importVectorKeys(vector, ['verify'], ['sign']).then( + function (vectors) { + var algorithm = vector.algorithmName; + promise_test(function (test) { + return subtle.sign(algorithm, vector.publicKey, vector.data).then( + function (signature) { + assert_unreached( + 'Should have thrown error for using publicKey to sign in ' + + vector.name + + ': ' + + err.message + + "'" + ); + }, + function (err) { + assert_equals( + err.name, + 'InvalidAccessError', + "Should throw InvalidAccessError instead of '" + + err.message + + "'" + ); + } + ); + }, vector.name + ' using publicKey to sign'); + }, + function (err) { + promise_test(function (test) { + assert_unreached( + 'importVectorKeys failed for ' + + vector.name + + ". Message: ''" + + err.message + + "''" + ); + }, 'importVectorKeys step: ' + + vector.name + + ' using publicKey to sign'); + } + ); + + all_promises.push(promise); + }); + + // Check for failures due to no "verify" usage. + testVectors.forEach(function (originalVector) { + var vector = Object.assign({}, originalVector); + + var promise = importVectorKeys(vector, [], ['sign']).then( + function (vectors) { + var algorithm = vector.algorithmName; + promise_test(function (test) { + return subtle + .verify(algorithm, vector.publicKey, vector.signature, vector.data) + .then( + function (plaintext) { + assert_unreached( + 'Should have thrown error for no verify usage in ' + + vector.name + + ': ' + + err.message + + "'" + ); + }, + function (err) { + assert_equals( + err.name, + 'InvalidAccessError', + "Should throw InvalidAccessError instead of '" + + err.message + + "'" + ); + } + ); + }, vector.name + ' no verify usage'); + }, + function (err) { + promise_test(function (test) { + assert_unreached( + 'importVectorKeys failed for ' + + vector.name + + ". Message: ''" + + err.message + + "''" + ); + }, 'importVectorKeys step: ' + vector.name + ' no verify usage'); + } + ); + + all_promises.push(promise); + }); + + // Check for successful signing and verification. + testVectors.forEach(function (vector) { + var promise = importVectorKeys(vector, ['verify'], ['sign']).then( + function (vectors) { + var algorithm = vector.algorithmName; + promise_test(function (test) { + return subtle.sign(algorithm, vector.privateKey, vector.data).then( + function (signature) { + // Can we verify the signature? + return subtle + .verify(algorithm, vector.publicKey, signature, vector.data) + .then( + function (is_verified) { + assert_true(is_verified, 'Round trip verification works'); + return signature; + }, + function (err) { + assert_unreached( + 'verify error for test ' + + vector.name + + ': ' + + err.message + + "'" + ); + } + ); + }, + function (err) { + assert_unreached( + 'sign error for test ' + vector.name + ": '" + err.message + "'" + ); + } + ); + }, vector.name + ' round trip'); + }, + function (err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested signing or verifying + promise_test(function (test) { + assert_unreached( + 'importVectorKeys failed for ' + + vector.name + + ". Message: ''" + + err.message + + "''" + ); + }, 'importVectorKeys step: ' + vector.name + ' round trip'); + } + ); + + all_promises.push(promise); + }); + + // Test signing with the wrong algorithm + testVectors.forEach(function (vector) { + // Want to get the key for the wrong algorithm + var promise = subtle + .generateKey({ name: 'HMAC', hash: 'SHA-1' }, false, ['sign', 'verify']) + .then( + function (wrongKey) { + var algorithm = vector.algorithmName; + return importVectorKeys(vector, ['verify'], ['sign']).then( + function (vectors) { + promise_test(function (test) { + var operation = subtle + .sign(algorithm, wrongKey, vector.data) + .then( + function (signature) { + assert_unreached( + 'Signing should not have succeeded for ' + vector.name + ); + }, + function (err) { + assert_equals( + err.name, + 'InvalidAccessError', + "Should have thrown InvalidAccessError instead of '" + + err.message + + "'" + ); + } + ); + + return operation; + }, vector.name + ' signing with wrong algorithm name'); + }, + function (err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested verification. + promise_test(function (test) { + assert_unreached( + 'importVectorKeys failed for ' + + vector.name + + ". Message: ''" + + err.message + + "''" + ); + }, 'importVectorKeys step: ' + + vector.name + + ' signing with wrong algorithm name'); + } + ); + }, + function (err) { + promise_test(function (test) { + assert_unreached( + 'Generate wrong key for test ' + + vector.name + + " failed: '" + + err.message + + "'" + ); + }, 'generate wrong key step: ' + + vector.name + + ' signing with wrong algorithm name'); + } + ); + + all_promises.push(promise); + }); + + // Test verification with the wrong algorithm + testVectors.forEach(function (vector) { + // Want to get the key for the wrong algorithm + var promise = subtle + .generateKey({ name: 'HMAC', hash: 'SHA-1' }, false, ['sign', 'verify']) + .then( + function (wrongKey) { + return importVectorKeys(vector, ['verify'], ['sign']).then( + function (vectors) { + var algorithm = vector.algorithmName; + promise_test(function (test) { + var operation = subtle + .verify(algorithm, wrongKey, vector.signature, vector.data) + .then( + function (signature) { + assert_unreached( + 'Verifying should not have succeeded for ' + vector.name + ); + }, + function (err) { + assert_equals( + err.name, + 'InvalidAccessError', + "Should have thrown InvalidAccessError instead of '" + + err.message + + "'" + ); + } + ); + + return operation; + }, vector.name + ' verifying with wrong algorithm name'); + }, + function (err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested verification. + promise_test(function (test) { + assert_unreached( + 'importVectorKeys failed for ' + + vector.name + + ". Message: ''" + + err.message + + "''" + ); + }, 'importVectorKeys step: ' + + vector.name + + ' verifying with wrong algorithm name'); + } + ); + }, + function (err) { + promise_test(function (test) { + assert_unreached( + 'Generate wrong key for test ' + + vector.name + + " failed: '" + + err.message + + "'" + ); + }, 'generate wrong key step: ' + + vector.name + + ' verifying with wrong algorithm name'); + } + ); + + all_promises.push(promise); + }); + + // Test verification fails with wrong signature + testVectors.forEach(function (vector) { + var promise = importVectorKeys(vector, ['verify'], ['sign']).then( + function (vectors) { + var algorithm = vector.algorithmName; + var signature = copyBuffer(vector.signature); + signature[0] = 255 - signature[0]; + promise_test(function (test) { + var operation = subtle + .verify(algorithm, vector.publicKey, signature, vector.data) + .then( + function (is_verified) { + assert_false(is_verified, 'Signature NOT verified'); + }, + function (err) { + assert_unreached( + 'Verification should not throw error ' + + vector.name + + ': ' + + err.message + + "'" + ); + } + ); + + return operation; + }, vector.name + ' verification failure due to altered signature'); + }, + function (err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested verification. + promise_test(function (test) { + assert_unreached( + 'importVectorKeys failed for ' + + vector.name + + ". Message: ''" + + err.message + + "''" + ); + }, 'importVectorKeys step: ' + + vector.name + + ' verification failure due to altered signature'); + } + ); + + all_promises.push(promise); + }); + + // Test verification fails with short (odd length) signature + testVectors.forEach(function (vector) { + var promise = importVectorKeys(vector, ['verify'], ['sign']).then( + function (vectors) { + var algorithm = vector.algorithmName; + var signature = vector.signature.slice(1); // Skip the first byte + promise_test(function (test) { + var operation = subtle + .verify(algorithm, vector.publicKey, signature, vector.data) + .then( + function (is_verified) { + assert_false(is_verified, 'Signature NOT verified'); + }, + function (err) { + assert_unreached( + 'Verification should not throw error ' + + vector.name + + ': ' + + err.message + + "'" + ); + } + ); + + return operation; + }, vector.name + ' verification failure due to shortened signature'); + }, + function (err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested verification. + promise_test(function (test) { + assert_unreached( + 'importVectorKeys failed for ' + + vector.name + + ". Message: ''" + + err.message + + "''" + ); + }, 'importVectorKeys step: ' + + vector.name + + ' verification failure due to shortened signature'); + } + ); + + all_promises.push(promise); + }); + + // Test verification fails with wrong plaintext + testVectors.forEach(function (vector) { + var promise = importVectorKeys(vector, ['verify'], ['sign']).then( + function (vectors) { + var algorithm = vector.algorithmName; + var plaintext = copyBuffer(vector.data); + plaintext[0] = 255 - plaintext[0]; + promise_test(function (test) { + var operation = subtle + .verify(algorithm, vector.publicKey, vector.signature, plaintext) + .then( + function (is_verified) { + assert_false(is_verified, 'Signature NOT verified'); + }, + function (err) { + assert_unreached( + 'Verification should not throw error ' + + vector.name + + ': ' + + err.message + + "'" + ); + } + ); + + return operation; + }, vector.name + ' verification failure due to altered plaintext'); + }, + function (err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested verification. + promise_test(function (test) { + assert_unreached( + 'importVectorKeys failed for ' + + vector.name + + ". Message: ''" + + err.message + + "''" + ); + }, 'importVectorKeys step: ' + + vector.name + + ' verification failure due to altered plaintext'); + } + ); + + all_promises.push(promise); + }); + + // Test invalid signatures + invalidTestVectors.forEach(function (vector) { + var promise = importVectorKeys(vector, ['verify'], ['sign']).then( + function (vectors) { + var algorithm = vector.algorithmName; + promise_test(function (test) { + var operation = subtle + .verify(algorithm, vector.publicKey, vector.signature, vector.data) + .then( + function (is_verified) { + assert_false(is_verified, 'Signature unexpectedly verified'); + }, + function (err) { + assert_unreached( + 'Verification should not throw error ' + + vector.name + + ': ' + + err.message + + "'" + ); + } + ); + + return operation; + }, vector.name + ' verification'); + }, + function (err) { + // We need a failed test if the importVectorKey operation fails, so + // we know we never tested verification. + promise_test(function (test) { + assert_unreached( + 'importVectorKeys failed for ' + + vector.name + + ". Message: ''" + + err.message + + "''" + ); + }, 'importVectorKeys step: ' + vector.name + ' verification'); + } + ); + + all_promises.push(promise); + }); + + promise_test(function () { + return Promise.all(all_promises) + .then(function () { + done(); + }) + .catch(function () { + done(); + }); + }, 'setup'); + + // A test vector has all needed fields for signing and verifying, EXCEPT that the + // key field may be null. This function replaces that null with the Correct + // CryptoKey object. + // + // Returns a Promise that yields an updated vector on success. + function importVectorKeys(vector, publicKeyUsages, privateKeyUsages) { + var publicPromise, privatePromise; + + if (vector.publicKey !== null) { + publicPromise = new Promise(function (resolve, reject) { + resolve(vector); + }); + } else { + publicPromise = subtle + .importKey( + vector.publicKeyFormat, + vector.publicKeyBuffer, + { name: vector.algorithmName }, + false, + publicKeyUsages + ) + .then(function (key) { + vector.publicKey = key; + return vector; + }); // Returns a copy of the sourceBuffer it is sent. + } + + if (vector.privateKey !== null) { + privatePromise = new Promise(function (resolve, reject) { + resolve(vector); + }); + } else { + privatePromise = subtle + .importKey( + vector.privateKeyFormat, + vector.privateKeyBuffer, + { name: vector.algorithmName }, + false, + privateKeyUsages + ) + .then(function (key) { + vector.privateKey = key; + return vector; + }); + } + + return Promise.all([publicPromise, privatePromise]); + } + + // Returns a copy of the sourceBuffer it is sent. + function copyBuffer(sourceBuffer) { + var source = new Uint8Array(sourceBuffer); + var copy = new Uint8Array(sourceBuffer.byteLength); + + for (var i = 0; i < source.byteLength; i++) { + copy[i] = source[i]; + } + + return copy; + } + + function equalBuffers(a, b) { + if (a.byteLength !== b.byteLength) { + return false; + } + + var aBytes = new Uint8Array(a); + var bBytes = new Uint8Array(b); + + for (var i = 0; i < a.byteLength; i++) { + if (aBytes[i] !== bBytes[i]) { + return false; + } + } + + return true; + } + + return; +} diff --git a/test/fixtures/wpt/WebCryptoAPI/sign_verify/mldsa.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/sign_verify/mldsa.tentative.https.any.js new file mode 100644 index 00000000000000..364e1d39e8eb27 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/sign_verify/mldsa.tentative.https.any.js @@ -0,0 +1,6 @@ +// META: title=WebCryptoAPI: sign() and verify() Using ML-DSA +// META: script=mldsa_vectors.js +// META: script=mldsa.js +// META: timeout=long + +run_test(); diff --git a/test/fixtures/wpt/WebCryptoAPI/sign_verify/mldsa_vectors.js b/test/fixtures/wpt/WebCryptoAPI/sign_verify/mldsa_vectors.js new file mode 100644 index 00000000000000..a035821b7e3593 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/sign_verify/mldsa_vectors.js @@ -0,0 +1,1086 @@ +// PKCS#8 private keys for ML-DSA variants +var pkcs8 = { + 'ML-DSA-44': new Uint8Array([ + 48, 52, 2, 1, 0, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 3, 17, 4, 34, 128, + 32, 153, 21, 95, 99, 48, 150, 218, 124, 190, 8, 122, 137, 72, 184, 79, 118, + 123, 16, 249, 1, 200, 35, 194, 64, 177, 221, 43, 200, 112, 5, 201, 62, + ]), + 'ML-DSA-65': new Uint8Array([ + 48, 52, 2, 1, 0, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 3, 18, 4, 34, 128, + 32, 132, 164, 137, 75, 123, 70, 164, 178, 3, 156, 206, 16, 195, 26, 133, + 186, 176, 195, 102, 48, 254, 35, 29, 66, 103, 17, 67, 152, 38, 7, 130, 139, + ]), + 'ML-DSA-87': new Uint8Array([ + 48, 52, 2, 1, 0, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 3, 19, 4, 34, 128, + 32, 161, 80, 109, 145, 76, 109, 101, 140, 117, 39, 228, 51, 151, 221, 109, + 76, 37, 246, 164, 121, 116, 51, 90, 76, 208, 59, 254, 105, 131, 68, 18, 81, + ]), +}; + +// SPKI public keys for ML-DSA variants +var spki = { + 'ML-DSA-44': new Uint8Array([ + 48, 130, 5, 50, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 3, 17, 3, 130, 5, + 33, 0, 85, 152, 213, 68, 198, 20, 177, 84, 200, 188, 33, 104, 36, 161, 193, + 127, 226, 151, 48, 107, 122, 191, 89, 86, 188, 3, 245, 199, 18, 79, 168, + 192, 218, 218, 223, 227, 84, 133, 41, 187, 9, 183, 14, 222, 155, 137, 84, + 111, 138, 97, 234, 152, 52, 15, 163, 47, 227, 218, 19, 20, 229, 93, 99, 252, + 155, 213, 30, 241, 158, 211, 213, 191, 155, 73, 211, 145, 59, 194, 75, 140, + 3, 161, 149, 139, 48, 172, 155, 172, 120, 234, 142, 79, 78, 116, 215, 184, + 50, 182, 162, 192, 93, 221, 179, 216, 70, 186, 92, 93, 51, 190, 61, 173, + 105, 206, 9, 208, 52, 54, 208, 252, 115, 176, 146, 118, 23, 0, 5, 41, 151, + 121, 241, 246, 193, 206, 212, 160, 181, 7, 99, 220, 78, 96, 123, 142, 35, + 107, 37, 218, 138, 139, 228, 207, 166, 132, 87, 36, 116, 251, 174, 10, 41, + 196, 171, 26, 212, 90, 213, 223, 141, 87, 232, 59, 46, 173, 16, 247, 173, 4, + 219, 165, 234, 8, 217, 233, 163, 13, 10, 160, 22, 87, 232, 2, 9, 92, 177, + 35, 67, 55, 104, 51, 204, 231, 81, 209, 62, 31, 117, 56, 141, 78, 109, 148, + 118, 191, 93, 193, 59, 30, 88, 237, 19, 169, 14, 11, 150, 102, 215, 144, 69, + 246, 32, 159, 110, 49, 75, 78, 225, 121, 184, 206, 234, 126, 171, 164, 43, + 237, 244, 63, 83, 70, 136, 213, 244, 121, 184, 34, 201, 249, 95, 64, 165, + 99, 14, 195, 231, 18, 121, 20, 156, 80, 231, 133, 197, 0, 94, 195, 22, 251, + 255, 174, 213, 103, 75, 88, 58, 138, 66, 37, 85, 162, 15, 242, 29, 49, 147, + 191, 163, 170, 109, 195, 22, 63, 197, 149, 117, 100, 36, 81, 115, 203, 126, + 62, 86, 103, 193, 182, 69, 238, 233, 162, 62, 248, 132, 158, 212, 208, 187, + 127, 212, 198, 169, 245, 26, 153, 28, 207, 85, 65, 145, 200, 23, 196, 38, + 64, 49, 54, 233, 185, 72, 156, 86, 230, 127, 152, 108, 184, 240, 109, 8, + 103, 228, 206, 142, 73, 74, 214, 52, 182, 203, 82, 201, 175, 188, 111, 42, + 232, 8, 177, 131, 47, 237, 92, 120, 210, 124, 48, 185, 215, 137, 36, 70, + 162, 164, 119, 0, 155, 20, 57, 33, 27, 220, 77, 254, 233, 190, 106, 135, 21, + 194, 57, 238, 95, 162, 78, 164, 33, 210, 215, 43, 100, 96, 232, 87, 19, 43, + 65, 240, 183, 17, 131, 247, 97, 241, 7, 111, 159, 40, 252, 45, 228, 76, 71, + 46, 85, 181, 54, 41, 135, 162, 144, 227, 128, 121, 173, 207, 119, 54, 19, + 197, 23, 231, 176, 125, 190, 32, 76, 60, 34, 24, 160, 42, 73, 190, 124, 99, + 5, 9, 214, 6, 220, 177, 206, 79, 222, 10, 142, 250, 63, 179, 67, 21, 159, + 57, 126, 239, 28, 238, 240, 107, 79, 185, 174, 232, 168, 146, 128, 229, 119, + 19, 21, 33, 239, 193, 42, 178, 152, 124, 24, 203, 131, 193, 93, 162, 2, 208, + 231, 20, 203, 232, 47, 54, 114, 255, 236, 97, 99, 156, 15, 160, 75, 60, 111, + 59, 35, 25, 230, 43, 91, 170, 161, 74, 70, 179, 180, 251, 71, 197, 240, 104, + 42, 39, 202, 206, 12, 115, 249, 138, 55, 252, 216, 61, 185, 121, 76, 137, + 172, 166, 88, 92, 130, 18, 52, 67, 13, 187, 49, 147, 212, 77, 74, 56, 59, + 123, 99, 205, 36, 137, 96, 111, 148, 121, 157, 2, 83, 246, 86, 156, 152, 98, + 172, 77, 244, 214, 225, 184, 240, 121, 144, 56, 213, 161, 43, 67, 4, 161, + 104, 202, 91, 134, 247, 108, 24, 46, 187, 63, 216, 50, 125, 120, 17, 216, + 22, 228, 156, 253, 7, 180, 15, 130, 180, 72, 71, 169, 3, 236, 247, 11, 170, + 32, 76, 236, 225, 133, 250, 20, 235, 200, 143, 89, 25, 158, 49, 158, 164, + 213, 221, 81, 120, 241, 150, 210, 19, 79, 165, 24, 35, 170, 182, 242, 255, + 143, 171, 148, 140, 41, 207, 186, 98, 224, 16, 152, 224, 38, 110, 175, 169, + 111, 132, 201, 178, 114, 25, 196, 50, 149, 158, 193, 180, 101, 183, 92, 109, + 131, 102, 119, 123, 78, 107, 223, 4, 1, 206, 140, 130, 237, 205, 36, 18, + 180, 197, 154, 26, 236, 140, 173, 230, 101, 35, 189, 121, 104, 21, 75, 81, + 224, 186, 212, 81, 107, 66, 244, 235, 64, 90, 206, 39, 44, 43, 162, 187, 63, + 229, 217, 154, 185, 157, 24, 125, 252, 91, 136, 59, 47, 182, 200, 73, 19, + 137, 132, 81, 16, 234, 227, 210, 32, 16, 160, 188, 250, 27, 190, 164, 53, + 244, 219, 199, 177, 146, 117, 50, 99, 72, 235, 37, 154, 72, 51, 203, 61, 39, + 230, 34, 132, 117, 217, 167, 201, 42, 17, 76, 72, 103, 172, 93, 169, 29, 76, + 88, 178, 226, 32, 53, 190, 60, 210, 132, 113, 198, 26, 70, 179, 47, 34, 184, + 88, 178, 208, 1, 196, 89, 136, 167, 33, 38, 9, 255, 89, 202, 27, 93, 229, + 100, 192, 24, 234, 200, 186, 125, 231, 212, 188, 11, 29, 51, 189, 70, 147, + 176, 231, 81, 16, 114, 152, 159, 21, 124, 185, 208, 50, 74, 211, 113, 207, + 35, 54, 173, 205, 133, 52, 167, 199, 87, 158, 120, 33, 204, 163, 146, 233, + 21, 61, 28, 102, 48, 232, 184, 15, 219, 238, 240, 215, 222, 239, 3, 110, + 180, 95, 103, 147, 236, 10, 57, 195, 159, 231, 50, 92, 145, 165, 44, 204, + 121, 187, 9, 210, 80, 86, 251, 169, 132, 236, 248, 23, 207, 222, 227, 13, + 53, 1, 88, 69, 105, 13, 238, 202, 251, 194, 245, 14, 38, 1, 245, 157, 212, + 162, 182, 217, 230, 115, 139, 175, 219, 199, 74, 124, 186, 158, 3, 220, 87, + 220, 177, 85, 13, 58, 168, 223, 6, 238, 156, 80, 121, 44, 166, 176, 0, 48, + 98, 70, 93, 78, 50, 192, 16, 186, 2, 233, 105, 105, 120, 195, 17, 100, 141, + 214, 158, 144, 63, 4, 88, 190, 101, 209, 55, 119, 46, 128, 117, 225, 121, + 204, 195, 19, 61, 170, 116, 251, 225, 230, 28, 27, 249, 84, 195, 224, 190, + 60, 212, 83, 3, 148, 204, 4, 103, 50, 233, 175, 207, 47, 51, 216, 79, 251, + 150, 81, 171, 7, 145, 55, 188, 187, 217, 200, 155, 246, 85, 42, 123, 18, + 112, 192, 116, 163, 40, 187, 132, 192, 210, 188, 106, 117, 217, 185, 183, + 202, 33, 11, 205, 10, 61, 52, 15, 66, 131, 121, 112, 26, 96, 166, 241, 1, + 68, 206, 80, 92, 132, 83, 89, 126, 135, 157, 4, 202, 16, 5, 131, 112, 62, + 56, 234, 176, 213, 119, 205, 203, 17, 106, 156, 117, 251, 135, 21, 73, 219, + 238, 3, 88, 21, 71, 136, 118, 0, 7, 106, 151, 200, 221, 179, 206, 50, 198, + 27, 118, 181, 27, 85, 35, 248, 44, 57, 15, 221, 97, 121, 4, 167, 111, 182, + 207, 195, 52, 134, 195, 128, 173, 111, 98, 152, 29, 138, 197, 175, 171, 247, + 194, 20, 134, 209, 232, 94, 17, 203, 139, 30, 237, 187, 243, 16, 180, 43, + 105, 236, 66, 175, 170, 139, 24, 99, 28, 225, 141, 96, 250, 119, 0, 111, + 212, 34, 217, 42, 134, 88, 78, 76, 126, 169, 168, 59, 154, 93, 54, 43, 161, + 29, 111, 124, 59, 225, 52, 86, 147, 38, 151, 161, 36, 119, 204, 164, 121, + 46, 186, 65, 84, 70, 38, 15, 203, 48, 168, 235, 231, 30, 55, 95, 36, 10, 20, + 166, 109, 8, 18, 109, 251, 213, 82, 142, 240, 49, 249, 180, 78, 69, + ]), + 'ML-DSA-65': new Uint8Array([ + 48, 130, 7, 178, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 3, 18, 3, 130, 7, + 161, 0, 216, 177, 233, 60, 151, 24, 246, 66, 175, 161, 192, 118, 9, 177, 87, + 232, 5, 216, 49, 254, 251, 160, 51, 216, 250, 171, 229, 104, 149, 117, 135, + 107, 5, 239, 244, 167, 83, 57, 49, 153, 29, 135, 108, 138, 117, 236, 120, + 65, 89, 65, 17, 201, 127, 147, 246, 103, 238, 204, 25, 83, 240, 29, 173, + 127, 140, 1, 88, 40, 43, 134, 51, 19, 125, 131, 224, 50, 167, 82, 20, 217, + 215, 162, 41, 95, 215, 56, 130, 226, 177, 216, 20, 169, 133, 85, 140, 9, + 105, 172, 54, 121, 0, 87, 202, 18, 93, 96, 147, 103, 127, 164, 63, 197, 97, + 49, 230, 125, 53, 80, 64, 20, 239, 29, 90, 118, 102, 221, 177, 6, 220, 220, + 170, 107, 107, 18, 138, 125, 138, 70, 66, 60, 185, 232, 209, 4, 100, 17, + 118, 24, 181, 110, 241, 50, 250, 138, 209, 19, 84, 220, 61, 96, 80, 128, 81, + 101, 160, 9, 5, 53, 33, 112, 60, 59, 195, 79, 115, 190, 101, 93, 56, 171, + 146, 51, 82, 233, 66, 225, 226, 211, 72, 58, 9, 74, 222, 185, 175, 211, 156, + 164, 68, 188, 119, 46, 14, 64, 160, 13, 207, 60, 81, 68, 108, 148, 59, 88, + 88, 92, 88, 171, 249, 204, 160, 137, 222, 234, 168, 233, 3, 86, 224, 174, + 105, 224, 1, 177, 184, 230, 236, 30, 85, 249, 56, 105, 211, 50, 83, 168, + 139, 28, 175, 181, 22, 89, 166, 215, 152, 218, 184, 111, 65, 24, 82, 71, + 185, 100, 172, 66, 178, 6, 215, 164, 252, 56, 40, 198, 207, 152, 110, 186, + 207, 39, 235, 179, 38, 215, 88, 105, 109, 177, 130, 91, 5, 223, 164, 78, + 241, 176, 125, 197, 94, 100, 40, 214, 251, 239, 253, 88, 154, 14, 75, 254, + 94, 210, 86, 244, 51, 95, 168, 139, 213, 73, 87, 151, 209, 150, 126, 88, 69, + 251, 116, 157, 122, 96, 212, 206, 42, 218, 38, 85, 184, 50, 246, 188, 35, + 72, 60, 226, 155, 246, 86, 209, 110, 133, 161, 129, 126, 80, 154, 238, 64, + 64, 170, 156, 177, 225, 52, 87, 42, 88, 154, 174, 246, 30, 84, 143, 221, 51, + 27, 65, 60, 40, 22, 120, 42, 145, 34, 82, 235, 79, 20, 215, 211, 231, 151, + 108, 119, 53, 116, 190, 13, 139, 199, 189, 84, 54, 186, 222, 90, 116, 253, + 227, 207, 104, 209, 118, 42, 144, 94, 22, 219, 198, 211, 216, 171, 75, 245, + 61, 240, 157, 108, 81, 19, 238, 39, 120, 210, 242, 63, 126, 6, 15, 18, 97, + 232, 207, 184, 84, 239, 72, 115, 90, 95, 112, 78, 45, 201, 13, 102, 208, + 151, 146, 253, 153, 177, 115, 14, 194, 184, 107, 118, 120, 63, 105, 89, 144, + 60, 242, 80, 106, 32, 11, 204, 170, 165, 221, 182, 31, 187, 159, 216, 118, + 218, 207, 182, 107, 136, 211, 162, 231, 196, 128, 83, 251, 192, 189, 149, 1, + 245, 36, 146, 159, 11, 116, 30, 191, 141, 182, 157, 227, 91, 88, 72, 224, + 55, 195, 96, 245, 135, 249, 142, 16, 229, 237, 27, 60, 2, 91, 138, 82, 197, + 210, 40, 8, 123, 172, 202, 207, 119, 199, 190, 102, 40, 141, 174, 93, 211, + 219, 134, 105, 26, 103, 100, 102, 62, 130, 224, 135, 173, 82, 224, 200, 213, + 76, 211, 38, 181, 16, 97, 99, 75, 14, 42, 162, 223, 237, 141, 1, 29, 140, + 191, 146, 49, 236, 179, 88, 202, 220, 124, 239, 231, 131, 101, 134, 111, 28, + 54, 151, 172, 67, 167, 113, 96, 204, 63, 76, 169, 95, 14, 175, 149, 189, + 173, 39, 177, 102, 23, 158, 102, 236, 224, 70, 203, 190, 132, 230, 136, 3, + 28, 201, 131, 148, 164, 219, 181, 208, 26, 239, 111, 86, 35, 102, 133, 114, + 113, 180, 184, 82, 180, 106, 124, 248, 126, 87, 177, 165, 176, 204, 128, + 141, 179, 141, 34, 119, 160, 57, 206, 168, 95, 197, 110, 79, 60, 48, 170, + 125, 206, 147, 137, 156, 85, 46, 7, 193, 228, 150, 22, 46, 147, 51, 153, + 157, 248, 151, 253, 114, 58, 126, 38, 127, 19, 225, 99, 183, 235, 175, 90, + 166, 8, 233, 141, 10, 85, 232, 147, 7, 20, 137, 240, 84, 231, 86, 134, 50, + 212, 201, 6, 253, 18, 150, 114, 160, 140, 2, 254, 189, 152, 14, 68, 110, 50, + 134, 199, 73, 237, 56, 116, 110, 135, 36, 40, 14, 167, 50, 71, 81, 9, 178, + 54, 182, 247, 64, 32, 204, 116, 92, 131, 40, 30, 246, 188, 236, 182, 187, + 132, 239, 124, 136, 238, 146, 137, 247, 87, 52, 15, 78, 108, 135, 178, 101, + 70, 199, 193, 192, 144, 196, 106, 186, 141, 42, 101, 214, 196, 67, 175, 38, + 8, 189, 148, 166, 253, 221, 144, 119, 81, 1, 232, 175, 81, 237, 13, 188, + 220, 230, 47, 115, 184, 179, 0, 51, 118, 39, 22, 114, 232, 88, 15, 121, 216, + 130, 107, 173, 108, 175, 225, 113, 40, 223, 185, 6, 244, 227, 73, 38, 64, + 84, 10, 200, 53, 81, 179, 217, 106, 172, 59, 161, 70, 180, 70, 48, 56, 46, + 233, 133, 245, 57, 120, 154, 167, 49, 109, 188, 152, 245, 181, 1, 159, 247, + 44, 167, 152, 6, 191, 246, 38, 120, 141, 57, 241, 168, 60, 38, 6, 82, 248, + 87, 85, 0, 10, 22, 19, 44, 178, 63, 38, 78, 1, 210, 166, 140, 3, 199, 112, + 135, 155, 36, 13, 204, 124, 47, 5, 190, 103, 91, 205, 147, 248, 115, 177, + 196, 180, 234, 85, 35, 24, 182, 16, 207, 107, 167, 10, 54, 193, 146, 71, 95, + 45, 109, 184, 43, 101, 155, 184, 55, 171, 196, 136, 89, 227, 84, 183, 31, 0, + 137, 230, 146, 250, 6, 27, 225, 241, 11, 95, 124, 248, 133, 171, 149, 67, + 73, 19, 110, 104, 173, 86, 6, 246, 195, 196, 200, 175, 53, 18, 198, 223, + 140, 85, 208, 253, 204, 220, 255, 232, 88, 238, 20, 97, 24, 52, 13, 3, 179, + 62, 151, 101, 67, 33, 79, 253, 157, 253, 233, 197, 109, 130, 78, 11, 165, + 214, 200, 41, 157, 63, 46, 175, 251, 246, 225, 227, 199, 92, 107, 216, 58, + 124, 226, 202, 153, 92, 31, 250, 182, 92, 99, 0, 110, 18, 78, 228, 166, 190, + 67, 88, 245, 155, 139, 82, 152, 39, 204, 74, 140, 95, 82, 82, 160, 147, 144, + 33, 0, 242, 200, 22, 102, 160, 233, 102, 224, 42, 205, 240, 56, 95, 197, + 226, 175, 235, 240, 125, 10, 51, 12, 246, 150, 234, 173, 95, 132, 173, 174, + 1, 161, 23, 39, 52, 168, 87, 54, 4, 66, 201, 34, 155, 82, 133, 170, 76, 52, + 226, 109, 163, 19, 34, 184, 226, 39, 20, 75, 72, 201, 70, 188, 71, 182, 230, + 6, 19, 255, 8, 145, 193, 63, 81, 150, 24, 72, 89, 168, 74, 98, 173, 133, 67, + 227, 44, 252, 252, 227, 192, 125, 20, 227, 144, 24, 31, 48, 67, 67, 48, 94, + 163, 52, 219, 163, 225, 214, 214, 109, 211, 122, 213, 198, 90, 204, 40, 97, + 211, 121, 17, 28, 132, 246, 110, 230, 51, 197, 42, 162, 143, 199, 158, 215, + 210, 133, 60, 65, 127, 1, 153, 193, 22, 171, 250, 114, 204, 246, 255, 126, + 25, 96, 44, 164, 102, 172, 211, 23, 245, 122, 48, 221, 249, 138, 148, 134, + 206, 135, 246, 42, 235, 198, 89, 189, 45, 125, 204, 69, 193, 48, 29, 144, + 125, 224, 127, 66, 1, 134, 141, 224, 211, 193, 141, 69, 128, 75, 167, 244, + 160, 120, 54, 191, 214, 29, 40, 249, 15, 46, 68, 141, 91, 242, 91, 80, 252, + 109, 122, 154, 64, 153, 56, 65, 254, 106, 18, 4, 172, 171, 136, 80, 98, 79, + 133, 255, 4, 100, 191, 144, 171, 219, 46, 132, 181, 130, 228, 107, 68, 32, + 123, 201, 17, 67, 35, 144, 180, 160, 30, 125, 9, 55, 184, 172, 0, 159, 250, + 232, 83, 168, 162, 102, 158, 121, 208, 177, 116, 163, 160, 80, 241, 46, 156, + 58, 203, 240, 67, 176, 244, 170, 160, 115, 122, 141, 154, 101, 218, 178, + 119, 130, 195, 32, 207, 51, 149, 98, 51, 219, 57, 121, 216, 156, 101, 218, + 184, 220, 204, 41, 181, 149, 63, 80, 194, 11, 143, 164, 219, 23, 123, 141, + 119, 43, 94, 78, 175, 89, 165, 48, 167, 44, 45, 219, 197, 15, 202, 118, 116, + 245, 151, 218, 14, 199, 96, 27, 102, 206, 198, 123, 222, 178, 210, 20, 200, + 38, 25, 124, 58, 102, 92, 197, 107, 51, 5, 236, 125, 173, 198, 113, 144, + 108, 177, 22, 104, 223, 165, 39, 9, 84, 87, 124, 80, 153, 8, 212, 76, 2, 28, + 12, 90, 212, 129, 148, 212, 229, 63, 29, 200, 113, 171, 154, 107, 189, 202, + 22, 147, 7, 32, 253, 70, 37, 224, 98, 199, 129, 21, 54, 49, 52, 124, 84, 40, + 190, 194, 108, 73, 26, 15, 124, 87, 87, 198, 217, 122, 127, 82, 167, 131, + 59, 8, 172, 49, 162, 61, 64, 79, 196, 205, 65, 110, 75, 130, 128, 197, 182, + 251, 110, 141, 197, 184, 166, 244, 246, 217, 20, 105, 85, 42, 80, 251, 77, + 59, 204, 247, 179, 218, 181, 124, 209, 4, 28, 118, 234, 145, 237, 140, 106, + 54, 88, 82, 28, 235, 68, 221, 109, 139, 11, 166, 182, 63, 142, 194, 255, + 213, 219, 116, 158, 31, 224, 119, 126, 232, 160, 144, 1, 177, 92, 219, 162, + 49, 181, 116, 163, 104, 245, 193, 188, 26, 172, 15, 190, 135, 207, 106, 246, + 13, 132, 76, 189, 160, 25, 123, 26, 20, 48, 203, 59, 209, 69, 235, 103, 253, + 160, 108, 83, 206, 70, 98, 0, 2, 57, 162, 202, 63, 45, 89, 173, 201, 254, + 254, 253, 143, 21, 77, 131, 184, 234, 37, 68, 206, 69, 186, 179, 145, 147, + 135, 42, 137, 152, 253, 213, 240, 13, 122, 161, 218, 186, 180, 213, 162, + 150, 231, 63, 112, 182, 233, 86, 12, 225, 195, 133, 37, 28, 22, 147, 201, + 200, 197, 115, 3, 138, 194, 86, 79, 247, 27, 241, 149, 128, 197, 8, 11, 134, + 53, 118, 175, 248, 253, 114, 91, 31, 192, 253, 209, 111, 31, 228, 244, 184, + 179, 146, 145, 167, 137, 155, 184, 218, 38, 62, 187, 22, 181, 193, 93, 16, + 9, 195, 42, 198, 225, 100, 144, 148, 223, 184, 40, 117, 32, 131, 94, 93, 83, + 88, 125, 95, 220, 20, 206, 7, 228, 78, 54, 238, 178, 196, 38, 245, 95, 8, + 235, 106, 17, 175, 142, 193, 60, 179, 53, 244, 92, 147, 244, 218, 95, 127, + 251, 128, 42, 105, 82, 243, 224, 213, 25, 91, 151, 22, 201, 18, 25, 230, + 165, 85, 25, 249, 170, 160, 171, 210, 209, 32, 154, 124, 245, 60, 30, 255, + 138, 154, 29, 85, 156, 232, 177, 78, 14, 137, 52, 215, 247, 26, 211, 115, + 72, 20, 133, 232, 1, 151, 251, 63, 45, 120, 69, 49, 209, 130, 255, 2, 218, + 21, 251, 16, 86, 30, 62, 136, 92, 149, 60, 6, 125, 129, 145, 235, 102, 190, + 144, 248, 1, 53, 135, 21, 158, 44, 158, 230, 246, 172, 249, 161, 105, 204, + 49, 60, 70, 63, 127, 163, 231, 175, 174, 234, 147, 185, 62, 5, 244, 156, 4, + 31, 39, 156, 176, 154, 251, 166, 143, 212, 43, 30, 97, 50, 37, 176, 155, 77, + 149, 102, + ]), + 'ML-DSA-87': new Uint8Array([ + 48, 130, 10, 50, 48, 11, 6, 9, 96, 134, 72, 1, 101, 3, 4, 3, 19, 3, 130, 10, + 33, 0, 146, 184, 67, 40, 172, 27, 204, 27, 135, 22, 109, 223, 127, 23, 97, + 130, 198, 228, 199, 62, 178, 21, 173, 20, 88, 180, 205, 168, 17, 164, 135, + 92, 85, 146, 76, 194, 152, 80, 239, 157, 33, 21, 239, 182, 176, 254, 124, + 80, 135, 138, 87, 169, 103, 99, 87, 5, 91, 161, 239, 59, 18, 246, 148, 20, + 32, 60, 117, 245, 182, 156, 196, 230, 82, 117, 228, 211, 81, 45, 115, 217, + 23, 95, 138, 95, 103, 124, 32, 89, 187, 48, 251, 103, 81, 234, 76, 4, 57, + 197, 71, 48, 125, 169, 195, 147, 183, 142, 166, 8, 147, 7, 77, 240, 111, 44, + 168, 23, 89, 107, 95, 220, 75, 202, 44, 25, 244, 200, 160, 0, 174, 111, 107, + 204, 22, 36, 122, 191, 101, 33, 52, 252, 14, 47, 25, 109, 135, 48, 131, 253, + 195, 237, 60, 86, 14, 119, 85, 28, 182, 139, 136, 191, 59, 187, 90, 126, + 207, 168, 238, 184, 83, 77, 254, 208, 21, 57, 104, 188, 228, 134, 82, 249, + 190, 249, 163, 120, 111, 68, 225, 210, 131, 29, 151, 153, 146, 71, 163, 104, + 225, 194, 33, 64, 213, 92, 145, 253, 42, 32, 233, 95, 224, 72, 184, 119, + 192, 113, 253, 177, 153, 246, 240, 49, 103, 170, 229, 82, 69, 186, 36, 252, + 29, 124, 255, 25, 148, 5, 160, 159, 105, 157, 185, 25, 158, 122, 145, 30, + 245, 51, 205, 62, 56, 154, 23, 52, 0, 225, 177, 105, 195, 131, 177, 151, + 197, 114, 110, 128, 227, 127, 176, 28, 252, 217, 56, 61, 136, 148, 190, 124, + 108, 129, 62, 243, 235, 37, 70, 228, 233, 10, 67, 124, 120, 58, 164, 83, 57, + 80, 39, 204, 98, 28, 199, 136, 75, 12, 51, 255, 24, 130, 127, 19, 239, 160, + 94, 137, 75, 15, 82, 158, 252, 163, 43, 236, 193, 234, 27, 74, 69, 14, 179, + 171, 10, 169, 27, 138, 172, 213, 189, 222, 167, 110, 24, 11, 118, 151, 223, + 94, 154, 125, 9, 21, 137, 70, 128, 51, 102, 52, 105, 104, 157, 54, 186, 75, + 217, 226, 169, 71, 125, 177, 253, 218, 85, 236, 242, 25, 215, 147, 181, 104, + 242, 82, 75, 50, 165, 49, 102, 128, 82, 237, 170, 134, 162, 196, 56, 247, + 199, 138, 102, 118, 37, 66, 114, 165, 177, 156, 251, 39, 199, 12, 167, 246, + 169, 150, 108, 91, 192, 42, 68, 192, 244, 255, 107, 18, 191, 7, 73, 19, 174, + 28, 116, 66, 131, 96, 173, 60, 131, 190, 249, 219, 246, 71, 182, 124, 183, + 129, 101, 109, 95, 180, 78, 17, 140, 182, 62, 80, 195, 184, 253, 176, 169, + 153, 1, 29, 83, 39, 252, 150, 41, 219, 176, 48, 151, 108, 60, 255, 239, 0, + 85, 101, 193, 110, 204, 12, 254, 22, 136, 15, 154, 217, 88, 13, 28, 252, + 232, 48, 32, 33, 41, 221, 103, 227, 228, 177, 54, 175, 195, 106, 174, 140, + 54, 128, 108, 214, 228, 215, 118, 226, 206, 171, 21, 155, 162, 152, 135, + 203, 16, 170, 130, 100, 173, 155, 243, 80, 40, 98, 157, 248, 7, 101, 88, + 199, 218, 224, 141, 82, 238, 121, 92, 82, 97, 49, 31, 155, 61, 63, 84, 227, + 90, 143, 164, 59, 216, 101, 19, 35, 134, 2, 20, 18, 197, 97, 215, 169, 85, + 220, 75, 254, 91, 125, 144, 43, 65, 128, 29, 66, 77, 184, 172, 89, 123, 203, + 231, 254, 59, 18, 249, 204, 249, 220, 153, 84, 166, 63, 23, 108, 120, 145, + 216, 67, 223, 123, 248, 15, 253, 63, 191, 126, 84, 95, 98, 141, 66, 200, + 129, 194, 174, 30, 80, 48, 75, 113, 14, 102, 101, 218, 249, 14, 203, 24, 6, + 11, 89, 99, 56, 49, 17, 148, 160, 242, 101, 191, 102, 227, 115, 33, 107, 71, + 235, 6, 141, 68, 161, 162, 165, 227, 159, 82, 253, 54, 157, 214, 255, 141, + 151, 154, 134, 150, 93, 141, 97, 158, 244, 180, 135, 42, 10, 3, 148, 9, 152, + 149, 20, 18, 237, 253, 180, 136, 165, 13, 80, 195, 220, 43, 3, 178, 10, 127, + 144, 2, 207, 209, 246, 40, 110, 38, 133, 9, 22, 180, 11, 223, 116, 236, 205, + 186, 25, 183, 155, 165, 77, 206, 101, 255, 106, 223, 70, 10, 22, 176, 119, + 142, 163, 197, 178, 251, 216, 112, 237, 63, 201, 77, 219, 196, 2, 176, 48, + 15, 207, 91, 74, 236, 21, 8, 205, 126, 77, 28, 13, 26, 28, 202, 250, 100, + 79, 134, 209, 193, 78, 202, 58, 248, 124, 215, 64, 143, 244, 17, 23, 163, + 162, 241, 249, 49, 210, 168, 203, 213, 135, 77, 14, 29, 35, 193, 234, 58, + 12, 106, 165, 163, 251, 192, 115, 251, 7, 198, 189, 93, 207, 178, 246, 50, + 189, 185, 51, 45, 84, 140, 194, 34, 46, 92, 90, 136, 81, 81, 53, 52, 253, + 128, 247, 131, 243, 21, 207, 245, 141, 49, 178, 213, 214, 211, 8, 17, 234, + 133, 225, 104, 197, 186, 224, 117, 1, 173, 104, 17, 177, 161, 223, 71, 195, + 159, 194, 45, 177, 116, 26, 187, 193, 161, 213, 179, 158, 8, 122, 186, 122, + 191, 158, 5, 12, 178, 235, 78, 132, 78, 189, 16, 86, 110, 73, 51, 129, 255, + 242, 110, 63, 6, 53, 209, 110, 132, 236, 43, 239, 192, 221, 138, 1, 128, + 176, 0, 113, 85, 119, 201, 36, 188, 202, 9, 223, 98, 196, 42, 130, 158, 149, + 200, 150, 202, 132, 118, 153, 97, 54, 195, 154, 15, 45, 246, 129, 144, 255, + 231, 75, 25, 56, 47, 178, 98, 10, 106, 84, 56, 113, 161, 227, 37, 246, 1, + 245, 129, 173, 70, 186, 11, 28, 125, 198, 243, 225, 113, 130, 5, 138, 52, + 251, 194, 152, 105, 48, 214, 13, 246, 228, 75, 236, 194, 223, 177, 64, 150, + 97, 167, 20, 27, 74, 76, 166, 199, 239, 91, 240, 8, 22, 54, 41, 63, 35, 112, + 255, 251, 88, 252, 147, 173, 185, 43, 98, 83, 155, 230, 176, 55, 161, 8, 83, + 15, 110, 151, 241, 110, 168, 203, 190, 198, 218, 152, 144, 150, 58, 123, 11, + 123, 250, 104, 113, 198, 93, 1, 152, 51, 172, 140, 246, 115, 113, 229, 218, + 166, 200, 35, 123, 16, 133, 169, 191, 59, 103, 12, 114, 15, 60, 37, 4, 92, + 208, 54, 31, 79, 56, 225, 6, 11, 74, 107, 79, 225, 239, 16, 73, 249, 234, + 197, 129, 230, 97, 39, 115, 49, 96, 141, 41, 242, 225, 177, 214, 18, 103, + 34, 229, 37, 176, 241, 99, 82, 227, 195, 77, 32, 64, 4, 120, 49, 199, 209, + 139, 2, 4, 222, 233, 45, 151, 141, 142, 252, 41, 124, 231, 13, 144, 63, 212, + 252, 145, 34, 142, 232, 152, 84, 135, 87, 175, 46, 53, 139, 60, 168, 135, + 167, 101, 253, 127, 152, 138, 154, 31, 231, 198, 77, 89, 182, 9, 54, 103, + 119, 100, 218, 245, 44, 191, 74, 30, 152, 84, 22, 62, 159, 131, 163, 223, 3, + 51, 194, 241, 49, 9, 213, 43, 214, 201, 75, 158, 198, 22, 203, 209, 190, + 199, 189, 75, 4, 6, 72, 60, 241, 113, 171, 30, 42, 143, 73, 51, 72, 206, + 110, 175, 203, 195, 199, 15, 155, 208, 166, 121, 26, 132, 59, 44, 72, 155, + 7, 48, 122, 132, 224, 142, 3, 7, 21, 207, 11, 30, 112, 18, 149, 146, 127, + 41, 104, 197, 169, 86, 213, 108, 253, 111, 160, 5, 11, 202, 172, 233, 32, 5, + 52, 92, 124, 152, 162, 11, 88, 28, 166, 248, 141, 251, 38, 161, 53, 49, 136, + 246, 183, 85, 9, 165, 115, 108, 18, 208, 218, 129, 165, 163, 131, 34, 32, + 94, 226, 121, 93, 24, 87, 226, 105, 25, 242, 128, 198, 78, 26, 237, 21, 92, + 33, 121, 8, 119, 131, 140, 193, 14, 60, 139, 130, 19, 65, 96, 50, 5, 249, + 12, 27, 51, 23, 195, 89, 255, 47, 23, 109, 62, 202, 190, 5, 131, 92, 91, 39, + 27, 209, 132, 146, 95, 98, 66, 26, 230, 186, 236, 186, 162, 149, 81, 143, + 221, 21, 79, 171, 236, 21, 161, 19, 135, 10, 213, 168, 200, 135, 19, 221, + 177, 207, 106, 214, 194, 124, 220, 53, 45, 176, 245, 178, 189, 49, 242, 22, + 230, 154, 241, 146, 230, 187, 180, 244, 158, 145, 197, 225, 51, 150, 140, + 26, 175, 78, 142, 243, 232, 221, 137, 205, 130, 178, 54, 216, 136, 118, 212, + 33, 90, 206, 18, 224, 158, 44, 23, 144, 204, 24, 184, 48, 81, 233, 124, 20, + 222, 77, 119, 144, 22, 145, 241, 19, 206, 135, 252, 164, 114, 84, 37, 175, + 107, 67, 243, 183, 137, 213, 53, 236, 41, 73, 50, 34, 146, 218, 204, 68, + 235, 158, 150, 139, 133, 75, 248, 157, 7, 0, 53, 68, 44, 156, 110, 56, 197, + 209, 201, 0, 155, 225, 85, 35, 169, 193, 231, 36, 31, 142, 101, 168, 29, + 192, 31, 128, 81, 191, 253, 184, 153, 226, 214, 1, 27, 6, 0, 192, 36, 101, + 72, 105, 150, 226, 3, 21, 12, 127, 72, 250, 223, 240, 136, 249, 157, 129, + 247, 91, 178, 157, 208, 86, 146, 23, 176, 150, 35, 211, 155, 22, 207, 119, + 168, 167, 122, 180, 183, 106, 97, 138, 87, 96, 34, 141, 110, 145, 231, 226, + 35, 115, 232, 129, 54, 186, 128, 190, 238, 37, 169, 194, 37, 24, 237, 211, + 164, 111, 54, 88, 245, 125, 67, 78, 194, 11, 194, 235, 217, 87, 203, 14, + 220, 189, 107, 68, 94, 139, 66, 230, 5, 54, 64, 28, 246, 143, 75, 127, 239, + 243, 20, 251, 189, 246, 246, 151, 90, 219, 227, 242, 223, 205, 40, 124, 245, + 4, 189, 72, 39, 145, 110, 96, 120, 164, 27, 117, 146, 177, 30, 76, 173, 106, + 130, 228, 192, 189, 59, 167, 30, 127, 178, 164, 5, 133, 80, 199, 207, 216, + 189, 156, 93, 222, 150, 129, 81, 193, 180, 38, 59, 8, 214, 210, 95, 150, + 182, 175, 148, 43, 153, 169, 66, 62, 135, 140, 159, 89, 195, 253, 3, 132, + 180, 164, 244, 243, 232, 71, 196, 200, 158, 194, 114, 115, 193, 88, 161, + 185, 235, 247, 14, 126, 225, 176, 111, 17, 79, 77, 245, 80, 229, 174, 6, + 180, 156, 217, 85, 174, 201, 255, 237, 85, 83, 53, 188, 153, 98, 91, 193, + 21, 211, 49, 145, 196, 252, 52, 66, 226, 131, 203, 214, 130, 237, 194, 208, + 174, 102, 133, 220, 235, 222, 79, 232, 36, 21, 161, 248, 51, 185, 164, 156, + 95, 121, 65, 57, 233, 183, 29, 199, 105, 104, 12, 90, 195, 186, 81, 199, + 176, 1, 87, 16, 226, 192, 206, 185, 197, 46, 34, 75, 174, 153, 238, 15, 50, + 87, 226, 96, 26, 197, 202, 73, 235, 19, 140, 9, 79, 12, 52, 83, 76, 85, 146, + 234, 24, 151, 179, 178, 118, 58, 162, 223, 103, 69, 244, 231, 135, 167, 204, + 117, 166, 60, 237, 82, 63, 11, 4, 207, 10, 146, 54, 126, 191, 79, 133, 60, + 128, 34, 136, 170, 23, 84, 81, 38, 94, 9, 130, 245, 100, 115, 209, 34, 228, + 158, 101, 216, 135, 208, 207, 191, 169, 115, 252, 144, 139, 226, 252, 6, 44, + 221, 134, 170, 87, 11, 46, 124, 58, 219, 179, 238, 6, 98, 216, 18, 174, 42, + 12, 97, 126, 85, 245, 81, 220, 232, 135, 114, 21, 125, 135, 225, 182, 245, + 228, 223, 242, 62, 158, 35, 76, 6, 110, 25, 184, 206, 124, 237, 54, 252, + 199, 44, 78, 89, 0, 135, 44, 176, 57, 168, 36, 221, 173, 77, 214, 209, 60, + 1, 202, 238, 237, 61, 90, 47, 114, 230, 92, 238, 235, 18, 151, 220, 243, + 225, 163, 159, 139, 189, 253, 62, 225, 182, 202, 59, 7, 83, 99, 129, 118, + 175, 37, 246, 85, 119, 251, 246, 69, 180, 247, 37, 24, 194, 89, 158, 97, + 230, 247, 254, 145, 102, 89, 77, 68, 245, 3, 103, 83, 28, 45, 168, 30, 189, + 151, 112, 120, 215, 84, 90, 198, 85, 85, 129, 55, 127, 124, 28, 137, 229, + 139, 54, 88, 229, 105, 81, 212, 83, 28, 107, 250, 82, 164, 43, 24, 15, 57, + 206, 156, 19, 145, 95, 57, 169, 8, 128, 211, 29, 213, 195, 148, 27, 73, 186, + 221, 242, 11, 167, 78, 246, 133, 18, 118, 67, 236, 59, 19, 112, 254, 93, + 168, 157, 118, 0, 107, 248, 57, 149, 67, 222, 123, 225, 207, 251, 69, 218, + 56, 110, 162, 19, 25, 209, 209, 213, 200, 158, 70, 9, 100, 208, 77, 48, 255, + 151, 200, 0, 68, 230, 70, 120, 209, 29, 86, 225, 188, 189, 226, 101, 42, + 176, 32, 147, 121, 72, 151, 130, 217, 13, 66, 148, 84, 129, 215, 249, 164, + 174, 187, 80, 85, 185, 245, 108, 169, 119, 59, 178, 144, 229, 63, 194, 132, + 250, 131, 82, 161, 125, 126, 255, 252, 220, 204, 104, 231, 201, 136, 246, + 116, 43, 88, 233, 0, 43, 128, 214, 40, 59, 81, 147, 139, 132, 69, 24, 233, + 21, 14, 91, 230, 241, 19, 138, 163, 55, 13, 221, 47, 64, 140, 248, 6, 38, + 164, 16, 219, 63, 33, 180, 71, 151, 0, 234, 103, 58, 213, 222, 163, 95, 132, + 1, 178, 146, 66, 124, 242, 223, 102, 129, 192, 214, 194, 117, 162, 252, 246, + 143, 42, 70, 139, 97, 168, 64, 141, 190, 115, 126, 93, 175, 59, 49, 9, 184, + 88, 201, 100, 182, 142, 145, 244, 72, 128, 203, 49, 196, 5, 5, 18, 46, 34, + 87, 171, 132, 158, 128, 75, 194, 8, 242, 52, 156, 229, 245, 56, 245, 88, 14, + 195, 110, 166, 51, 158, 245, 195, 120, 17, 166, 66, 100, 212, 188, 243, 2, + 236, 90, 8, 16, 35, 151, 122, 175, 115, 168, 186, 191, 60, 71, 23, 81, 217, + 79, 203, 239, 61, 146, 247, 168, 112, 83, 102, 146, 222, 178, 45, 247, 63, + 23, 181, 3, 136, 208, 62, 154, 203, 35, 250, 238, 61, 98, 207, 90, 169, 175, + 36, 227, 9, 182, 78, 226, 99, 89, 67, 105, 185, 35, 242, 162, 54, 99, 60, + 148, 14, 118, 1, 26, 120, 62, 82, 62, 222, 34, 99, 58, 174, 145, 199, 190, + 21, 182, 117, 238, 13, 170, 29, 67, 149, 44, 90, 94, 181, 125, 182, 186, 82, + 55, 105, 253, 29, 212, 67, 134, 204, 227, 94, 255, 127, 72, 157, 140, 142, + 224, 77, 149, 29, 170, 45, 163, 214, 209, 46, 28, 125, 177, 111, 2, 92, 121, + 252, 166, 204, 227, 173, 51, 60, 162, 243, 202, 207, 103, 30, 153, 182, 116, + 182, 130, 98, 59, 25, 141, 239, 49, 224, 176, 27, 237, 218, 76, 68, 189, + 108, 185, 136, 255, 105, 150, 11, 153, 44, 248, 139, 199, 178, 235, 85, 115, + 121, 144, 87, 221, 50, 222, 238, 16, 20, 51, 190, 93, 248, 228, 84, 228, + 115, 31, 229, 227, 137, 180, 44, 115, 224, 119, 129, 181, 134, 224, 144, + 186, 123, 208, 118, 96, 101, 177, 191, 232, 171, 6, 17, 247, 187, 173, 84, + 70, 249, 19, 191, 116, 172, 126, 131, 216, 123, 225, 151, 55, 205, 177, 93, + 139, 117, + ]), +}; + +// Test message to sign (same for all variants) +var data = new Uint8Array([ + 77, 76, 45, 68, 83, 65, 32, 116, 101, 115, 116, 32, 109, 101, 115, 115, 97, + 103, 101, 32, 102, 111, 114, 32, 115, 105, 103, 110, 105, 110, 103, 32, 97, + 110, 100, 32, 118, 101, 114, 105, 102, 105, 99, 97, 116, 105, 111, 110, 46, + 32, 84, 104, 105, 115, 32, 105, 115, 32, 97, 32, 116, 101, 115, 116, 32, 111, + 102, 32, 77, 76, 45, 68, 83, 65, 32, 105, 109, 112, 108, 101, 109, 101, 110, + 116, 97, 116, 105, 111, 110, 46, +]); + +// Valid signatures for each ML-DSA variant +var signatures = { + 'ML-DSA-44': new Uint8Array([ + 56, 160, 238, 165, 206, 185, 253, 250, 240, 49, 157, 80, 171, 182, 48, 254, + 218, 228, 93, 60, 65, 196, 177, 207, 50, 102, 195, 4, 191, 17, 173, 83, 203, + 142, 171, 138, 160, 201, 238, 150, 63, 111, 25, 245, 225, 122, 188, 84, 238, + 168, 92, 57, 117, 107, 112, 29, 123, 67, 78, 233, 105, 13, 11, 47, 93, 61, + 45, 70, 114, 151, 243, 126, 161, 158, 141, 176, 129, 144, 12, 210, 152, 217, + 28, 215, 47, 209, 244, 167, 31, 250, 156, 31, 191, 64, 102, 143, 189, 136, + 59, 11, 17, 34, 234, 157, 22, 171, 24, 192, 201, 119, 220, 121, 143, 236, + 72, 17, 170, 191, 172, 242, 140, 71, 202, 22, 53, 161, 156, 208, 89, 51, 54, + 0, 151, 192, 2, 176, 115, 128, 0, 172, 70, 141, 151, 88, 122, 85, 217, 107, + 2, 217, 0, 97, 191, 156, 170, 9, 53, 108, 111, 62, 157, 28, 69, 80, 71, 221, + 83, 194, 182, 184, 70, 91, 50, 149, 50, 86, 111, 150, 195, 66, 68, 151, 6, + 208, 88, 203, 135, 215, 231, 208, 61, 54, 112, 56, 69, 221, 154, 60, 62, 71, + 45, 225, 68, 91, 60, 104, 185, 182, 39, 59, 199, 247, 170, 117, 227, 100, + 92, 85, 42, 173, 238, 34, 115, 146, 20, 248, 174, 107, 164, 32, 73, 22, 175, + 215, 106, 122, 164, 134, 66, 65, 227, 83, 93, 68, 211, 184, 167, 6, 109, + 236, 160, 183, 231, 4, 135, 77, 72, 163, 40, 175, 105, 95, 205, 120, 112, + 169, 182, 4, 176, 149, 178, 72, 75, 116, 214, 198, 225, 230, 238, 63, 96, + 60, 94, 169, 222, 116, 64, 31, 95, 34, 198, 106, 182, 27, 71, 57, 80, 46, + 18, 52, 52, 55, 113, 28, 128, 191, 176, 149, 86, 143, 9, 197, 15, 39, 180, + 227, 47, 133, 211, 220, 77, 186, 247, 26, 114, 42, 177, 190, 192, 57, 60, + 69, 54, 60, 179, 174, 1, 39, 63, 247, 50, 235, 29, 188, 254, 84, 215, 116, + 231, 94, 79, 200, 50, 215, 38, 41, 10, 211, 5, 197, 136, 147, 177, 159, 104, + 52, 49, 162, 178, 232, 30, 240, 24, 39, 160, 210, 193, 137, 65, 217, 255, + 57, 196, 118, 103, 74, 121, 161, 219, 84, 64, 123, 4, 229, 206, 231, 41, 2, + 168, 159, 64, 69, 115, 2, 61, 1, 211, 129, 236, 115, 186, 236, 163, 28, 206, + 11, 106, 189, 70, 137, 152, 13, 42, 116, 11, 235, 1, 99, 177, 135, 240, 141, + 27, 254, 143, 107, 84, 37, 49, 31, 205, 181, 208, 65, 149, 37, 132, 176, 7, + 235, 209, 228, 206, 190, 145, 166, 81, 106, 99, 88, 8, 190, 66, 167, 217, + 45, 177, 185, 135, 24, 89, 235, 164, 38, 100, 111, 85, 178, 135, 27, 15, 9, + 100, 34, 112, 39, 219, 211, 175, 69, 93, 157, 138, 74, 219, 13, 171, 207, + 152, 144, 175, 43, 174, 38, 88, 51, 114, 10, 235, 79, 233, 230, 4, 5, 143, + 44, 214, 216, 194, 6, 97, 184, 183, 219, 207, 249, 178, 106, 91, 60, 201, + 126, 134, 244, 128, 231, 29, 203, 16, 48, 61, 133, 101, 133, 2, 39, 155, + 142, 66, 148, 106, 61, 117, 114, 184, 136, 214, 191, 44, 227, 122, 163, 157, + 88, 50, 236, 206, 81, 225, 204, 89, 88, 77, 78, 148, 56, 255, 13, 8, 118, + 185, 155, 214, 233, 179, 236, 159, 207, 19, 254, 98, 176, 193, 204, 71, 191, + 100, 102, 56, 95, 79, 139, 84, 13, 77, 70, 0, 13, 52, 13, 210, 15, 6, 44, + 37, 176, 61, 39, 131, 65, 14, 157, 106, 214, 57, 62, 139, 142, 32, 210, 198, + 156, 241, 74, 38, 103, 179, 34, 92, 46, 21, 160, 222, 133, 47, 239, 240, + 198, 5, 142, 47, 29, 247, 206, 160, 47, 250, 161, 102, 244, 240, 184, 201, + 224, 52, 53, 51, 151, 175, 5, 175, 211, 148, 236, 27, 59, 224, 219, 168, + 229, 117, 67, 198, 14, 43, 106, 37, 161, 179, 41, 59, 161, 145, 159, 189, + 196, 74, 148, 124, 116, 254, 191, 149, 16, 139, 118, 240, 8, 144, 88, 28, + 215, 14, 191, 219, 6, 158, 165, 245, 174, 237, 7, 239, 177, 182, 58, 175, + 180, 142, 143, 40, 169, 57, 193, 78, 66, 89, 214, 222, 2, 6, 59, 162, 30, + 149, 255, 13, 169, 203, 192, 122, 16, 33, 174, 170, 143, 146, 53, 58, 28, 3, + 156, 18, 79, 185, 148, 41, 106, 59, 228, 137, 10, 232, 169, 135, 234, 248, + 16, 163, 74, 103, 112, 95, 101, 55, 207, 152, 155, 48, 92, 59, 115, 116, 99, + 174, 67, 57, 161, 166, 60, 235, 179, 209, 216, 50, 84, 177, 173, 53, 210, + 119, 230, 235, 56, 99, 64, 135, 245, 137, 37, 146, 140, 64, 160, 141, 120, + 114, 104, 160, 253, 204, 153, 47, 139, 235, 166, 66, 87, 181, 80, 1, 250, + 130, 216, 159, 143, 79, 192, 146, 222, 243, 238, 208, 163, 190, 124, 218, + 214, 59, 37, 219, 73, 141, 224, 194, 209, 148, 205, 143, 15, 42, 47, 232, + 132, 34, 200, 79, 88, 164, 203, 70, 41, 64, 250, 18, 4, 182, 139, 73, 27, + 160, 122, 132, 39, 193, 100, 79, 28, 249, 92, 139, 50, 67, 194, 128, 83, 74, + 231, 194, 75, 118, 98, 18, 47, 36, 4, 110, 250, 132, 130, 175, 136, 110, + 226, 168, 20, 242, 63, 195, 175, 179, 144, 193, 3, 62, 126, 85, 196, 69, + 137, 228, 66, 57, 20, 56, 149, 22, 38, 247, 243, 56, 87, 207, 86, 253, 21, + 227, 88, 122, 119, 52, 85, 93, 205, 112, 214, 158, 19, 246, 218, 127, 225, + 244, 159, 99, 140, 248, 123, 36, 243, 48, 138, 151, 47, 237, 24, 188, 73, + 227, 180, 190, 122, 26, 169, 65, 136, 195, 175, 168, 212, 136, 51, 47, 81, + 9, 182, 57, 62, 244, 180, 182, 102, 2, 84, 111, 208, 53, 21, 178, 121, 89, + 237, 52, 85, 231, 167, 174, 201, 0, 181, 204, 97, 70, 200, 18, 19, 149, 213, + 254, 194, 142, 224, 253, 127, 18, 119, 68, 51, 216, 201, 227, 111, 85, 254, + 216, 207, 217, 61, 88, 148, 108, 139, 14, 226, 158, 194, 155, 118, 76, 108, + 222, 30, 26, 166, 167, 119, 65, 16, 44, 110, 11, 24, 40, 222, 190, 89, 37, + 109, 221, 152, 185, 115, 155, 175, 13, 212, 17, 12, 220, 142, 72, 206, 17, + 166, 222, 253, 146, 107, 253, 163, 34, 230, 72, 218, 42, 166, 114, 72, 230, + 22, 33, 73, 58, 51, 212, 125, 219, 137, 1, 91, 222, 156, 88, 58, 66, 127, + 204, 187, 117, 5, 107, 77, 18, 207, 35, 202, 100, 196, 247, 37, 212, 195, + 16, 243, 121, 71, 153, 5, 138, 103, 99, 82, 145, 175, 181, 44, 215, 145, 97, + 100, 252, 172, 100, 0, 237, 222, 182, 88, 242, 187, 100, 174, 32, 141, 213, + 176, 227, 39, 94, 10, 186, 33, 46, 176, 141, 218, 189, 94, 33, 74, 111, 178, + 215, 97, 117, 31, 231, 206, 31, 97, 187, 241, 77, 19, 100, 222, 237, 130, + 232, 33, 43, 3, 195, 36, 65, 7, 197, 104, 0, 119, 2, 30, 191, 253, 21, 175, + 33, 139, 109, 88, 196, 131, 84, 241, 22, 6, 112, 41, 133, 144, 241, 228, + 213, 209, 173, 18, 154, 2, 49, 23, 156, 167, 43, 206, 249, 37, 134, 14, 153, + 105, 177, 39, 88, 12, 107, 104, 249, 223, 2, 205, 217, 208, 120, 236, 241, + 185, 101, 29, 112, 22, 115, 165, 197, 55, 245, 191, 164, 22, 55, 18, 216, + 81, 200, 11, 248, 187, 143, 117, 27, 2, 162, 143, 133, 202, 173, 149, 33, + 99, 14, 206, 97, 165, 89, 41, 240, 203, 176, 168, 95, 246, 72, 224, 38, 197, + 139, 66, 26, 32, 187, 17, 1, 229, 125, 173, 64, 89, 14, 23, 5, 212, 141, 40, + 151, 107, 52, 231, 10, 81, 12, 1, 190, 243, 14, 142, 38, 238, 161, 144, 188, + 65, 245, 98, 156, 148, 125, 247, 145, 193, 87, 249, 156, 185, 240, 4, 184, + 109, 190, 5, 151, 1, 165, 198, 123, 246, 235, 175, 75, 208, 255, 38, 123, + 114, 43, 246, 87, 19, 197, 246, 50, 163, 81, 63, 90, 206, 203, 244, 47, 164, + 221, 233, 71, 123, 74, 222, 92, 78, 238, 43, 120, 98, 186, 73, 187, 223, + 153, 236, 58, 78, 86, 124, 88, 241, 250, 31, 239, 46, 243, 48, 52, 65, 204, + 13, 127, 157, 117, 235, 209, 172, 242, 96, 123, 144, 113, 213, 132, 27, 168, + 77, 104, 73, 86, 210, 14, 100, 66, 21, 189, 57, 120, 217, 33, 250, 100, 246, + 178, 34, 43, 219, 87, 122, 180, 31, 205, 19, 195, 51, 239, 57, 74, 43, 171, + 151, 227, 41, 90, 238, 89, 187, 253, 96, 154, 136, 221, 114, 36, 55, 60, + 137, 189, 209, 195, 195, 3, 123, 130, 34, 4, 122, 38, 233, 114, 155, 30, 15, + 94, 59, 53, 2, 21, 47, 28, 0, 12, 201, 166, 10, 71, 98, 125, 57, 241, 138, + 64, 127, 125, 146, 226, 225, 241, 66, 59, 148, 129, 237, 226, 31, 209, 175, + 182, 63, 33, 180, 193, 143, 238, 217, 140, 49, 200, 209, 139, 250, 236, 231, + 235, 59, 92, 248, 67, 161, 93, 58, 202, 40, 148, 229, 215, 197, 126, 147, 9, + 83, 250, 75, 134, 199, 13, 255, 23, 184, 167, 181, 7, 99, 220, 154, 54, 225, + 199, 214, 27, 254, 154, 61, 170, 134, 238, 227, 193, 229, 18, 26, 100, 61, + 159, 157, 96, 14, 13, 140, 254, 79, 109, 113, 208, 137, 155, 71, 157, 169, + 130, 106, 138, 8, 171, 116, 77, 205, 102, 164, 250, 99, 139, 56, 50, 84, 29, + 176, 171, 214, 205, 44, 156, 144, 7, 236, 167, 182, 223, 134, 64, 101, 212, + 38, 97, 62, 122, 237, 193, 189, 253, 57, 98, 211, 239, 213, 151, 181, 141, + 98, 218, 64, 114, 87, 148, 158, 94, 254, 247, 167, 193, 193, 156, 35, 69, + 215, 39, 141, 93, 102, 57, 48, 209, 216, 59, 158, 159, 1, 167, 77, 100, 170, + 194, 145, 175, 192, 81, 72, 202, 94, 131, 5, 98, 252, 162, 35, 110, 62, 226, + 154, 48, 230, 118, 247, 79, 38, 96, 87, 151, 24, 6, 244, 139, 29, 5, 162, + 227, 214, 92, 200, 12, 145, 236, 182, 198, 167, 75, 230, 187, 99, 188, 57, + 17, 194, 212, 82, 16, 46, 79, 111, 45, 246, 132, 243, 17, 32, 158, 38, 78, + 218, 225, 115, 64, 213, 201, 185, 191, 153, 32, 124, 42, 71, 121, 150, 56, + 234, 152, 81, 251, 85, 213, 232, 127, 141, 249, 68, 242, 100, 115, 247, 155, + 203, 123, 0, 76, 194, 25, 104, 79, 76, 31, 3, 24, 185, 24, 14, 223, 20, 155, + 135, 236, 101, 208, 111, 105, 79, 134, 115, 13, 144, 161, 74, 109, 163, 47, + 24, 239, 230, 155, 54, 232, 249, 127, 243, 104, 193, 34, 239, 94, 200, 182, + 229, 213, 10, 153, 173, 8, 175, 17, 219, 6, 130, 72, 229, 116, 250, 250, 49, + 2, 77, 119, 63, 87, 147, 74, 73, 93, 33, 233, 231, 250, 22, 188, 172, 73, + 148, 90, 125, 155, 126, 243, 93, 227, 209, 99, 222, 134, 100, 99, 27, 179, + 195, 130, 138, 8, 146, 66, 224, 129, 163, 238, 235, 48, 229, 88, 112, 155, + 83, 88, 253, 121, 42, 249, 31, 217, 81, 9, 226, 202, 101, 232, 123, 88, 136, + 214, 215, 63, 36, 158, 110, 171, 22, 234, 217, 125, 85, 169, 25, 21, 242, + 12, 140, 55, 130, 40, 61, 8, 117, 64, 95, 196, 157, 190, 38, 218, 156, 38, + 221, 134, 223, 206, 156, 13, 100, 70, 181, 247, 15, 186, 251, 42, 234, 217, + 191, 159, 55, 184, 251, 179, 240, 77, 192, 42, 104, 208, 246, 155, 56, 45, + 82, 180, 187, 138, 67, 216, 18, 180, 189, 116, 111, 232, 95, 202, 153, 79, + 210, 171, 0, 230, 192, 126, 41, 117, 218, 182, 190, 17, 225, 71, 133, 161, + 7, 108, 24, 63, 188, 80, 248, 225, 193, 22, 173, 60, 214, 141, 182, 185, + 140, 73, 94, 184, 143, 113, 99, 65, 100, 232, 6, 34, 124, 243, 130, 68, 183, + 202, 183, 80, 170, 243, 70, 59, 14, 21, 58, 137, 35, 154, 223, 0, 103, 86, + 141, 137, 128, 117, 57, 110, 253, 254, 3, 113, 199, 159, 64, 56, 239, 196, + 78, 45, 202, 25, 189, 249, 234, 253, 217, 132, 23, 139, 116, 98, 236, 16, + 225, 9, 216, 118, 188, 62, 244, 171, 34, 253, 138, 209, 210, 249, 249, 77, + 252, 144, 214, 3, 72, 66, 30, 196, 39, 99, 241, 236, 136, 73, 167, 250, 110, + 215, 217, 204, 140, 97, 247, 161, 176, 59, 45, 117, 39, 236, 80, 137, 194, + 220, 52, 95, 159, 46, 18, 3, 173, 138, 196, 246, 112, 84, 118, 186, 112, + 219, 108, 241, 83, 63, 103, 58, 213, 209, 254, 31, 107, 197, 48, 53, 30, 65, + 247, 71, 19, 94, 125, 169, 101, 139, 223, 219, 113, 58, 221, 168, 110, 82, + 129, 67, 41, 192, 14, 206, 24, 110, 83, 176, 90, 6, 114, 126, 55, 236, 76, + 250, 160, 249, 92, 155, 70, 186, 228, 8, 118, 144, 232, 217, 66, 189, 33, + 93, 39, 210, 57, 235, 240, 165, 72, 220, 235, 210, 107, 158, 106, 188, 102, + 197, 55, 137, 84, 159, 1, 148, 116, 19, 127, 70, 166, 193, 33, 202, 106, + 198, 233, 217, 101, 195, 196, 144, 23, 249, 8, 94, 159, 134, 167, 184, 124, + 115, 9, 144, 47, 134, 218, 99, 211, 162, 233, 188, 37, 31, 34, 25, 74, 80, + 81, 85, 107, 119, 132, 133, 141, 150, 160, 163, 167, 178, 199, 209, 212, 32, + 67, 99, 101, 109, 112, 113, 123, 142, 151, 184, 203, 205, 223, 253, 29, 31, + 35, 42, 62, 71, 75, 90, 104, 136, 138, 149, 159, 160, 171, 189, 191, 192, + 204, 217, 237, 241, 23, 29, 41, 97, 139, 148, 170, 218, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 33, 55, 63, + ]), + 'ML-DSA-65': new Uint8Array([ + 146, 96, 54, 223, 241, 155, 153, 151, 60, 82, 43, 87, 39, 239, 17, 188, 251, + 35, 188, 126, 12, 147, 179, 10, 16, 161, 49, 80, 163, 83, 247, 170, 233, + 144, 246, 62, 148, 223, 26, 93, 247, 10, 196, 20, 117, 164, 163, 35, 96, + 109, 94, 75, 5, 50, 194, 191, 246, 236, 104, 37, 180, 68, 36, 143, 106, 100, + 51, 246, 20, 35, 151, 3, 120, 165, 249, 93, 119, 239, 14, 184, 124, 170, 24, + 41, 81, 240, 137, 17, 54, 155, 146, 136, 185, 137, 70, 81, 148, 10, 252, + 219, 177, 211, 152, 5, 192, 52, 59, 169, 69, 199, 203, 2, 145, 24, 252, 66, + 121, 217, 76, 202, 225, 112, 242, 78, 31, 218, 166, 162, 57, 156, 200, 5, + 10, 24, 72, 179, 142, 134, 31, 203, 187, 171, 141, 226, 230, 62, 217, 29, + 98, 134, 77, 30, 45, 228, 120, 98, 25, 157, 216, 253, 132, 12, 183, 224, + 131, 234, 170, 71, 204, 163, 200, 145, 12, 150, 215, 66, 240, 114, 45, 188, + 161, 39, 242, 151, 1, 76, 128, 115, 174, 90, 160, 11, 52, 133, 186, 124, 4, + 157, 195, 96, 213, 102, 69, 84, 194, 211, 80, 60, 42, 193, 51, 151, 224, 36, + 33, 59, 180, 139, 218, 28, 145, 51, 114, 91, 236, 18, 125, 82, 23, 252, 130, + 3, 127, 35, 17, 44, 160, 60, 84, 5, 20, 186, 178, 5, 95, 41, 177, 14, 128, + 251, 210, 228, 211, 46, 157, 190, 13, 50, 188, 8, 128, 222, 146, 33, 181, + 39, 83, 62, 29, 8, 233, 196, 73, 44, 237, 157, 8, 48, 67, 2, 209, 65, 38, + 138, 143, 149, 52, 11, 236, 179, 250, 6, 182, 125, 218, 133, 127, 72, 107, + 46, 158, 155, 112, 147, 253, 24, 202, 2, 226, 140, 32, 153, 179, 80, 46, + 175, 23, 17, 138, 12, 226, 251, 153, 122, 232, 68, 142, 1, 154, 112, 64, 26, + 62, 35, 172, 240, 250, 70, 111, 192, 3, 69, 205, 148, 184, 193, 90, 106, 8, + 151, 169, 178, 83, 251, 173, 72, 62, 38, 102, 126, 64, 104, 39, 241, 96, + 180, 123, 141, 115, 228, 0, 39, 6, 73, 249, 26, 30, 177, 152, 194, 201, 83, + 85, 211, 184, 211, 120, 167, 169, 17, 65, 67, 158, 202, 183, 112, 232, 163, + 184, 205, 115, 164, 117, 93, 176, 138, 74, 167, 162, 135, 199, 113, 225, + 104, 38, 31, 240, 177, 11, 88, 120, 45, 225, 88, 199, 4, 193, 164, 252, 212, + 172, 142, 248, 43, 130, 113, 134, 6, 6, 149, 65, 148, 58, 25, 128, 179, 25, + 234, 107, 28, 199, 84, 157, 100, 143, 8, 164, 146, 220, 252, 251, 101, 251, + 226, 117, 179, 241, 212, 108, 98, 175, 52, 23, 103, 222, 23, 213, 114, 235, + 17, 177, 239, 228, 60, 252, 176, 29, 47, 239, 255, 52, 200, 223, 213, 152, + 214, 165, 213, 123, 103, 11, 54, 49, 183, 8, 65, 57, 103, 226, 67, 46, 198, + 233, 45, 47, 188, 38, 45, 93, 64, 50, 142, 125, 83, 156, 210, 101, 74, 31, + 184, 74, 167, 158, 84, 128, 28, 187, 159, 110, 162, 120, 82, 209, 16, 141, + 175, 175, 241, 228, 30, 166, 200, 140, 105, 192, 36, 168, 126, 203, 174, + 251, 161, 176, 30, 146, 108, 98, 197, 33, 43, 169, 176, 86, 196, 172, 3, + 214, 104, 189, 241, 66, 95, 12, 237, 155, 224, 114, 95, 12, 22, 48, 4, 149, + 37, 231, 209, 171, 45, 248, 229, 222, 187, 243, 253, 170, 200, 8, 189, 127, + 69, 31, 141, 243, 15, 148, 102, 150, 187, 95, 111, 4, 115, 110, 196, 41, + 247, 116, 153, 171, 133, 227, 80, 132, 166, 66, 42, 96, 168, 120, 46, 157, + 179, 90, 72, 16, 216, 52, 174, 255, 232, 16, 59, 128, 202, 73, 217, 37, 28, + 18, 121, 214, 53, 139, 121, 236, 238, 186, 151, 68, 156, 191, 106, 146, 222, + 62, 94, 38, 11, 177, 243, 64, 206, 69, 142, 189, 10, 15, 39, 59, 104, 83, + 174, 114, 138, 94, 180, 203, 220, 87, 93, 71, 239, 164, 131, 144, 83, 62, + 143, 71, 115, 56, 76, 174, 1, 111, 43, 8, 151, 52, 236, 64, 69, 150, 170, + 189, 209, 221, 173, 211, 34, 74, 62, 18, 33, 219, 10, 215, 139, 154, 147, + 185, 221, 250, 225, 76, 42, 104, 125, 130, 55, 189, 136, 76, 92, 49, 233, 8, + 89, 88, 36, 33, 168, 154, 94, 172, 155, 1, 246, 65, 85, 87, 95, 109, 87, + 190, 237, 3, 146, 227, 59, 213, 62, 102, 208, 85, 73, 224, 37, 225, 59, 33, + 178, 18, 107, 66, 53, 75, 250, 166, 242, 56, 46, 92, 201, 1, 153, 88, 167, + 100, 86, 27, 89, 46, 240, 74, 60, 78, 121, 48, 186, 8, 218, 77, 215, 111, + 101, 227, 83, 144, 197, 253, 232, 173, 30, 113, 165, 188, 65, 221, 177, 105, + 41, 160, 186, 177, 193, 128, 106, 91, 25, 59, 114, 213, 110, 103, 140, 79, + 166, 55, 32, 128, 142, 214, 196, 80, 162, 113, 147, 250, 188, 184, 107, 153, + 16, 94, 3, 175, 214, 101, 88, 149, 166, 135, 11, 4, 91, 11, 78, 77, 196, 97, + 248, 218, 70, 71, 118, 78, 47, 253, 143, 113, 123, 255, 77, 122, 219, 153, + 181, 125, 168, 220, 187, 212, 204, 28, 93, 60, 1, 41, 170, 118, 40, 60, 173, + 210, 136, 189, 190, 61, 252, 168, 140, 93, 132, 97, 22, 82, 63, 86, 217, + 168, 116, 37, 57, 128, 12, 218, 228, 22, 176, 59, 152, 8, 11, 72, 185, 149, + 17, 58, 252, 160, 158, 178, 252, 195, 191, 107, 208, 130, 52, 234, 232, 180, + 208, 99, 247, 86, 12, 179, 106, 244, 60, 92, 193, 111, 35, 81, 47, 117, 201, + 34, 254, 108, 165, 121, 235, 201, 118, 139, 241, 252, 110, 158, 91, 212, + 177, 41, 49, 73, 168, 30, 143, 92, 60, 185, 46, 241, 219, 107, 144, 104, + 168, 132, 31, 0, 125, 71, 124, 213, 159, 66, 38, 7, 111, 140, 115, 222, 145, + 208, 201, 173, 152, 126, 177, 122, 119, 223, 209, 40, 172, 219, 105, 239, + 127, 60, 135, 147, 24, 96, 84, 90, 10, 152, 201, 229, 198, 90, 223, 85, 1, + 36, 52, 114, 48, 240, 231, 148, 34, 183, 98, 149, 148, 171, 231, 101, 235, + 245, 22, 87, 107, 254, 252, 42, 41, 159, 147, 20, 174, 84, 121, 197, 42, 47, + 25, 219, 122, 36, 251, 46, 197, 240, 31, 120, 20, 115, 226, 31, 186, 163, + 133, 216, 9, 204, 144, 7, 204, 85, 174, 24, 252, 181, 45, 223, 193, 22, 7, + 107, 201, 213, 115, 9, 208, 55, 180, 253, 185, 49, 11, 116, 252, 137, 133, + 127, 175, 163, 160, 80, 86, 86, 170, 210, 191, 157, 145, 61, 2, 232, 142, + 201, 6, 113, 29, 4, 30, 223, 248, 227, 231, 184, 129, 174, 213, 88, 192, + 127, 123, 152, 134, 168, 182, 91, 251, 221, 145, 212, 39, 56, 60, 253, 120, + 224, 151, 4, 194, 244, 149, 233, 75, 167, 166, 53, 115, 191, 172, 19, 142, + 174, 142, 77, 194, 153, 246, 140, 49, 162, 214, 119, 171, 123, 234, 180, 88, + 53, 254, 221, 98, 31, 24, 152, 161, 17, 32, 45, 11, 165, 237, 129, 16, 30, + 115, 238, 210, 53, 124, 111, 189, 28, 131, 172, 247, 251, 54, 98, 100, 43, + 32, 196, 26, 213, 145, 146, 200, 77, 255, 67, 180, 118, 118, 131, 154, 12, + 204, 39, 113, 22, 205, 163, 87, 10, 53, 7, 11, 148, 117, 201, 70, 193, 52, + 99, 194, 248, 73, 68, 140, 19, 88, 18, 17, 81, 22, 12, 56, 187, 151, 199, + 160, 30, 158, 36, 95, 136, 106, 121, 53, 40, 118, 254, 31, 46, 86, 25, 232, + 171, 119, 136, 183, 254, 69, 172, 169, 137, 255, 111, 97, 69, 140, 190, 38, + 243, 155, 228, 182, 74, 229, 228, 153, 238, 201, 156, 120, 139, 54, 207, 73, + 241, 179, 16, 117, 108, 168, 0, 205, 102, 144, 254, 120, 68, 142, 35, 140, + 203, 38, 202, 230, 0, 117, 177, 227, 180, 179, 72, 74, 133, 199, 148, 53, + 231, 221, 2, 58, 138, 130, 94, 5, 231, 5, 11, 239, 218, 27, 242, 28, 243, + 71, 211, 223, 118, 79, 158, 49, 99, 228, 199, 107, 178, 218, 195, 209, 142, + 123, 57, 208, 221, 31, 110, 106, 198, 211, 1, 141, 37, 20, 81, 155, 18, 234, + 241, 241, 239, 206, 57, 40, 119, 65, 39, 58, 41, 102, 181, 159, 108, 21, 55, + 42, 139, 116, 74, 194, 45, 190, 131, 119, 15, 80, 115, 53, 227, 11, 151, + 181, 242, 75, 35, 54, 214, 80, 167, 233, 109, 162, 122, 38, 18, 154, 202, + 217, 74, 95, 188, 167, 76, 144, 130, 160, 10, 243, 206, 31, 37, 205, 38, 71, + 229, 143, 176, 242, 44, 237, 93, 104, 187, 27, 86, 81, 4, 55, 91, 56, 17, + 32, 151, 25, 66, 75, 116, 146, 0, 140, 8, 36, 98, 240, 82, 33, 151, 121, 14, + 57, 62, 213, 252, 115, 59, 62, 189, 9, 115, 135, 124, 0, 191, 232, 236, 116, + 167, 65, 227, 106, 176, 205, 107, 42, 131, 41, 11, 17, 150, 28, 162, 194, + 174, 188, 22, 94, 42, 221, 30, 143, 41, 116, 214, 129, 7, 35, 25, 225, 225, + 167, 161, 112, 134, 139, 209, 213, 69, 66, 235, 72, 217, 140, 5, 165, 115, + 123, 201, 243, 157, 108, 61, 74, 239, 55, 52, 37, 16, 60, 215, 104, 192, + 253, 110, 47, 0, 23, 165, 120, 29, 183, 76, 144, 152, 213, 141, 130, 113, + 98, 121, 1, 182, 128, 116, 173, 53, 61, 59, 98, 207, 179, 35, 67, 228, 199, + 162, 151, 0, 195, 71, 90, 151, 193, 245, 54, 103, 103, 33, 154, 161, 188, + 201, 97, 106, 21, 76, 213, 111, 67, 120, 251, 114, 181, 15, 224, 96, 90, 1, + 108, 91, 189, 28, 254, 184, 246, 15, 48, 77, 207, 42, 104, 66, 23, 208, 135, + 240, 237, 135, 218, 196, 45, 96, 33, 9, 192, 237, 101, 181, 76, 190, 198, + 59, 135, 169, 88, 229, 30, 201, 231, 148, 219, 51, 100, 53, 97, 173, 178, + 67, 165, 159, 190, 86, 179, 247, 35, 97, 39, 69, 246, 93, 204, 170, 83, 33, + 196, 117, 166, 254, 194, 191, 66, 22, 241, 80, 136, 201, 83, 234, 198, 116, + 38, 180, 104, 15, 241, 94, 178, 158, 207, 105, 150, 249, 229, 38, 248, 162, + 227, 158, 228, 91, 11, 112, 224, 173, 152, 168, 60, 234, 138, 82, 231, 218, + 217, 46, 214, 74, 48, 9, 19, 153, 204, 83, 19, 168, 13, 24, 30, 225, 65, + 244, 98, 151, 118, 203, 110, 231, 233, 19, 153, 84, 65, 166, 148, 211, 213, + 241, 51, 112, 217, 158, 92, 126, 209, 168, 87, 12, 80, 62, 244, 91, 203, + 220, 199, 116, 241, 209, 251, 143, 184, 4, 126, 175, 1, 103, 24, 43, 175, + 157, 20, 10, 70, 19, 239, 159, 209, 33, 24, 75, 28, 227, 141, 133, 118, 13, + 170, 71, 81, 161, 238, 97, 79, 69, 49, 152, 203, 189, 2, 139, 213, 89, 119, + 124, 241, 110, 120, 19, 143, 246, 117, 164, 153, 49, 53, 63, 125, 75, 63, + 193, 238, 127, 231, 19, 107, 245, 1, 42, 86, 30, 139, 25, 149, 62, 230, 30, + 98, 48, 69, 96, 66, 153, 65, 162, 25, 41, 118, 196, 26, 211, 66, 193, 184, + 165, 221, 198, 95, 175, 42, 10, 132, 253, 59, 166, 208, 156, 59, 97, 110, + 15, 15, 173, 116, 42, 254, 151, 202, 209, 189, 60, 69, 167, 32, 233, 153, 4, + 139, 190, 92, 164, 164, 64, 149, 106, 70, 27, 233, 109, 50, 136, 62, 154, 5, + 214, 228, 132, 247, 187, 179, 34, 163, 65, 44, 30, 106, 4, 18, 72, 146, 19, + 83, 64, 68, 36, 122, 61, 140, 227, 82, 17, 228, 105, 105, 222, 52, 94, 132, + 8, 145, 132, 192, 185, 177, 172, 34, 153, 4, 98, 98, 42, 37, 189, 195, 71, + 185, 188, 203, 88, 232, 37, 106, 251, 104, 47, 211, 78, 193, 240, 73, 178, + 250, 226, 209, 98, 29, 225, 230, 201, 192, 185, 114, 82, 14, 81, 104, 79, + 226, 133, 248, 162, 150, 139, 149, 227, 79, 81, 74, 9, 197, 54, 124, 195, + 39, 63, 34, 195, 21, 205, 76, 91, 88, 174, 243, 178, 207, 86, 64, 178, 70, + 180, 5, 30, 134, 119, 188, 116, 38, 66, 227, 65, 174, 85, 251, 49, 103, 132, + 194, 23, 203, 207, 85, 28, 99, 8, 55, 246, 177, 63, 86, 186, 172, 171, 154, + 94, 177, 53, 159, 108, 8, 1, 108, 131, 147, 145, 126, 201, 50, 183, 89, 179, + 253, 235, 56, 93, 63, 82, 7, 45, 236, 57, 108, 185, 180, 136, 175, 64, 9, + 128, 173, 56, 125, 83, 55, 208, 179, 23, 114, 21, 71, 241, 128, 70, 92, 201, + 133, 50, 108, 15, 109, 254, 103, 44, 251, 65, 201, 199, 53, 207, 67, 93, 37, + 163, 189, 196, 106, 238, 4, 56, 246, 93, 22, 131, 190, 215, 81, 50, 71, 146, + 183, 200, 112, 157, 58, 229, 245, 138, 90, 117, 99, 209, 120, 55, 181, 79, + 141, 44, 226, 33, 164, 93, 206, 44, 101, 216, 175, 108, 191, 224, 54, 36, + 120, 112, 108, 226, 81, 178, 123, 219, 216, 135, 122, 191, 177, 207, 143, + 245, 99, 122, 135, 215, 154, 11, 80, 13, 128, 52, 92, 180, 113, 238, 64, + 156, 181, 47, 89, 111, 34, 135, 232, 1, 200, 253, 243, 250, 197, 199, 170, + 29, 244, 182, 0, 244, 211, 89, 248, 34, 26, 221, 161, 183, 228, 36, 51, 106, + 115, 162, 59, 3, 144, 150, 50, 125, 29, 250, 29, 167, 162, 106, 186, 195, + 236, 55, 240, 182, 4, 165, 167, 42, 204, 148, 192, 240, 5, 100, 154, 10, + 116, 158, 205, 187, 148, 162, 91, 207, 242, 245, 163, 160, 149, 169, 118, + 27, 125, 38, 16, 2, 152, 177, 235, 138, 105, 114, 119, 73, 189, 92, 146, 9, + 65, 206, 102, 246, 139, 113, 158, 56, 148, 191, 87, 59, 228, 126, 25, 245, + 63, 31, 131, 21, 4, 217, 170, 106, 127, 49, 48, 239, 72, 113, 22, 145, 87, + 129, 149, 79, 216, 72, 48, 8, 40, 133, 33, 109, 38, 142, 200, 91, 35, 246, + 27, 252, 230, 225, 152, 14, 117, 246, 198, 139, 56, 231, 47, 30, 44, 24, + 137, 224, 158, 72, 220, 34, 250, 17, 57, 23, 4, 226, 43, 139, 77, 209, 10, + 200, 38, 187, 141, 143, 235, 106, 44, 38, 107, 24, 235, 39, 183, 94, 186, + 54, 246, 242, 242, 207, 37, 200, 132, 62, 244, 76, 6, 112, 221, 160, 199, + 45, 65, 24, 74, 244, 135, 18, 76, 16, 172, 234, 72, 0, 119, 136, 28, 228, + 34, 134, 62, 143, 108, 86, 92, 238, 165, 250, 242, 153, 31, 253, 6, 92, 172, + 75, 199, 10, 5, 146, 115, 43, 237, 140, 191, 212, 155, 231, 35, 12, 190, 9, + 5, 224, 28, 204, 220, 233, 35, 57, 107, 140, 63, 108, 145, 193, 15, 252, + 134, 18, 20, 181, 97, 5, 241, 244, 165, 249, 176, 66, 187, 116, 233, 235, + 203, 51, 58, 28, 4, 58, 70, 137, 203, 143, 190, 247, 217, 236, 55, 32, 172, + 140, 70, 168, 209, 74, 102, 137, 76, 117, 130, 130, 70, 81, 196, 193, 230, + 143, 207, 24, 127, 109, 181, 226, 100, 135, 146, 118, 235, 251, 171, 211, + 54, 103, 47, 77, 238, 135, 230, 154, 151, 145, 96, 234, 169, 194, 178, 61, + 21, 103, 175, 112, 206, 164, 133, 19, 108, 150, 151, 54, 155, 116, 87, 243, + 75, 198, 140, 206, 28, 39, 238, 43, 211, 48, 51, 37, 191, 64, 190, 151, 122, + 229, 251, 62, 44, 81, 243, 217, 8, 188, 133, 24, 233, 78, 26, 121, 180, 40, + 245, 22, 183, 199, 183, 155, 63, 229, 37, 198, 124, 245, 42, 48, 64, 178, + 128, 109, 135, 152, 226, 86, 128, 244, 67, 192, 84, 211, 244, 134, 23, 166, + 49, 69, 104, 165, 152, 77, 34, 5, 50, 167, 104, 181, 153, 112, 229, 125, + 184, 212, 66, 218, 240, 59, 163, 105, 96, 26, 166, 103, 24, 201, 131, 66, + 21, 71, 44, 115, 241, 201, 210, 93, 190, 219, 30, 151, 100, 197, 2, 211, 81, + 73, 254, 132, 204, 51, 59, 156, 182, 147, 165, 159, 183, 127, 69, 9, 138, + 12, 152, 108, 220, 148, 183, 245, 157, 94, 68, 120, 122, 147, 94, 240, 186, + 201, 21, 161, 163, 58, 37, 251, 159, 219, 241, 191, 112, 76, 198, 100, 100, + 100, 20, 52, 198, 91, 10, 129, 139, 71, 78, 51, 2, 177, 234, 67, 13, 82, + 165, 236, 19, 148, 238, 42, 60, 128, 60, 231, 175, 142, 129, 89, 213, 180, + 3, 155, 50, 51, 65, 14, 210, 87, 109, 139, 80, 138, 239, 36, 129, 197, 23, + 106, 80, 202, 21, 218, 183, 48, 198, 46, 120, 63, 148, 144, 236, 135, 142, + 38, 125, 244, 42, 142, 187, 98, 140, 22, 129, 29, 110, 191, 223, 180, 36, + 71, 107, 155, 34, 228, 213, 158, 202, 193, 175, 95, 217, 150, 91, 57, 197, + 101, 118, 20, 79, 173, 233, 5, 115, 35, 96, 254, 185, 236, 57, 115, 93, 114, + 26, 215, 195, 4, 149, 100, 247, 226, 10, 92, 169, 105, 12, 219, 94, 26, 229, + 21, 169, 55, 103, 31, 7, 47, 18, 142, 223, 171, 176, 235, 142, 10, 197, 138, + 89, 211, 28, 127, 96, 111, 86, 121, 220, 77, 174, 84, 227, 86, 182, 159, 13, + 141, 205, 11, 35, 177, 163, 94, 234, 246, 156, 154, 56, 85, 185, 251, 181, + 49, 15, 212, 74, 94, 65, 178, 8, 12, 1, 179, 175, 138, 232, 151, 78, 84, + 168, 146, 195, 140, 128, 241, 110, 32, 197, 141, 162, 37, 117, 82, 93, 166, + 105, 9, 20, 69, 112, 85, 62, 63, 126, 244, 178, 127, 59, 51, 19, 222, 167, + 229, 203, 30, 46, 105, 10, 163, 90, 97, 140, 140, 224, 99, 37, 74, 98, 219, + 130, 61, 126, 68, 43, 153, 178, 78, 177, 91, 187, 46, 225, 220, 215, 175, 1, + 137, 217, 40, 205, 47, 163, 179, 98, 81, 46, 169, 194, 25, 34, 169, 33, 143, + 24, 120, 98, 149, 147, 7, 115, 20, 65, 230, 143, 249, 82, 140, 80, 37, 205, + 230, 239, 117, 34, 174, 55, 191, 131, 22, 213, 205, 112, 92, 168, 243, 131, + 110, 227, 218, 103, 194, 57, 156, 120, 252, 116, 233, 170, 75, 55, 148, 154, + 34, 89, 220, 101, 60, 195, 152, 252, 43, 170, 250, 119, 243, 21, 139, 195, + 173, 6, 78, 244, 195, 149, 73, 87, 239, 71, 117, 80, 24, 69, 33, 149, 59, + 207, 50, 38, 243, 99, 147, 243, 72, 113, 51, 86, 80, 150, 84, 230, 64, 236, + 122, 167, 84, 29, 219, 235, 59, 245, 148, 177, 68, 4, 120, 243, 32, 157, + 239, 194, 2, 255, 83, 0, 8, 23, 40, 101, 134, 137, 145, 169, 172, 179, 188, + 4, 94, 112, 169, 11, 26, 97, 114, 236, 239, 14, 32, 176, 178, 181, 186, 13, + 37, 87, 91, 120, 231, 10, 38, 91, 164, 173, 186, 187, 230, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 11, 15, 21, 27, 33, 41, + ]), + 'ML-DSA-87': new Uint8Array([ + 114, 160, 86, 137, 42, 198, 166, 136, 233, 153, 38, 105, 246, 197, 97, 186, + 174, 108, 5, 66, 156, 228, 140, 34, 160, 168, 237, 59, 225, 85, 25, 2, 166, + 159, 149, 14, 43, 42, 188, 97, 94, 94, 209, 66, 7, 67, 27, 106, 33, 26, 223, + 95, 136, 41, 37, 24, 76, 91, 73, 22, 74, 29, 71, 38, 136, 51, 11, 169, 162, + 187, 9, 166, 202, 84, 196, 51, 243, 233, 146, 71, 56, 9, 156, 20, 119, 182, + 187, 115, 228, 13, 237, 77, 99, 100, 219, 127, 64, 62, 149, 231, 36, 52, 77, + 48, 182, 182, 172, 173, 182, 8, 78, 174, 180, 50, 14, 246, 200, 12, 17, 9, + 165, 219, 139, 215, 126, 24, 104, 147, 92, 43, 204, 188, 233, 28, 7, 165, + 14, 173, 210, 184, 99, 196, 139, 226, 96, 120, 177, 156, 133, 151, 32, 112, + 198, 113, 87, 246, 190, 29, 253, 31, 66, 42, 78, 35, 96, 196, 213, 150, 22, + 109, 201, 27, 23, 65, 63, 93, 120, 204, 123, 229, 30, 205, 226, 35, 74, 176, + 21, 34, 225, 38, 63, 131, 159, 203, 76, 26, 113, 104, 72, 110, 181, 234, + 202, 154, 172, 168, 247, 97, 156, 224, 20, 236, 190, 106, 127, 56, 197, 66, + 236, 92, 92, 134, 150, 14, 218, 213, 214, 18, 237, 99, 102, 31, 133, 13, + 203, 63, 59, 157, 144, 182, 250, 105, 59, 48, 52, 146, 208, 100, 117, 220, + 81, 60, 106, 79, 10, 147, 163, 160, 193, 110, 154, 237, 81, 137, 202, 70, + 80, 102, 59, 34, 223, 150, 99, 112, 55, 233, 79, 8, 247, 246, 181, 175, 201, + 12, 253, 226, 30, 162, 233, 23, 124, 129, 150, 78, 52, 99, 228, 217, 33, + 251, 29, 45, 138, 207, 245, 51, 44, 246, 230, 149, 163, 131, 251, 118, 44, + 111, 53, 87, 20, 193, 65, 59, 118, 96, 96, 4, 33, 136, 136, 179, 248, 25, + 196, 224, 51, 190, 37, 155, 245, 151, 9, 45, 215, 160, 104, 38, 76, 19, 172, + 11, 167, 253, 249, 105, 7, 244, 13, 82, 91, 123, 93, 134, 247, 201, 78, 35, + 231, 130, 56, 171, 221, 138, 227, 40, 170, 56, 169, 200, 232, 8, 167, 168, + 66, 0, 241, 252, 48, 185, 0, 255, 230, 91, 124, 210, 247, 241, 225, 236, 37, + 130, 218, 21, 89, 100, 68, 142, 116, 253, 152, 178, 42, 207, 218, 147, 18, + 76, 193, 115, 102, 47, 59, 116, 110, 57, 15, 142, 176, 48, 144, 79, 10, 232, + 239, 128, 180, 202, 7, 182, 100, 106, 96, 81, 210, 154, 214, 171, 96, 132, + 103, 50, 48, 116, 217, 192, 159, 10, 45, 36, 22, 173, 225, 92, 43, 18, 4, + 122, 185, 137, 245, 175, 159, 125, 111, 196, 40, 201, 28, 185, 174, 227, + 132, 205, 81, 50, 205, 124, 55, 75, 150, 127, 250, 114, 68, 224, 65, 160, + 149, 171, 7, 130, 44, 179, 157, 13, 156, 35, 77, 68, 184, 204, 245, 219, + 203, 13, 47, 140, 171, 105, 202, 138, 131, 72, 226, 70, 98, 100, 247, 31, + 31, 68, 185, 40, 55, 0, 68, 42, 102, 111, 141, 179, 78, 207, 142, 149, 142, + 248, 191, 152, 7, 191, 180, 58, 147, 68, 158, 50, 131, 98, 17, 88, 128, 71, + 223, 145, 238, 177, 172, 61, 17, 45, 178, 232, 217, 161, 51, 197, 220, 196, + 57, 80, 2, 241, 197, 107, 113, 133, 176, 221, 68, 74, 25, 223, 24, 227, 112, + 135, 51, 56, 129, 223, 43, 53, 25, 226, 209, 243, 99, 208, 247, 193, 93, 52, + 173, 159, 253, 197, 2, 70, 43, 163, 116, 74, 40, 195, 98, 233, 34, 90, 90, + 232, 27, 39, 94, 191, 9, 16, 88, 194, 250, 75, 212, 63, 73, 216, 134, 35, + 126, 13, 120, 3, 193, 173, 61, 193, 185, 72, 67, 88, 67, 64, 167, 161, 43, + 144, 28, 80, 92, 193, 75, 246, 102, 200, 224, 71, 250, 195, 219, 110, 149, + 89, 169, 64, 9, 169, 109, 140, 132, 151, 5, 49, 231, 243, 167, 198, 11, 88, + 109, 97, 90, 144, 171, 124, 145, 122, 82, 108, 133, 4, 189, 205, 21, 218, + 110, 70, 199, 137, 241, 98, 243, 157, 124, 65, 216, 195, 40, 158, 41, 135, + 227, 12, 233, 182, 195, 8, 18, 245, 222, 176, 31, 63, 168, 246, 124, 253, + 83, 33, 185, 128, 125, 215, 130, 49, 228, 157, 126, 78, 142, 72, 150, 220, + 102, 153, 161, 38, 254, 169, 174, 191, 66, 59, 151, 28, 126, 86, 205, 71, 0, + 133, 87, 188, 172, 227, 147, 133, 100, 104, 111, 192, 97, 170, 6, 253, 37, + 121, 103, 251, 155, 86, 139, 127, 53, 72, 151, 172, 69, 231, 115, 153, 253, + 212, 13, 202, 120, 126, 110, 144, 130, 198, 190, 5, 151, 56, 161, 252, 235, + 48, 119, 188, 129, 157, 215, 82, 157, 254, 187, 180, 177, 138, 73, 153, 101, + 158, 102, 144, 170, 240, 248, 251, 77, 181, 227, 163, 60, 129, 249, 68, 235, + 70, 74, 117, 161, 231, 47, 123, 186, 84, 33, 139, 193, 120, 75, 63, 218, 4, + 194, 116, 0, 189, 29, 135, 104, 249, 196, 168, 102, 47, 143, 38, 25, 156, + 27, 250, 75, 3, 102, 38, 118, 180, 92, 172, 251, 200, 202, 42, 112, 154, + 105, 203, 133, 108, 170, 10, 23, 139, 205, 111, 124, 190, 44, 11, 197, 6, + 220, 121, 230, 71, 236, 77, 110, 133, 205, 140, 255, 246, 222, 195, 24, 188, + 66, 79, 142, 101, 195, 127, 40, 243, 26, 177, 253, 242, 32, 203, 166, 37, + 60, 32, 210, 71, 252, 103, 135, 99, 153, 126, 156, 131, 48, 132, 183, 85, + 130, 59, 165, 206, 5, 107, 77, 82, 129, 70, 166, 121, 165, 154, 196, 202, + 113, 216, 239, 176, 142, 62, 149, 87, 185, 162, 93, 179, 99, 71, 2, 81, 236, + 153, 235, 31, 185, 29, 215, 212, 46, 255, 245, 173, 223, 96, 107, 192, 75, + 197, 157, 206, 121, 32, 89, 11, 149, 7, 37, 57, 228, 76, 163, 104, 182, 196, + 189, 147, 59, 181, 149, 54, 23, 146, 131, 115, 168, 48, 197, 84, 33, 36, + 251, 41, 130, 61, 79, 154, 87, 181, 51, 208, 254, 220, 210, 82, 189, 63, 84, + 118, 191, 101, 246, 220, 219, 183, 127, 186, 2, 181, 24, 183, 97, 37, 50, 1, + 136, 233, 59, 183, 154, 44, 195, 139, 30, 76, 191, 218, 0, 116, 225, 92, 8, + 5, 193, 131, 74, 234, 5, 89, 186, 156, 8, 234, 112, 3, 233, 177, 191, 40, + 240, 204, 179, 8, 27, 55, 240, 12, 175, 176, 75, 65, 63, 94, 23, 44, 39, + 103, 115, 54, 244, 33, 20, 51, 114, 87, 129, 249, 107, 66, 170, 90, 242, + 207, 237, 62, 235, 60, 121, 98, 248, 145, 159, 171, 184, 175, 22, 42, 116, + 83, 207, 92, 178, 208, 138, 26, 102, 211, 102, 51, 184, 185, 175, 121, 26, + 40, 124, 83, 226, 89, 63, 156, 92, 118, 101, 75, 8, 87, 93, 237, 119, 76, + 167, 89, 111, 187, 211, 168, 243, 182, 158, 134, 5, 223, 140, 100, 67, 100, + 15, 244, 170, 38, 123, 155, 111, 166, 43, 184, 216, 83, 72, 177, 227, 246, + 204, 82, 141, 192, 169, 127, 87, 65, 43, 5, 163, 212, 39, 90, 122, 35, 106, + 181, 202, 122, 198, 255, 134, 209, 240, 254, 235, 255, 103, 14, 175, 189, + 184, 159, 180, 178, 36, 188, 123, 187, 224, 117, 22, 95, 162, 162, 162, 188, + 173, 48, 136, 8, 115, 151, 31, 35, 88, 252, 85, 149, 176, 232, 28, 130, 205, + 5, 154, 106, 108, 13, 169, 236, 38, 43, 124, 167, 26, 174, 119, 101, 86, + 215, 5, 176, 92, 160, 50, 247, 216, 211, 110, 107, 162, 243, 46, 165, 46, + 59, 204, 104, 122, 103, 192, 183, 119, 226, 74, 249, 158, 203, 1, 153, 10, + 202, 14, 249, 89, 88, 54, 82, 119, 136, 110, 20, 175, 169, 163, 183, 248, + 225, 72, 212, 90, 239, 254, 62, 113, 223, 13, 218, 11, 250, 146, 247, 96, + 51, 5, 206, 81, 215, 252, 146, 246, 46, 28, 77, 196, 160, 251, 228, 118, 3, + 198, 54, 205, 59, 50, 156, 172, 0, 209, 14, 152, 91, 200, 191, 115, 124, 8, + 20, 184, 82, 168, 236, 0, 249, 151, 164, 106, 36, 13, 37, 208, 53, 3, 159, + 96, 68, 221, 177, 105, 110, 152, 214, 234, 156, 16, 94, 180, 99, 165, 130, + 110, 207, 147, 218, 151, 77, 241, 22, 0, 221, 148, 171, 229, 13, 228, 43, + 121, 167, 210, 50, 108, 206, 154, 159, 229, 236, 12, 245, 55, 204, 127, 2, + 114, 186, 70, 191, 183, 3, 148, 131, 102, 238, 155, 38, 230, 102, 127, 241, + 111, 246, 93, 16, 191, 195, 163, 130, 220, 103, 28, 93, 94, 15, 181, 83, 5, + 110, 75, 45, 96, 18, 83, 109, 72, 92, 201, 121, 124, 30, 88, 221, 13, 234, + 219, 68, 93, 22, 63, 170, 106, 107, 199, 160, 143, 195, 196, 203, 46, 13, + 223, 65, 51, 24, 200, 3, 72, 227, 144, 54, 146, 123, 211, 37, 29, 161, 220, + 6, 113, 115, 91, 137, 252, 146, 237, 45, 156, 93, 79, 152, 23, 238, 6, 126, + 237, 170, 40, 232, 252, 229, 87, 194, 216, 5, 183, 122, 63, 213, 120, 139, + 162, 91, 55, 27, 237, 148, 250, 225, 225, 236, 121, 19, 63, 207, 63, 7, 187, + 248, 78, 39, 79, 58, 113, 151, 147, 152, 124, 193, 51, 164, 102, 101, 13, + 158, 230, 31, 152, 65, 93, 123, 53, 129, 224, 253, 201, 219, 138, 120, 63, + 46, 214, 253, 189, 165, 129, 182, 58, 106, 118, 23, 148, 228, 30, 88, 210, + 129, 116, 73, 107, 215, 51, 248, 9, 48, 94, 50, 16, 165, 76, 85, 97, 182, + 157, 57, 207, 105, 12, 124, 194, 47, 24, 89, 155, 68, 144, 52, 134, 53, 168, + 240, 129, 206, 42, 249, 120, 142, 47, 67, 198, 230, 185, 21, 132, 57, 212, + 244, 58, 3, 48, 182, 212, 168, 51, 241, 77, 164, 236, 71, 195, 26, 162, 5, + 251, 237, 175, 43, 241, 70, 38, 112, 204, 97, 248, 235, 163, 36, 158, 185, + 52, 236, 87, 70, 12, 228, 89, 54, 60, 205, 53, 110, 77, 114, 127, 2, 207, + 224, 21, 130, 193, 112, 134, 10, 82, 28, 26, 57, 107, 62, 29, 144, 214, 41, + 206, 246, 169, 168, 66, 84, 77, 239, 177, 13, 61, 153, 100, 216, 163, 91, + 95, 97, 59, 163, 222, 181, 207, 12, 207, 241, 60, 128, 12, 89, 73, 36, 253, + 86, 54, 31, 226, 7, 19, 127, 208, 169, 95, 171, 9, 133, 39, 15, 48, 186, + 149, 227, 243, 175, 91, 116, 165, 50, 157, 68, 122, 186, 234, 109, 45, 230, + 131, 119, 154, 67, 131, 172, 162, 140, 210, 102, 30, 98, 43, 28, 147, 63, + 244, 168, 163, 100, 218, 94, 57, 222, 107, 186, 235, 38, 133, 205, 104, 80, + 94, 184, 147, 106, 50, 98, 212, 182, 85, 64, 32, 60, 177, 48, 5, 173, 132, + 215, 178, 168, 157, 250, 238, 159, 153, 101, 183, 21, 194, 232, 145, 210, + 141, 180, 37, 40, 115, 236, 23, 164, 230, 1, 86, 210, 87, 91, 110, 195, 171, + 243, 180, 177, 236, 187, 60, 168, 126, 106, 234, 166, 236, 160, 165, 208, + 89, 237, 53, 68, 129, 229, 17, 97, 162, 65, 68, 222, 243, 208, 3, 153, 129, + 47, 131, 205, 121, 216, 115, 237, 54, 137, 189, 249, 203, 243, 56, 201, 181, + 193, 145, 41, 224, 222, 94, 161, 168, 91, 85, 249, 36, 244, 65, 136, 31, + 212, 25, 27, 87, 242, 189, 22, 59, 15, 107, 53, 168, 92, 254, 12, 172, 12, + 131, 11, 7, 242, 127, 129, 34, 88, 14, 243, 207, 112, 228, 144, 242, 9, 242, + 188, 31, 238, 194, 101, 6, 189, 144, 13, 107, 108, 135, 179, 238, 19, 21, + 91, 80, 229, 36, 85, 213, 35, 243, 138, 203, 206, 128, 233, 226, 4, 178, 16, + 46, 128, 17, 174, 72, 201, 95, 6, 185, 186, 11, 124, 206, 82, 64, 25, 224, + 116, 151, 211, 55, 193, 10, 242, 145, 131, 219, 205, 146, 244, 106, 204, 38, + 50, 218, 22, 8, 132, 31, 225, 123, 221, 181, 213, 139, 34, 117, 152, 23, + 147, 166, 30, 0, 97, 173, 173, 9, 58, 250, 128, 230, 134, 9, 70, 104, 178, + 235, 232, 121, 8, 156, 245, 213, 10, 238, 136, 105, 93, 167, 120, 144, 40, + 148, 23, 243, 111, 220, 120, 222, 93, 81, 163, 48, 131, 192, 146, 191, 234, + 228, 232, 239, 95, 57, 92, 4, 77, 86, 238, 191, 81, 56, 100, 172, 114, 7, + 108, 68, 8, 187, 128, 115, 51, 113, 130, 247, 236, 167, 223, 48, 122, 142, + 57, 118, 15, 223, 147, 244, 145, 122, 59, 10, 65, 132, 0, 212, 169, 16, 115, + 161, 216, 88, 44, 231, 82, 70, 126, 49, 116, 187, 49, 71, 199, 55, 94, 249, + 152, 7, 225, 193, 189, 130, 192, 58, 54, 149, 146, 79, 149, 3, 211, 171, + 196, 127, 22, 75, 18, 228, 179, 166, 13, 40, 133, 152, 195, 37, 194, 100, + 70, 120, 6, 171, 62, 130, 230, 129, 234, 74, 114, 18, 44, 87, 164, 200, 179, + 167, 221, 168, 135, 130, 80, 185, 185, 108, 138, 79, 27, 41, 208, 90, 49, + 165, 46, 236, 89, 33, 208, 73, 118, 66, 231, 78, 18, 84, 27, 122, 84, 255, + 44, 213, 93, 118, 12, 237, 186, 251, 209, 48, 25, 14, 167, 151, 33, 126, + 210, 67, 9, 145, 219, 163, 153, 75, 40, 65, 118, 252, 191, 14, 108, 149, 8, + 26, 168, 63, 225, 25, 69, 218, 2, 189, 195, 133, 195, 128, 178, 147, 119, + 69, 69, 68, 130, 12, 141, 153, 250, 99, 93, 2, 138, 207, 6, 99, 85, 68, 192, + 140, 126, 211, 111, 10, 251, 54, 101, 170, 192, 240, 201, 116, 69, 43, 190, + 184, 230, 22, 243, 87, 87, 196, 238, 157, 185, 159, 54, 223, 185, 106, 116, + 81, 177, 89, 103, 194, 16, 181, 220, 124, 84, 189, 117, 24, 7, 110, 62, 129, + 129, 60, 9, 69, 26, 118, 198, 224, 126, 166, 130, 52, 27, 187, 216, 35, 107, + 74, 58, 60, 87, 77, 109, 243, 174, 137, 234, 173, 141, 16, 64, 17, 47, 173, + 84, 28, 47, 50, 103, 19, 190, 193, 168, 102, 152, 228, 234, 233, 61, 236, + 18, 25, 155, 152, 229, 45, 224, 182, 163, 232, 125, 205, 58, 199, 200, 28, + 203, 120, 249, 61, 54, 9, 94, 120, 191, 141, 71, 146, 25, 239, 194, 26, 225, + 186, 239, 37, 98, 0, 79, 152, 189, 67, 38, 80, 56, 165, 129, 18, 196, 86, + 33, 60, 82, 107, 252, 174, 158, 76, 116, 13, 30, 240, 79, 117, 71, 85, 85, + 154, 226, 46, 129, 63, 237, 152, 122, 118, 229, 161, 238, 236, 85, 18, 220, + 118, 87, 165, 100, 115, 196, 53, 49, 248, 101, 149, 106, 153, 32, 10, 178, + 55, 40, 245, 112, 187, 140, 158, 176, 151, 40, 139, 243, 170, 208, 56, 54, + 1, 50, 73, 94, 251, 133, 22, 97, 176, 106, 72, 17, 165, 28, 173, 48, 20, 42, + 80, 116, 46, 196, 195, 250, 92, 17, 127, 75, 186, 105, 231, 95, 160, 47, + 188, 136, 211, 196, 127, 158, 134, 204, 224, 91, 174, 250, 145, 182, 191, + 82, 213, 12, 192, 44, 110, 72, 192, 132, 197, 214, 102, 1, 222, 124, 196, + 213, 196, 121, 19, 46, 41, 92, 232, 236, 51, 96, 131, 235, 194, 84, 122, 89, + 148, 212, 12, 126, 248, 160, 159, 149, 247, 198, 6, 62, 51, 2, 251, 250, 36, + 116, 239, 161, 93, 239, 240, 140, 1, 43, 197, 196, 74, 242, 102, 243, 94, + 149, 26, 106, 209, 23, 96, 187, 67, 32, 172, 119, 2, 209, 83, 64, 223, 147, + 18, 88, 2, 156, 229, 5, 148, 111, 91, 179, 93, 196, 62, 41, 230, 16, 16, + 232, 198, 116, 227, 112, 238, 85, 103, 217, 85, 188, 231, 121, 13, 219, 16, + 77, 173, 165, 124, 57, 21, 33, 172, 153, 176, 179, 83, 97, 252, 245, 146, + 176, 160, 218, 38, 122, 93, 51, 48, 195, 89, 58, 1, 196, 211, 139, 224, 91, + 77, 122, 89, 162, 188, 73, 179, 167, 237, 243, 91, 44, 197, 70, 225, 199, + 158, 95, 104, 72, 200, 48, 168, 186, 197, 201, 219, 27, 149, 83, 52, 78, 62, + 30, 130, 35, 205, 183, 15, 61, 18, 71, 140, 233, 164, 169, 102, 91, 160, + 196, 222, 171, 172, 136, 24, 231, 152, 41, 139, 173, 127, 35, 179, 167, 9, + 103, 226, 237, 216, 99, 199, 12, 248, 17, 236, 250, 32, 16, 207, 68, 222, + 224, 124, 242, 99, 244, 186, 56, 199, 158, 40, 79, 225, 107, 14, 54, 32, + 183, 8, 107, 130, 4, 32, 161, 200, 72, 214, 175, 107, 63, 243, 133, 213, + 210, 77, 107, 166, 133, 230, 4, 105, 146, 201, 199, 201, 171, 148, 217, 5, + 170, 171, 200, 227, 234, 238, 81, 99, 39, 103, 214, 109, 103, 15, 97, 199, + 208, 64, 168, 62, 52, 143, 242, 173, 20, 138, 42, 253, 33, 31, 44, 252, 240, + 31, 199, 151, 228, 63, 220, 221, 238, 201, 151, 239, 34, 63, 71, 5, 151, + 190, 185, 167, 97, 117, 119, 3, 114, 93, 8, 228, 191, 228, 183, 104, 61, + 236, 176, 141, 98, 184, 148, 207, 210, 54, 186, 139, 118, 200, 160, 228, + 179, 70, 220, 167, 157, 187, 144, 186, 128, 51, 62, 125, 13, 170, 207, 229, + 77, 56, 173, 140, 190, 35, 68, 116, 99, 67, 113, 230, 32, 83, 208, 91, 72, + 115, 7, 225, 109, 80, 234, 225, 213, 115, 156, 166, 179, 37, 107, 49, 100, + 181, 203, 156, 228, 29, 91, 227, 141, 166, 243, 234, 180, 108, 127, 218, 90, + 7, 39, 131, 98, 104, 230, 143, 178, 193, 165, 203, 12, 153, 239, 197, 31, + 195, 189, 62, 247, 228, 77, 30, 0, 141, 153, 215, 64, 188, 240, 62, 208, + 243, 189, 31, 9, 129, 14, 26, 144, 99, 113, 247, 223, 113, 224, 175, 135, + 135, 64, 82, 15, 177, 24, 254, 89, 182, 230, 121, 25, 89, 181, 239, 236, 40, + 88, 61, 146, 96, 139, 94, 81, 82, 136, 10, 202, 177, 119, 154, 247, 74, 65, + 99, 119, 166, 106, 9, 227, 101, 167, 93, 37, 221, 106, 84, 214, 239, 138, + 202, 82, 201, 222, 222, 177, 3, 227, 175, 115, 193, 22, 132, 0, 151, 212, + 168, 128, 200, 148, 211, 205, 71, 67, 15, 246, 96, 20, 49, 161, 24, 82, 84, + 222, 74, 56, 116, 126, 249, 71, 45, 191, 52, 222, 6, 180, 43, 149, 240, 90, + 24, 28, 196, 237, 104, 58, 201, 115, 126, 237, 201, 191, 33, 44, 47, 45, + 254, 188, 16, 107, 58, 198, 134, 3, 200, 130, 53, 121, 215, 172, 176, 70, + 201, 141, 6, 23, 17, 193, 44, 11, 47, 207, 140, 209, 248, 147, 80, 86, 150, + 43, 119, 90, 162, 83, 221, 221, 103, 241, 138, 58, 74, 91, 45, 119, 236, + 146, 119, 63, 242, 164, 146, 200, 138, 158, 87, 10, 168, 1, 60, 228, 84, + 238, 83, 181, 170, 97, 185, 58, 221, 171, 202, 118, 104, 20, 233, 117, 153, + 228, 206, 129, 149, 180, 134, 85, 15, 142, 173, 108, 117, 21, 8, 164, 189, + 254, 106, 135, 243, 212, 220, 93, 107, 207, 243, 233, 69, 164, 31, 73, 73, + 186, 136, 155, 47, 216, 165, 178, 105, 219, 193, 144, 217, 242, 216, 25, 96, + 108, 16, 80, 122, 233, 97, 111, 137, 21, 96, 189, 67, 135, 249, 102, 225, + 179, 206, 193, 156, 136, 188, 1, 118, 146, 143, 183, 208, 140, 136, 171, + 143, 26, 234, 117, 119, 7, 198, 184, 147, 113, 216, 186, 67, 43, 164, 151, + 110, 102, 45, 70, 15, 168, 235, 252, 160, 89, 4, 247, 85, 14, 5, 58, 56, + 176, 146, 48, 162, 180, 76, 4, 229, 1, 50, 254, 155, 199, 46, 174, 39, 231, + 34, 111, 137, 6, 250, 18, 53, 48, 210, 228, 177, 110, 251, 101, 69, 199, + 226, 77, 203, 162, 40, 215, 9, 59, 102, 43, 4, 228, 196, 150, 81, 93, 183, + 222, 156, 188, 15, 64, 182, 197, 204, 124, 84, 0, 151, 152, 212, 31, 159, + 21, 132, 89, 230, 97, 178, 153, 209, 116, 170, 62, 215, 171, 102, 27, 4, + 236, 28, 240, 120, 245, 97, 134, 196, 200, 34, 44, 153, 162, 156, 57, 25, + 30, 35, 244, 205, 16, 224, 131, 216, 185, 116, 199, 16, 220, 25, 20, 53, + 116, 133, 146, 48, 152, 251, 180, 55, 42, 251, 229, 128, 140, 53, 80, 18, + 131, 20, 186, 150, 101, 165, 96, 139, 131, 22, 230, 38, 39, 95, 226, 103, + 210, 105, 180, 92, 134, 176, 16, 169, 34, 236, 141, 28, 31, 249, 151, 93, + 25, 90, 128, 161, 115, 193, 46, 70, 186, 120, 119, 208, 99, 40, 193, 218, + 155, 118, 72, 137, 170, 245, 32, 32, 3, 138, 58, 174, 208, 193, 81, 33, 120, + 224, 161, 46, 143, 235, 125, 191, 75, 13, 23, 115, 67, 211, 64, 208, 94, + 227, 236, 208, 121, 79, 75, 49, 209, 193, 162, 202, 92, 87, 200, 114, 90, + 153, 84, 99, 224, 8, 132, 56, 245, 171, 123, 125, 110, 253, 186, 79, 196, + 193, 180, 88, 213, 68, 63, 84, 208, 2, 156, 100, 240, 98, 32, 237, 239, 211, + 10, 50, 88, 17, 157, 207, 236, 152, 255, 164, 107, 126, 237, 195, 114, 88, + 160, 165, 38, 69, 89, 25, 35, 131, 12, 11, 249, 100, 143, 251, 47, 8, 96, + 122, 80, 35, 156, 173, 192, 87, 76, 140, 61, 45, 253, 17, 101, 129, 30, 25, + 183, 150, 84, 45, 37, 48, 149, 22, 212, 188, 103, 33, 85, 159, 21, 135, 104, + 41, 112, 155, 31, 23, 37, 241, 163, 187, 195, 184, 204, 116, 109, 231, 68, + 120, 226, 250, 76, 201, 87, 95, 126, 9, 85, 138, 27, 175, 0, 38, 197, 23, + 18, 82, 53, 65, 165, 31, 73, 86, 42, 43, 167, 24, 195, 163, 159, 130, 81, + 123, 74, 34, 202, 145, 27, 173, 174, 132, 179, 61, 90, 58, 127, 94, 29, 249, + 240, 219, 74, 52, 19, 131, 228, 29, 50, 209, 68, 158, 230, 155, 119, 129, + 169, 190, 182, 10, 148, 212, 155, 75, 65, 189, 63, 230, 103, 223, 169, 181, + 125, 229, 69, 240, 52, 241, 13, 33, 197, 32, 208, 154, 242, 31, 110, 88, 72, + 92, 20, 165, 83, 204, 34, 56, 142, 206, 38, 61, 115, 246, 195, 80, 98, 137, + 51, 109, 83, 24, 141, 32, 47, 94, 58, 1, 63, 45, 157, 183, 245, 204, 168, + 235, 188, 171, 84, 33, 186, 8, 155, 115, 119, 99, 144, 102, 112, 73, 181, + 25, 38, 23, 242, 138, 8, 218, 34, 161, 184, 115, 83, 4, 219, 206, 24, 213, + 249, 84, 159, 7, 26, 128, 250, 133, 56, 106, 197, 114, 172, 248, 35, 152, + 190, 45, 6, 6, 190, 227, 163, 77, 85, 12, 79, 14, 237, 2, 245, 245, 102, 99, + 43, 80, 144, 253, 81, 189, 237, 176, 151, 74, 72, 243, 201, 192, 140, 159, + 186, 218, 215, 10, 159, 11, 206, 203, 135, 175, 95, 98, 207, 29, 169, 87, + 65, 16, 188, 246, 198, 235, 127, 206, 108, 185, 55, 134, 243, 118, 230, 82, + 104, 35, 88, 53, 206, 171, 142, 121, 225, 217, 192, 169, 180, 219, 174, 158, + 60, 237, 250, 241, 48, 112, 214, 81, 184, 7, 29, 146, 83, 235, 116, 222, 72, + 217, 231, 148, 199, 121, 15, 59, 136, 127, 89, 126, 75, 110, 119, 112, 56, + 123, 245, 70, 156, 255, 111, 208, 142, 163, 250, 241, 133, 161, 216, 199, + 47, 65, 191, 79, 63, 90, 45, 161, 190, 250, 239, 97, 27, 222, 104, 96, 191, + 238, 77, 60, 74, 45, 114, 46, 60, 247, 142, 228, 134, 202, 67, 101, 255, 31, + 124, 187, 140, 200, 145, 21, 252, 204, 18, 136, 224, 124, 132, 132, 226, 56, + 95, 246, 135, 209, 173, 140, 251, 246, 71, 244, 93, 223, 229, 253, 14, 167, + 153, 119, 36, 57, 9, 155, 13, 199, 181, 238, 231, 173, 209, 38, 65, 251, 31, + 237, 70, 234, 110, 84, 93, 58, 158, 56, 238, 205, 240, 85, 52, 140, 124, 95, + 87, 109, 0, 11, 99, 169, 208, 123, 134, 178, 195, 19, 45, 62, 107, 221, 206, + 173, 66, 149, 213, 66, 94, 29, 166, 171, 150, 52, 110, 3, 205, 160, 247, + 205, 27, 203, 136, 246, 157, 146, 232, 73, 250, 255, 232, 213, 239, 64, 41, + 240, 230, 244, 32, 183, 86, 91, 7, 34, 61, 156, 236, 163, 207, 151, 110, + 237, 21, 13, 118, 218, 6, 62, 49, 185, 100, 116, 28, 167, 131, 152, 171, 36, + 167, 159, 181, 65, 48, 37, 92, 130, 148, 240, 140, 108, 27, 76, 84, 169, + 128, 59, 83, 147, 76, 204, 102, 41, 103, 255, 90, 108, 251, 162, 223, 130, + 216, 144, 17, 59, 124, 187, 9, 207, 234, 77, 165, 180, 81, 75, 18, 0, 22, + 148, 4, 87, 51, 149, 116, 7, 152, 153, 240, 178, 168, 106, 255, 237, 73, + 253, 58, 133, 183, 151, 186, 209, 102, 110, 91, 38, 106, 249, 171, 4, 170, + 174, 204, 88, 190, 46, 77, 233, 137, 9, 213, 85, 131, 189, 59, 47, 33, 226, + 117, 136, 186, 40, 29, 185, 211, 190, 112, 19, 103, 155, 76, 33, 66, 114, + 114, 180, 81, 24, 4, 238, 52, 149, 234, 144, 84, 204, 119, 13, 130, 160, + 118, 251, 213, 104, 6, 164, 175, 149, 237, 87, 81, 136, 117, 93, 83, 92, + 126, 4, 222, 42, 57, 47, 54, 225, 18, 6, 242, 128, 223, 203, 165, 48, 220, + 152, 112, 35, 72, 100, 143, 104, 3, 252, 228, 160, 191, 154, 71, 251, 216, + 174, 255, 207, 57, 18, 171, 148, 151, 175, 135, 158, 165, 221, 46, 157, 254, + 32, 207, 59, 224, 253, 121, 200, 175, 91, 190, 40, 12, 232, 83, 60, 73, 103, + 146, 102, 235, 216, 46, 27, 80, 219, 114, 127, 37, 210, 53, 243, 21, 9, 85, + 18, 212, 153, 112, 110, 17, 67, 243, 75, 185, 234, 52, 94, 169, 47, 208, + 210, 224, 31, 180, 176, 151, 101, 166, 13, 202, 176, 91, 29, 140, 53, 194, + 222, 219, 148, 118, 169, 26, 247, 135, 175, 173, 24, 130, 35, 213, 176, 187, + 128, 21, 27, 223, 132, 255, 128, 235, 221, 169, 139, 74, 111, 178, 223, 38, + 229, 30, 47, 71, 117, 139, 149, 212, 216, 226, 233, 244, 253, 8, 101, 110, + 114, 139, 141, 182, 200, 217, 228, 247, 251, 5, 15, 48, 140, 190, 227, 242, + 79, 136, 161, 167, 176, 252, 8, 10, 11, 40, 116, 172, 193, 233, 248, 47, 57, + 124, 165, 166, 180, 189, 3, 28, 87, 162, 163, 232, 238, 248, 1, 43, 64, 93, + 109, 149, 172, 187, 204, 210, 233, 0, 0, 0, 0, 11, 23, 30, 36, 45, 52, 60, + 71, + ]), +}; + +function getTestVectors() { + var vectors = []; + + // Basic test without context + ['ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87'].forEach((algorithmName) => { + vectors.push({ + name: algorithmName + ' basic test', + publicKeyBuffer: spki[algorithmName], + publicKeyFormat: 'spki', + publicKey: null, + privateKeyBuffer: pkcs8[algorithmName], + privateKeyFormat: 'pkcs8', + privateKey: null, + algorithmName: algorithmName, + data: data, + signature: signatures[algorithmName], + }); + }); + + return vectors; +} + +// Invalid test vectors for negative testing +function getInvalidTestVectors() { + var vectors = []; + + // Test with invalid signature + ['ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87'].forEach((algorithmName) => { + vectors.push({ + name: algorithmName + ' invalid signature', + publicKeyBuffer: spki[algorithmName], + publicKeyFormat: 'spki', + publicKey: null, + privateKeyBuffer: pkcs8[algorithmName], + privateKeyFormat: 'pkcs8', + privateKey: null, + algorithmName: algorithmName, + data: data, + signature: new Uint8Array([1, 2, 3, 4, 5]), // Invalid signature + }); + }); + + return vectors; +} diff --git a/test/fixtures/wpt/WebCryptoAPI/supports.tentative.https.any.js b/test/fixtures/wpt/WebCryptoAPI/supports.tentative.https.any.js new file mode 100644 index 00000000000000..dd39273e4b918b --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/supports.tentative.https.any.js @@ -0,0 +1,397 @@ +// META: title=WebCrypto API: supports method tests +// META: script=util/helpers.js + +'use strict'; + +const standardAlgorithms = { + // Asymmetric algorithms + 'RSASSA-PKCS1-v1_5': { + operations: ['generateKey', 'importKey', 'sign', 'verify'], + keyGenParams: { + name: 'RSASSA-PKCS1-v1_5', + modulusLength: 2048, + publicExponent: new Uint8Array([1, 0, 1]), + hash: 'SHA-256', + }, + importParams: { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' }, + signParams: { name: 'RSASSA-PKCS1-v1_5' }, + }, + 'RSA-PSS': { + operations: ['generateKey', 'importKey', 'sign', 'verify'], + keyGenParams: { + name: 'RSA-PSS', + modulusLength: 2048, + publicExponent: new Uint8Array([1, 0, 1]), + hash: 'SHA-256', + }, + importParams: { name: 'RSA-PSS', hash: 'SHA-256' }, + signParams: { name: 'RSA-PSS', saltLength: 32 }, + }, + 'RSA-OAEP': { + operations: ['generateKey', 'importKey', 'encrypt', 'decrypt'], + keyGenParams: { + name: 'RSA-OAEP', + modulusLength: 2048, + publicExponent: new Uint8Array([1, 0, 1]), + hash: 'SHA-256', + }, + importParams: { name: 'RSA-OAEP', hash: 'SHA-256' }, + encryptParams: { name: 'RSA-OAEP' }, + }, + ECDSA: { + operations: ['generateKey', 'importKey', 'sign', 'verify'], + keyGenParams: { name: 'ECDSA', namedCurve: 'P-256' }, + importParams: { name: 'ECDSA', namedCurve: 'P-256' }, + signParams: { name: 'ECDSA', hash: 'SHA-256' }, + }, + ECDH: { + operations: ['generateKey', 'importKey', 'deriveBits'], + keyGenParams: { name: 'ECDH', namedCurve: 'P-256' }, + importParams: { name: 'ECDH', namedCurve: 'P-256' }, + deriveBitsParams: { + name: 'ECDH', + public: crypto.subtle.generateKey( + { name: 'ECDH', namedCurve: 'P-256' }, + false, + ['deriveBits'] + ), + }, + }, + Ed25519: { + operations: ['generateKey', 'importKey', 'sign', 'verify'], + keyGenParams: null, + signParams: { name: 'Ed25519' }, + }, + X25519: { + operations: ['generateKey', 'importKey', 'deriveBits'], + keyGenParams: null, + deriveBitsParams: { + name: 'X25519', + public: crypto.subtle.generateKey('X25519', false, ['deriveBits']), + }, + }, + + // Symmetric algorithms + 'AES-CBC': { + operations: ['generateKey', 'importKey', 'encrypt', 'decrypt'], + keyGenParams: { name: 'AES-CBC', length: 256 }, + encryptParams: { name: 'AES-CBC', iv: new Uint8Array(16) }, + }, + 'AES-CTR': { + operations: ['generateKey', 'importKey', 'encrypt', 'decrypt'], + keyGenParams: { name: 'AES-CTR', length: 256 }, + encryptParams: { + name: 'AES-CTR', + counter: new Uint8Array(16), + length: 128, + }, + }, + 'AES-GCM': { + operations: ['generateKey', 'importKey', 'encrypt', 'decrypt'], + keyGenParams: { name: 'AES-GCM', length: 256 }, + encryptParams: { name: 'AES-GCM', iv: new Uint8Array(12) }, + }, + 'AES-KW': { + operations: ['generateKey', 'importKey'], // wrapKey/unwrapKey not in requested operations + keyGenParams: { name: 'AES-KW', length: 256 }, + }, + HMAC: { + operations: ['generateKey', 'importKey', 'sign', 'verify'], + keyGenParams: { name: 'HMAC', hash: 'SHA-256' }, + importParams: { name: 'HMAC', hash: 'SHA-256' }, + signParams: { name: 'HMAC' }, + }, + + // Hash algorithms + 'SHA-1': { + operations: ['digest'], + keyGenParams: null, + }, + 'SHA-256': { + operations: ['digest'], + keyGenParams: null, + }, + 'SHA-384': { + operations: ['digest'], + keyGenParams: null, + }, + 'SHA-512': { + operations: ['digest'], + keyGenParams: null, + }, + + // Key derivation algorithms + HKDF: { + operations: ['importKey', 'deriveBits'], + keyGenParams: null, + deriveBitsParams: { + name: 'HKDF', + hash: 'SHA-256', + salt: new Uint8Array(16), + info: new Uint8Array(0), + }, + }, + PBKDF2: { + operations: ['importKey', 'deriveBits'], + keyGenParams: null, + deriveBitsParams: { + name: 'PBKDF2', + hash: 'SHA-256', + salt: new Uint8Array(16), + iterations: 100000, + }, + }, +}; + +const operations = [ + 'generateKey', + 'importKey', + 'sign', + 'verify', + 'encrypt', + 'decrypt', + 'deriveBits', + 'digest', +]; + +// Test that supports method exists and is a static method +test(() => { + assert_true( + typeof SubtleCrypto.supports === 'function', + 'SubtleCrypto.supports should be a function' + ); +}, 'SubtleCrypto.supports method exists'); + +// Test invalid operation names +test(() => { + assert_false( + SubtleCrypto.supports('invalidOperation', 'AES-GCM'), + 'Invalid operation should return false' + ); + assert_false( + SubtleCrypto.supports('', 'AES-GCM'), + 'Empty operation should return false' + ); + assert_false( + SubtleCrypto.supports('GENERATEKEY', 'AES-GCM'), + 'Case-sensitive operation check' + ); +}, 'supports returns false for invalid operations'); + +// Test invalid algorithm identifiers +test(() => { + assert_false( + SubtleCrypto.supports('generateKey', 'InvalidAlgorithm'), + 'Invalid algorithm should return false' + ); + assert_false( + SubtleCrypto.supports('generateKey', ''), + 'Empty algorithm should return false' + ); +}, 'supports returns false for invalid algorithms'); + +// Test standard WebCrypto algorithms for requested operations +for (const [algorithmName, algorithmInfo] of Object.entries( + standardAlgorithms +)) { + for (const operation of operations) { + promise_test(async (t) => { + const isSupported = algorithmInfo.operations.includes(operation); + + // Use appropriate algorithm parameters for each operation + let algorithm; + let length; + switch (operation) { + case 'generateKey': + algorithm = algorithmInfo.keyGenParams || algorithmName; + break; + case 'importKey': + algorithm = algorithmInfo.importParams || algorithmName; + break; + case 'sign': + case 'verify': + algorithm = algorithmInfo.signParams || algorithmName; + break; + case 'encrypt': + case 'decrypt': + algorithm = algorithmInfo.encryptParams || algorithmName; + break; + case 'deriveBits': + algorithm = algorithmInfo.deriveBitsParams || algorithmName; + if (algorithm?.public instanceof Promise) { + algorithm.public = (await algorithm.public).publicKey; + } + if (algorithmName === 'PBKDF2' || algorithmName === 'HKDF') { + length = 256; + } + break; + case 'digest': + algorithm = algorithmName; + break; + default: + algorithm = algorithmName; + } + + const result = SubtleCrypto.supports(operation, algorithm, length); + + if (isSupported) { + assert_true(result, `${algorithmName} should support ${operation}`); + } else { + assert_false(result, `${algorithmName} should not support ${operation}`); + } + }, `supports(${operation}, ${algorithmName})`); + } +} + +// Test algorithm objects (not just strings) +test(() => { + assert_true( + SubtleCrypto.supports('generateKey', { name: 'AES-GCM', length: 256 }), + 'Algorithm object should be supported' + ); + assert_true( + SubtleCrypto.supports('generateKey', { name: 'HMAC', hash: 'SHA-256' }), + 'Algorithm object with parameters should be supported' + ); +}, 'supports works with algorithm objects'); + +// Test with algorithm objects that have invalid parameters +test(() => { + assert_false( + SubtleCrypto.supports('generateKey', { name: 'AES-GCM', length: 100 }), + 'Invalid key length should return false' + ); + assert_false( + SubtleCrypto.supports('generateKey', { + name: 'HMAC', + hash: 'INVALID-HASH', + }), + 'Invalid hash parameter should return false' + ); +}, 'supports returns false for algorithm objects with invalid parameters'); + +// Test some specific combinations that should work +test(() => { + // RSA algorithms + assert_true( + SubtleCrypto.supports('generateKey', { + name: 'RSASSA-PKCS1-v1_5', + modulusLength: 2048, + publicExponent: new Uint8Array([1, 0, 1]), + hash: 'SHA-256', + }), + 'RSASSA-PKCS1-v1_5 generateKey' + ); + assert_true( + SubtleCrypto.supports('sign', { name: 'RSASSA-PKCS1-v1_5' }), + 'RSASSA-PKCS1-v1_5 sign' + ); + assert_true( + SubtleCrypto.supports('verify', { name: 'RSASSA-PKCS1-v1_5' }), + 'RSASSA-PKCS1-v1_5 verify' + ); + + // ECDSA + assert_true( + SubtleCrypto.supports('generateKey', { + name: 'ECDSA', + namedCurve: 'P-256', + }), + 'ECDSA generateKey' + ); + assert_true( + SubtleCrypto.supports('sign', { name: 'ECDSA', hash: 'SHA-256' }), + 'ECDSA sign' + ); + assert_true( + SubtleCrypto.supports('verify', { name: 'ECDSA', hash: 'SHA-256' }), + 'ECDSA verify' + ); + + // AES-GCM + assert_true( + SubtleCrypto.supports('generateKey', { name: 'AES-GCM', length: 256 }), + 'AES-GCM generateKey' + ); + assert_true( + SubtleCrypto.supports('encrypt', { + name: 'AES-GCM', + iv: new Uint8Array(12), + }), + 'AES-GCM encrypt' + ); + assert_true( + SubtleCrypto.supports('decrypt', { + name: 'AES-GCM', + iv: new Uint8Array(12), + }), + 'AES-GCM decrypt' + ); + + // HMAC + assert_true( + SubtleCrypto.supports('generateKey', { name: 'HMAC', hash: 'SHA-256' }), + 'HMAC generateKey' + ); + assert_true(SubtleCrypto.supports('sign', { name: 'HMAC' }), 'HMAC sign'); + assert_true(SubtleCrypto.supports('verify', { name: 'HMAC' }), 'HMAC verify'); +}, 'Common algorithm and operation combinations work'); + +// Test some specific combinations that should not work +test(() => { + // Hash algorithms don't support key operations + assert_false( + SubtleCrypto.supports('generateKey', 'SHA-256'), + 'SHA-256 generateKey should fail' + ); + assert_false( + SubtleCrypto.supports('sign', 'SHA-256'), + 'SHA-256 sign should fail' + ); + + // AES can't sign/verify (these require algorithm parameters due to normalization) + assert_false( + SubtleCrypto.supports('sign', 'AES-GCM'), + 'AES-GCM sign should fail' + ); + assert_false( + SubtleCrypto.supports('verify', 'AES-GCM'), + 'AES-GCM verify should fail' + ); + + // ECDSA can't encrypt/decrypt + assert_false( + SubtleCrypto.supports('encrypt', 'ECDSA'), + 'ECDSA encrypt should fail' + ); + assert_false( + SubtleCrypto.supports('decrypt', 'ECDSA'), + 'ECDSA decrypt should fail' + ); + + // HMAC can't encrypt/decrypt + assert_false( + SubtleCrypto.supports('encrypt', 'HMAC'), + 'HMAC encrypt should fail' + ); + assert_false( + SubtleCrypto.supports('decrypt', 'HMAC'), + 'HMAC decrypt should fail' + ); + + // Non-hash algorithms can't digest + assert_false( + SubtleCrypto.supports('digest', 'AES-GCM'), + 'AES-GCM digest should fail' + ); + assert_false( + SubtleCrypto.supports('digest', 'ECDSA'), + 'ECDSA digest should fail' + ); + assert_false( + SubtleCrypto.supports('digest', 'HMAC'), + 'HMAC digest should fail' + ); +}, 'Invalid algorithm and operation combinations fail'); + +done(); diff --git a/test/fixtures/wpt/WebCryptoAPI/util/helpers.js b/test/fixtures/wpt/WebCryptoAPI/util/helpers.js index 488eadf29c09da..dbcc5053b1313a 100644 --- a/test/fixtures/wpt/WebCryptoAPI/util/helpers.js +++ b/test/fixtures/wpt/WebCryptoAPI/util/helpers.js @@ -24,7 +24,20 @@ var registeredAlgorithmNames = [ "Ed25519", "Ed448", "X25519", - "X448" + "X448", + "ML-DSA-44", + "ML-DSA-65", + "ML-DSA-87", + "ML-KEM-512", + "ML-KEM-768", + "ML-KEM-1024", + "ChaCha20-Poly1305", + "Argon2i", + "Argon2d", + "Argon2id", + "AES-OCB", + "KMAC128", + "KMAC256", ]; @@ -124,6 +137,15 @@ function assert_goodCryptoKey(key, algorithm, extractable, usages, kind) { default: assert_unreached("Unrecognized hash"); } + } else if (key.algorithm.name.toUpperCase().startsWith("KMAC") && algorithm.length === undefined) { + switch (key.algorithm.name.toUpperCase()) { + case 'KMAC128': + assert_equals(key.algorithm.length, 128, "Correct length"); + break; + case 'KMAC256': + assert_equals(key.algorithm.length, 256, "Correct length"); + break; + } } else { assert_equals(key.algorithm.length, algorithm.length, "Correct length"); } @@ -139,13 +161,13 @@ function assert_goodCryptoKey(key, algorithm, extractable, usages, kind) { // only a single key. The publicKey and privateKey portions of a key pair // recognize only some of the usages appropriate for a key pair. if (key.type === "public") { - ["encrypt", "verify", "wrapKey"].forEach(function(usage) { + ["encrypt", "verify", "wrapKey", "encapsulateBits", "encapsulateKey"].forEach(function(usage) { if (usages.includes(usage)) { correctUsages.push(usage); } }); } else if (key.type === "private") { - ["decrypt", "sign", "unwrapKey", "deriveKey", "deriveBits"].forEach(function(usage) { + ["decrypt", "sign", "unwrapKey", "deriveKey", "deriveBits", "decapsulateBits", "decapsulateKey"].forEach(function(usage) { if (usages.includes(usage)) { correctUsages.push(usage); } @@ -206,7 +228,15 @@ function allAlgorithmSpecifiersFor(algorithmName) { curves.forEach(function(curveName) { results.push({name: algorithmName, namedCurve: curveName}); }); - } else if (algorithmName.toUpperCase().substring(0, 1) === "X" || algorithmName.toUpperCase().substring(0, 2) === "ED") { + } else if (algorithmName.toUpperCase().startsWith("KMAC")) { + [ + {length: 128}, + {length: 160}, + {length: 256}, + ].forEach(function(hashAlgorithm) { + results.push({name: algorithmName, ...hashAlgorithm}); + }); + } else { results.push(algorithmName); results.push({ name: algorithmName }); } diff --git a/test/fixtures/wpt/versions.json b/test/fixtures/wpt/versions.json index 7fa0e4572b7703..afb05be1481f70 100644 --- a/test/fixtures/wpt/versions.json +++ b/test/fixtures/wpt/versions.json @@ -96,7 +96,7 @@ "path": "web-locks" }, "WebCryptoAPI": { - "commit": "ff26d9b307b981b3f1b88f454268e6bb8933e6c2", + "commit": "c58b6f4e0eaf8d3b9792f7add1d3dfcbef40053f", "path": "WebCryptoAPI" }, "webidl/ecmascript-binding/es-exceptions": { From 038c86f3de0a87b839778476ceb70b4e007e58c3 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Thu, 13 Nov 2025 17:58:37 +0100 Subject: [PATCH 2/4] fixup! test: update WPT for WebCryptoAPI to c58b6f4e0e --- test/wpt/status/WebCryptoAPI.cjs | 41 ++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/test/wpt/status/WebCryptoAPI.cjs b/test/wpt/status/WebCryptoAPI.cjs index 7e4639ca497ba0..f1c04d07d22869 100644 --- a/test/wpt/status/WebCryptoAPI.cjs +++ b/test/wpt/status/WebCryptoAPI.cjs @@ -2,9 +2,50 @@ const os = require('node:os'); +const { hasOpenSSL } = require('../../common/crypto.js'); + const s390x = os.arch() === 's390x'; +const conditionalSkips = {}; + +function skip(...files) { + for (const file of files) { + conditionalSkips[file] = { + 'skip': `Unsupported in OpenSSL ${process.versions.openssl}`, + } + } +} + +if (!hasOpenSSL(3, 0)) { + skip('encrypt_decrypt/aes_ocb.tentative.https.any.js'); + skip('generateKey/failures_AES-OCB.tentative.https.any.js'); + skip('generateKey/failures_kmac.tentative.https.any.js'); + skip('generateKey/successes_AES-OCB.tentative.https.any.js'); + skip('generateKey/successes_kmac.tentative.https.any.js'); + skip('import_export/AES-OCB_importKey.tentative.https.any.js'); + skip('import_export/KMAC_importKey.tentative.https.any.js'); + skip('sign_verify/kmac.tentative.https.any.js'); +} + +if (!hasOpenSSL(3, 2)) { + skip('derive_bits_keys/argon2.tentative.https.any.js'); + skip('import_export/Argon2_importKey.tentative.https.any.js'); +} + +if (!hasOpenSSL(3, 5)) { + skip('encap_decap/encap_decap_bits.tentative.https.any.js'); + skip('encap_decap/encap_decap_keys.tentative.https.any.js'); + skip('generateKey/failures_ML-DSA.tentative.https.any.js'); + skip('generateKey/failures_ML-KEM.tentative.https.any.js'); + skip('generateKey/successes_ML-DSA.tentative.https.any.js'); + skip('generateKey/successes_ML-KEM.tentative.https.any.js'); + skip('import_export/ML-DSA_importKey.tentative.https.any.js'); + skip('import_export/ML-KEM_importKey.tentative.https.any.js'); + skip('sign_verify/mldsa.tentative.https.any.js'); +} + module.exports = { + ...conditionalSkips, 'algorithm-discards-context.https.window.js': { 'skip': 'Not relevant in Node.js context', }, From da9f3c68dde762fefe42ad2fa670f7aa55f0af13 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Thu, 13 Nov 2025 18:01:57 +0100 Subject: [PATCH 3/4] fixup! test: update WPT for WebCryptoAPI to c58b6f4e0e --- test/wpt/status/WebCryptoAPI.cjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/wpt/status/WebCryptoAPI.cjs b/test/wpt/status/WebCryptoAPI.cjs index f1c04d07d22869..98d7f306bb8c53 100644 --- a/test/wpt/status/WebCryptoAPI.cjs +++ b/test/wpt/status/WebCryptoAPI.cjs @@ -12,7 +12,7 @@ function skip(...files) { for (const file of files) { conditionalSkips[file] = { 'skip': `Unsupported in OpenSSL ${process.versions.openssl}`, - } + }; } } From c85168f9a311c6daf7421909d2df42bf0c9ef307 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Thu, 13 Nov 2025 18:12:42 +0100 Subject: [PATCH 4/4] fixup! test: update WPT for WebCryptoAPI to c58b6f4e0e --- test/wpt/status/WebCryptoAPI.cjs | 41 +++++++++++++++++--------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/test/wpt/status/WebCryptoAPI.cjs b/test/wpt/status/WebCryptoAPI.cjs index 98d7f306bb8c53..d23fb1d40453fe 100644 --- a/test/wpt/status/WebCryptoAPI.cjs +++ b/test/wpt/status/WebCryptoAPI.cjs @@ -17,31 +17,34 @@ function skip(...files) { } if (!hasOpenSSL(3, 0)) { - skip('encrypt_decrypt/aes_ocb.tentative.https.any.js'); - skip('generateKey/failures_AES-OCB.tentative.https.any.js'); - skip('generateKey/failures_kmac.tentative.https.any.js'); - skip('generateKey/successes_AES-OCB.tentative.https.any.js'); - skip('generateKey/successes_kmac.tentative.https.any.js'); - skip('import_export/AES-OCB_importKey.tentative.https.any.js'); - skip('import_export/KMAC_importKey.tentative.https.any.js'); - skip('sign_verify/kmac.tentative.https.any.js'); + skip( + 'encrypt_decrypt/aes_ocb.tentative.https.any.js', + 'generateKey/failures_AES-OCB.tentative.https.any.js', + 'generateKey/failures_kmac.tentative.https.any.js', + 'generateKey/successes_AES-OCB.tentative.https.any.js', + 'generateKey/successes_kmac.tentative.https.any.js', + 'import_export/AES-OCB_importKey.tentative.https.any.js', + 'import_export/KMAC_importKey.tentative.https.any.js', + 'sign_verify/kmac.tentative.https.any.js'); } if (!hasOpenSSL(3, 2)) { - skip('derive_bits_keys/argon2.tentative.https.any.js'); - skip('import_export/Argon2_importKey.tentative.https.any.js'); + skip( + 'derive_bits_keys/argon2.tentative.https.any.js', + 'import_export/Argon2_importKey.tentative.https.any.js'); } if (!hasOpenSSL(3, 5)) { - skip('encap_decap/encap_decap_bits.tentative.https.any.js'); - skip('encap_decap/encap_decap_keys.tentative.https.any.js'); - skip('generateKey/failures_ML-DSA.tentative.https.any.js'); - skip('generateKey/failures_ML-KEM.tentative.https.any.js'); - skip('generateKey/successes_ML-DSA.tentative.https.any.js'); - skip('generateKey/successes_ML-KEM.tentative.https.any.js'); - skip('import_export/ML-DSA_importKey.tentative.https.any.js'); - skip('import_export/ML-KEM_importKey.tentative.https.any.js'); - skip('sign_verify/mldsa.tentative.https.any.js'); + skip( + 'encap_decap/encap_decap_bits.tentative.https.any.js', + 'encap_decap/encap_decap_keys.tentative.https.any.js', + 'generateKey/failures_ML-DSA.tentative.https.any.js', + 'generateKey/failures_ML-KEM.tentative.https.any.js', + 'generateKey/successes_ML-DSA.tentative.https.any.js', + 'generateKey/successes_ML-KEM.tentative.https.any.js', + 'import_export/ML-DSA_importKey.tentative.https.any.js', + 'import_export/ML-KEM_importKey.tentative.https.any.js', + 'sign_verify/mldsa.tentative.https.any.js'); } module.exports = {