crypto: support ML-KEM KeyObject

PR-URL: https://github.com/nodejs/node/pull/59461
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Ethan Arrowood <ethan@arrowood.dev>
This commit is contained in:
Filip Skokan 2025-08-16 16:39:14 +02:00 committed by GitHub
parent 00a42d8205
commit 66e25cf1b3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 665 additions and 3 deletions

View File

@ -11,6 +11,22 @@
#include <cstring>
#if OPENSSL_VERSION_MAJOR >= 3
#include <openssl/provider.h>
#endif
#if OPENSSL_WITH_PQC
struct PQCMapping {
const char* name;
int nid;
};
constexpr static PQCMapping pqc_mappings[] = {
{"ML-DSA-44", EVP_PKEY_ML_DSA_44},
{"ML-DSA-65", EVP_PKEY_ML_DSA_65},
{"ML-DSA-87", EVP_PKEY_ML_DSA_87},
{"ML-KEM-512", EVP_PKEY_ML_KEM_512},
{"ML-KEM-768", EVP_PKEY_ML_KEM_768},
{"ML-KEM-1024", EVP_PKEY_ML_KEM_1024},
};
#endif
// EVP_PKEY_CTX_set_dsa_paramgen_q_bits was added in OpenSSL 1.1.1e.
@ -1969,11 +1985,21 @@ int EVPKeyPointer::id(const EVP_PKEY* key) {
if (key == nullptr) return 0;
int type = EVP_PKEY_id(key);
#if OPENSSL_WITH_PQC
// EVP_PKEY_id returns -1 when EVP_PKEY_* is only implemented in a provider
// which is the case for all post-quantum NIST algorithms
// one suggested way would be to use a chain of `EVP_PKEY_is_a`
// https://github.com/openssl/openssl/issues/27738#issuecomment-3013215870
// or, this way there are less calls to the OpenSSL provider, just
// getting the name once
if (type == -1) {
if (EVP_PKEY_is_a(key, "ML-DSA-44")) return EVP_PKEY_ML_DSA_44;
if (EVP_PKEY_is_a(key, "ML-DSA-65")) return EVP_PKEY_ML_DSA_65;
if (EVP_PKEY_is_a(key, "ML-DSA-87")) return EVP_PKEY_ML_DSA_87;
const char* type_name = EVP_PKEY_get0_type_name(key);
if (type_name == nullptr) return -1;
for (const auto& mapping : pqc_mappings) {
if (strcmp(type_name, mapping.name) == 0) {
return mapping.nid;
}
}
}
#endif
return type;

View File

@ -31,6 +31,9 @@
// Define OPENSSL_WITH_PQC for post-quantum cryptography support
#if OPENSSL_VERSION_NUMBER >= 0x30500000L
#define OPENSSL_WITH_PQC 1
#define EVP_PKEY_ML_KEM_512 NID_ML_KEM_512
#define EVP_PKEY_ML_KEM_768 NID_ML_KEM_768
#define EVP_PKEY_ML_KEM_1024 NID_ML_KEM_1024
#include <openssl/core_names.h>
#endif

View File

@ -2024,6 +2024,9 @@ Other key details might be exposed via this API using additional attributes.
<!-- YAML
added: v11.6.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/59461
description: Add support for ML-KEM keys.
- version: v24.6.0
pr-url: https://github.com/nodejs/node/pull/59259
description: Add support for ML-DSA keys.
@ -2064,6 +2067,9 @@ types are:
* `'ml-dsa-44'`[^openssl35] (OID 2.16.840.1.101.3.4.3.17)
* `'ml-dsa-65'`[^openssl35] (OID 2.16.840.1.101.3.4.3.18)
* `'ml-dsa-87'`[^openssl35] (OID 2.16.840.1.101.3.4.3.19)
* `'ml-kem-512'`[^openssl35] (OID 2.16.840.1.101.3.4.4.1)
* `'ml-kem-768'`[^openssl35] (OID 2.16.840.1.101.3.4.4.2)
* `'ml-kem-1024'`[^openssl35] (OID 2.16.840.1.101.3.4.4.3)
This property is `undefined` for unrecognized `KeyObject` types and symmetric
keys.
@ -3663,6 +3669,9 @@ underlying hash function. See [`crypto.createHmac()`][] for more information.
<!-- YAML
added: v10.12.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/59461
description: Add support for ML-KEM key pairs.
- version: v24.6.0
pr-url: https://github.com/nodejs/node/pull/59259
description: Add support for ML-DSA key pairs.
@ -3786,6 +3795,9 @@ a `Promise` for an `Object` with `publicKey` and `privateKey` properties.
<!-- YAML
added: v10.12.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/59461
description: Add support for ML-KEM key pairs.
- version: v24.6.0
pr-url: https://github.com/nodejs/node/pull/59259
description: Add support for ML-DSA key pairs.

View File

@ -22,6 +22,9 @@ const {
EVP_PKEY_ML_DSA_44,
EVP_PKEY_ML_DSA_65,
EVP_PKEY_ML_DSA_87,
EVP_PKEY_ML_KEM_1024,
EVP_PKEY_ML_KEM_512,
EVP_PKEY_ML_KEM_768,
EVP_PKEY_X25519,
EVP_PKEY_X448,
OPENSSL_EC_NAMED_CURVE,
@ -173,6 +176,9 @@ const ids = {
'ml-dsa-44': EVP_PKEY_ML_DSA_44,
'ml-dsa-65': EVP_PKEY_ML_DSA_65,
'ml-dsa-87': EVP_PKEY_ML_DSA_87,
'ml-kem-512': EVP_PKEY_ML_KEM_512,
'ml-kem-768': EVP_PKEY_ML_KEM_768,
'ml-kem-1024': EVP_PKEY_ML_KEM_1024,
};
function createJob(mode, type, options) {
@ -294,6 +300,9 @@ function createJob(mode, type, options) {
case 'ml-dsa-44':
case 'ml-dsa-65':
case 'ml-dsa-87':
case 'ml-kem-512':
case 'ml-kem-768':
case 'ml-kem-1024':
{
if (ids[type] === undefined) {
throw new ERR_INVALID_ARG_VALUE('type', type, 'must be a supported key type');

View File

@ -978,6 +978,12 @@ Local<Value> KeyObjectHandle::GetAsymmetricKeyType() const {
return env()->crypto_ml_dsa_65_string();
case EVP_PKEY_ML_DSA_87:
return env()->crypto_ml_dsa_87_string();
case EVP_PKEY_ML_KEM_512:
return env()->crypto_ml_kem_512_string();
case EVP_PKEY_ML_KEM_768:
return env()->crypto_ml_kem_768_string();
case EVP_PKEY_ML_KEM_1024:
return env()->crypto_ml_kem_1024_string();
#endif
default:
return Undefined(env()->isolate());
@ -1258,6 +1264,9 @@ void Initialize(Environment* env, Local<Object> target) {
NODE_DEFINE_CONSTANT(target, EVP_PKEY_ML_DSA_44);
NODE_DEFINE_CONSTANT(target, EVP_PKEY_ML_DSA_65);
NODE_DEFINE_CONSTANT(target, EVP_PKEY_ML_DSA_87);
NODE_DEFINE_CONSTANT(target, EVP_PKEY_ML_KEM_512);
NODE_DEFINE_CONSTANT(target, EVP_PKEY_ML_KEM_768);
NODE_DEFINE_CONSTANT(target, EVP_PKEY_ML_KEM_1024);
#endif
NODE_DEFINE_CONSTANT(target, EVP_PKEY_X25519);
NODE_DEFINE_CONSTANT(target, EVP_PKEY_X448);

View File

@ -118,6 +118,9 @@
V(crypto_ml_dsa_44_string, "ml-dsa-44") \
V(crypto_ml_dsa_65_string, "ml-dsa-65") \
V(crypto_ml_dsa_87_string, "ml-dsa-87") \
V(crypto_ml_kem_512_string, "ml-kem-512") \
V(crypto_ml_kem_768_string, "ml-kem-768") \
V(crypto_ml_kem_1024_string, "ml-kem-1024") \
V(crypto_x25519_string, "x25519") \
V(crypto_x448_string, "x448") \
V(crypto_rsa_string, "rsa") \

View File

@ -110,6 +110,18 @@ all: \
ml_dsa_87_private_seed_only.pem \
ml_dsa_87_private_priv_only.pem \
ml_dsa_87_public.pem \
ml_kem_512_private.pem \
ml_kem_512_private_seed_only.pem \
ml_kem_512_private_priv_only.pem \
ml_kem_512_public.pem \
ml_kem_768_private.pem \
ml_kem_768_private_seed_only.pem \
ml_kem_768_private_priv_only.pem \
ml_kem_768_public.pem \
ml_kem_1024_private.pem \
ml_kem_1024_private_seed_only.pem \
ml_kem_1024_private_priv_only.pem \
ml_kem_1024_public.pem \
#
# Create Certificate Authority: ca1
@ -903,6 +915,42 @@ ml_dsa_87_private_priv_only.pem: ml_dsa_87_private.pem
ml_dsa_87_public.pem: ml_dsa_87_private.pem
openssl pkey -in ml_dsa_87_private.pem -pubout -out ml_dsa_87_public.pem
ml_kem_512_private.pem:
openssl genpkey -algorithm ml-kem-512 -out ml_kem_512_private.pem
ml_kem_512_private_seed_only.pem: ml_kem_512_private.pem
openssl pkey -in ml_kem_512_private.pem -provparam ml-kem.output_formats=seed-only -out ml_kem_512_private_seed_only.pem
ml_kem_512_private_priv_only.pem: ml_kem_512_private.pem
openssl pkey -in ml_kem_512_private.pem -provparam ml-kem.output_formats=priv-only -out ml_kem_512_private_priv_only.pem
ml_kem_512_public.pem: ml_kem_512_private.pem
openssl pkey -in ml_kem_512_private.pem -pubout -out ml_kem_512_public.pem
ml_kem_768_private.pem:
openssl genpkey -algorithm ml-kem-768 -out ml_kem_768_private.pem
ml_kem_768_private_seed_only.pem: ml_kem_768_private.pem
openssl pkey -in ml_kem_768_private.pem -provparam ml-kem.output_formats=seed-only -out ml_kem_768_private_seed_only.pem
ml_kem_768_private_priv_only.pem: ml_kem_768_private.pem
openssl pkey -in ml_kem_768_private.pem -provparam ml-kem.output_formats=priv-only -out ml_kem_768_private_priv_only.pem
ml_kem_768_public.pem: ml_kem_768_private.pem
openssl pkey -in ml_kem_768_private.pem -pubout -out ml_kem_768_public.pem
ml_kem_1024_private.pem:
openssl genpkey -algorithm ml-kem-1024 -out ml_kem_1024_private.pem
ml_kem_1024_private_seed_only.pem: ml_kem_1024_private.pem
openssl pkey -in ml_kem_1024_private.pem -provparam ml-kem.output_formats=seed-only -out ml_kem_1024_private_seed_only.pem
ml_kem_1024_private_priv_only.pem: ml_kem_1024_private.pem
openssl pkey -in ml_kem_1024_private.pem -provparam ml-kem.output_formats=priv-only -out ml_kem_1024_private_priv_only.pem
ml_kem_1024_public.pem: ml_kem_1024_private.pem
openssl pkey -in ml_kem_1024_private.pem -pubout -out ml_kem_1024_public.pem
x448_private.pem:
openssl genpkey -algorithm x448 -out x448_private.pem

View File

@ -0,0 +1,71 @@
-----BEGIN PRIVATE KEY-----
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
SAs=
-----END PRIVATE KEY-----

View File

@ -0,0 +1,69 @@
-----BEGIN PRIVATE KEY-----
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
AJV/u5KhD/rnJLoLOu0eNGt4p3Oh6Mg5ttxICw==
-----END PRIVATE KEY-----

View File

@ -0,0 +1,4 @@
-----BEGIN PRIVATE KEY-----
MFQCAQAwCwYJYIZIAWUDBAQDBEKAQF8HoLJVBnDJ87tXNTXHLMkZgWjm1khEiBjv
n7XHI+TLwMIywwCVf7uSoQ/65yS6CzrtHjRreKdzoejIObbcSAs=
-----END PRIVATE KEY-----

View File

@ -0,0 +1,36 @@
-----BEGIN PUBLIC KEY-----
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
KaRt3ND5
-----END PUBLIC KEY-----

View File

@ -0,0 +1,39 @@
-----BEGIN PRIVATE KEY-----
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
jmg=
-----END PRIVATE KEY-----

View File

@ -0,0 +1,37 @@
-----BEGIN PRIVATE KEY-----
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
1xtlVqz7oLTcOAx1JNA+E7yXLnGPgZdplLmOaA==
-----END PRIVATE KEY-----

View File

@ -0,0 +1,4 @@
-----BEGIN PRIVATE KEY-----
MFQCAQAwCwYJYIZIAWUDBAQBBEKAQLI1YWWjA83YR+6zGsO2fRx/uy34qWNsHl6Q
qq9CNwjMzrf4wdcbZVas+6C03DgMdSTQPhO8ly5xj4GXaZS5jmg=
-----END PRIVATE KEY-----

View File

@ -0,0 +1,20 @@
-----BEGIN PUBLIC KEY-----
MIIDMjALBglghkgBZQMEBAEDggMhANslme5hIWyiaKR5mWF4xhEUKxwRwkKgU4Y8
FVOYL0z1qj7qgKOnB1qzqxwgbfWhksjztgazNMOztVGSbGnTJoUSWjrzeNgLw+jr
nm72JHvyEzsotq2xP88MOuPKMdSRfGTLE0fKaY/6l/6ogGGhQs6ahhucf7MLmAbI
bsJ0mdqYpTk0Oe+3XDhzVA1GebY3T3nLsZKUP0DoYRiRys6FWNWIsOM6Tw/ZCi8T
uwc1G0y3DWUrOVQSeVJGsMuLH40GuEDUaKDCFQoBuyG1WE/sr4F5Y3RBsXwWKbHs
HR11ghexB7RJpWLCKd8ZT40mxOhRS0C3akLIiOaqLZuCRjwhr5ULItQBw8mjwtWS
Ji+IQxvCF7D8T38HzEuzp+QLZ/fMMTEKPVUos6abOyxXzjGER+hZmJY2z/QZVnrG
MRl5GdQ0c2tLSqz2mTIwJKEUqxm7B2ocHcjbTFZ4q1cktzsFphx0hzsjX8CqNlll
SytrvKcYlYtHewQhMe5luKLRoS/4j5/LI4nmFhkbyey8tFPGq3gLBXtym7h7nZwD
BcOgN/B7CFm2xVI5BW+yCb+FjjblKAqqQ5JzmIwSlFtlPqrWn8/jqyw2zzrQQtIg
xk48fdLCxxu1oAm7sHzktRlXI8DSHLasY1ywflbBBlzpnc17yevTJZRAfWrAXNQL
QPOiR/H1TMgGFtcbBGwzuirKQXBLXLrCXr0ikhRoINE8ayVlmV7cmfN1wS6lZ9gB
ulnKhOOmcebTYa0WO20iFSzwC2unyzx8ZjtAhtJQk5Q4vmcAfxlAe8WAbE3IoKCA
bTXYPwZagBFRuu45tM5YNygzDW8nwgVRKVowMauJpuQ4zHBWmGl4lL9EZ2pqEjJh
uU11Oh2yAt2XF7PBV/uTfrLrMo9MKypMiSOrwryDpgJxiLxEI+a3PtKkWWVFyIjn
Y9qwWJPpwGL6sOqbfYfRVUtoOLImhyGUbI86OUdIdGrVj9HJKkzntd1xjNO5L0uM
I42DIGsHAHzQlD50frjHbMucLhg8fhVm+oEZ4VrD4NUu1vgdoK8UjyMKLU43NbCg
d3lKtKWu
-----END PUBLIC KEY-----

View File

@ -0,0 +1,55 @@
-----BEGIN PRIVATE KEY-----
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
N+A=
-----END PRIVATE KEY-----

View File

@ -0,0 +1,53 @@
-----BEGIN PRIVATE KEY-----
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
FoBsHg0+HRLIWO3Nx5OwGhsUToPjfW0OWIU34A==
-----END PRIVATE KEY-----

View File

@ -0,0 +1,4 @@
-----BEGIN PRIVATE KEY-----
MFQCAQAwCwYJYIZIAWUDBAQCBEKAQJE38nuuXNtBM+E9aw7+WLAv5C3sXzcTUB0W
aIQCz9zoYY44sBaAbB4NPh0SyFjtzceTsBobFE6D431tDliFN+A=
-----END PRIVATE KEY-----

View File

@ -0,0 +1,28 @@
-----BEGIN PUBLIC KEY-----
MIIEsjALBglghkgBZQMEBAIDggShAM/VP4GYGoswjpq6iE4SMI0aryZTvFKBSlay
d4TkPlJ6vYzChzCcMbBswyzgMrvmlW0LSeLJYZ/CrV1HxdepZ9ncRdnLyQ5VB0K6
yyi4qTCgMeSiYfGDMDISc1MKEckhxorQopIEQzEKMyfki5omXeFGOln2kS9kR2DZ
EVsUvSO4iHoFtyxXP6/lKj97nsOnXF0FymDozINbvTWIPwyzun+rwfNEJ8SSPYjH
sypokB2kqJFhbk7GM8x0HG7CIOmKAhr0kEJ0oc4USSXYVBcaE2ZsWQAWhidcltBJ
ezfwVqiwZQFTxmychirzkOD6LNIxjO/RrP1DmyX0cpExSuk4vXxgE51UvfJSbvX5
GwmBmU7Hm6rxRA+hnvkHDLuTU7RohrA8g2OoqjbEta6nwPpCfkmqFg7qHAFBapER
xtZ1ZhGRuMRWZwI5bDtnbog7w+wqxOgjX1UWmqcmYfEGz15lXuREB9IxGTjXOiO2
zni2s50qwnLctcaBdrQooMTkDG68ZZ0mp62YIrAabK8VVqYkA9zlw8OHvZ41oIhC
YYT3BSaVmEtVtErlKFSZFE+skfqbpPxDavdgnul1hYq1cB8lphgmovmnJdfykoRS
QvwHLh1UC1gAiRsciFUsEBKTE4dQfLI0esFWnwiSpNHkzbqkMAoHfZu1CivsutVM
aTfUa8X3wZypXIaTCZGqIpiMVIRBKU9Ti4dmaNECHmMFp+dicQzoexZRj2eDfGsb
BG81SgMTLoh1sR/mSU2lmVM4yvlZlvlpjHSQnwmhetw8Bi02HVogYdyGKikRMetb
CU/BdwrJJy/5jCy5R59mey9Zc7X1bTl3JKGEeZsDdcm8J5K8Sf6Tqr/BoG5RFNRk
JwYxxgXWhPLBrKhZg5/6z0pqi9i6Zr/3uNS0I+xsW/FzTLQKg6DjNAgReClHD5o5
vl42UgyThVcaHOzXGFpFosm5lvUUk4FQHc2JHqewgIoajA/0dHohqnoVgtWUwef5
pCYbLW1soye0LOm3Zc6sv4VnXmXkMvbBsZzchf5YpNqnxgCky8ElYScwZ49qZ4AS
omFJqvDMZdj4N8Y1V+98rOdYF193xEtSwlrlxlbcfXW5Z2EgNizgmaqmcGV1jzVg
pBL0mEMsBzPkcDdnWp+Be79Tud23A9oixjsVzvfpu2zAe7ccKQUXUuWiw/VSY2Ap
p8pnFxjkF/bUnbLXXV+6OVHwesa2XlyoPhTMmLZwMzPHidr2Z9fiGMlqIpa8z8X7
Qn9rlVPcNgS2ZiwnR7z0T7SJxSfEvNNigwbyYSa1AJh4KCPbqK40sDm6A6Y6yADa
aIv7eyKaIktUQJKHw8E8cv8HF7dpAUNWh0qAYbpGiI2WQgcIZRNxPq3Gi6bVH8Bp
IN11C3C7sYNxfhkjWFlQH37kEvqFJyK2Tpgqwk98ZOLSM8uEF9j5Q6bqGI5grCUE
OqOoH5k2DWc3yGfoRKMcHxXhsgzWWY/qcoG6WjomNrdXchNCOjzKd5lCrBzJGl6Z
WKGBu7C8tUb4wCEhZJl8gus5goeZN0IQe2H8oAPqs9Gd3FGyH3s3CXWn4GqjMkfL
UrBsiiTt
-----END PUBLIC KEY-----

View File

@ -0,0 +1,86 @@
'use strict';
const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
const { hasOpenSSL } = require('../common/crypto');
const assert = require('assert');
const {
createPublicKey,
createPrivateKey,
} = require('crypto');
const fixtures = require('../common/fixtures');
function getKeyFileName(type, suffix) {
return `${type.replaceAll('-', '_')}_${suffix}.pem`;
}
for (const asymmetricKeyType of ['ml-kem-512', 'ml-kem-768', 'ml-kem-1024']) {
const keys = {
public: fixtures.readKey(getKeyFileName(asymmetricKeyType, 'public'), 'ascii'),
private: fixtures.readKey(getKeyFileName(asymmetricKeyType, 'private'), 'ascii'),
private_seed_only: fixtures.readKey(getKeyFileName(asymmetricKeyType, 'private_seed_only'), 'ascii'),
private_priv_only: fixtures.readKey(getKeyFileName(asymmetricKeyType, 'private_priv_only'), 'ascii'),
};
function assertKey(key) {
assert.deepStrictEqual(key.asymmetricKeyDetails, {});
assert.strictEqual(key.asymmetricKeyType, asymmetricKeyType);
assert.strictEqual(key.equals(key), true);
assert.deepStrictEqual(key, key);
}
function assertPublicKey(key) {
assertKey(key);
assert.strictEqual(key.type, 'public');
assert.strictEqual(key.export({ format: 'pem', type: 'spki' }), keys.public);
key.export({ format: 'der', type: 'spki' });
assert.throws(() => key.export({ format: 'jwk' }),
{ code: 'ERR_CRYPTO_JWK_UNSUPPORTED_KEY_TYPE', message: 'Unsupported JWK Key Type.' });
}
function assertPrivateKey(key, hasSeed) {
assertKey(key);
assert.strictEqual(key.type, 'private');
assertPublicKey(createPublicKey(key));
key.export({ format: 'der', type: 'pkcs8' });
if (hasSeed) {
assert.strictEqual(key.export({ format: 'pem', type: 'pkcs8' }), keys.private);
} else {
assert.strictEqual(key.export({ format: 'pem', type: 'pkcs8' }), keys.private_priv_only);
}
assert.throws(() => key.export({ format: 'jwk' }),
{ code: 'ERR_CRYPTO_JWK_UNSUPPORTED_KEY_TYPE', message: 'Unsupported JWK Key Type.' });
}
if (!hasOpenSSL(3, 5)) {
assert.throws(() => createPublicKey(keys.public), {
code: hasOpenSSL(3) ? 'ERR_OSSL_EVP_DECODE_ERROR' : 'ERR_OSSL_EVP_UNSUPPORTED_ALGORITHM',
});
for (const pem of [keys.private, keys.private_seed_only, keys.private_priv_only]) {
assert.throws(() => createPrivateKey(pem), {
code: hasOpenSSL(3) ? 'ERR_OSSL_UNSUPPORTED' : 'ERR_OSSL_EVP_UNSUPPORTED_ALGORITHM',
});
}
} else {
const publicKey = createPublicKey(keys.public);
assertPublicKey(publicKey);
{
for (const [pem, hasSeed] of [
[keys.private, true],
[keys.private_seed_only, true],
[keys.private_priv_only, false],
]) {
const pubFromPriv = createPublicKey(pem);
assertPublicKey(pubFromPriv);
assertPrivateKey(createPrivateKey(pem), hasSeed);
assert.strictEqual(pubFromPriv.equals(publicKey), true);
}
}
}
}

View File

@ -0,0 +1,46 @@
'use strict';
const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
const { hasOpenSSL } = require('../common/crypto');
const assert = require('assert');
const {
generateKeyPair,
} = require('crypto');
if (!hasOpenSSL(3, 5)) {
for (const asymmetricKeyType of ['ml-kem-512', 'ml-kem-768', 'ml-kem-1024']) {
assert.throws(() => generateKeyPair(asymmetricKeyType, common.mustNotCall()), {
code: 'ERR_INVALID_ARG_VALUE',
message: /The argument 'type' must be a supported key type/
});
}
} else {
for (const asymmetricKeyType of ['ml-kem-512', 'ml-kem-768', 'ml-kem-1024']) {
for (const [publicKeyEncoding, validate] of [
[undefined, (publicKey) => {
assert.strictEqual(publicKey.type, 'public');
assert.strictEqual(publicKey.asymmetricKeyType, asymmetricKeyType);
assert.deepStrictEqual(publicKey.asymmetricKeyDetails, {});
}],
[{ format: 'pem', type: 'spki' }, (publicKey) => assert.strictEqual(typeof publicKey, 'string')],
[{ format: 'der', type: 'spki' }, (publicKey) => assert.strictEqual(Buffer.isBuffer(publicKey), true)],
]) {
generateKeyPair(asymmetricKeyType, { publicKeyEncoding }, common.mustSucceed(validate));
}
for (const [privateKeyEncoding, validate] of [
[undefined, (_, privateKey) => {
assert.strictEqual(privateKey.type, 'private');
assert.strictEqual(privateKey.asymmetricKeyType, asymmetricKeyType);
assert.deepStrictEqual(privateKey.asymmetricKeyDetails, {});
}],
[{ format: 'pem', type: 'pkcs8' }, (_, privateKey) => assert.strictEqual(typeof privateKey, 'string')],
[{ format: 'der', type: 'pkcs8' }, (_, privateKey) => assert.strictEqual(Buffer.isBuffer(privateKey), true)],
]) {
generateKeyPair(asymmetricKeyType, { privateKeyEncoding }, common.mustSucceed(validate));
}
}
}