Summary
Perry has useful KeyObject-compatible surrogates for selected crypto flows, but it does not expose Node's crypto.KeyObject class/static surface or the full KeyObject#toCryptoKey() conversion behavior. This leaves feature checks such as typeof crypto.KeyObject, typeof crypto.KeyObject.from, key instanceof crypto.KeyObject, and asymmetric-key key.toCryptoKey(...) incompatible even when the underlying key operation itself works.
Evidence
Current Node documents KeyObject as an exported class, says createSecretKey(), createPublicKey(), and createPrivateKey() create KeyObject instances, documents KeyObject.from(key) for converting a CryptoKey back to a KeyObject, and documents keyObject.toCryptoKey(algorithm, extractable, keyUsages) returning a CryptoKey.
A local Node probe confirms the observable shape:
$ NO_COLOR=1 FORCE_COLOR=0 node keyobject-shape.js
typeof KeyObject: function
typeof KeyObject.from: function
secret instanceof KeyObject: true
secret type: secret
secret toCryptoKey typeof: function
private instanceof KeyObject: true
private type: private
private toCryptoKey typeof: function
public instanceof KeyObject: true
public type: public
public toCryptoKey typeof: function
KeyObject.from(CryptoKey) also returns an exportable KeyObject:
KeyObject.from CryptoKey type: secret
KeyObject.from CryptoKey instanceof: true
export hex: 000102030405060708090a0b0c0d0e0f
On origin/main, the manifest and native module value-read table expose crypto factories such as createSecretKey, createPrivateKey, and createPublicKey, but not crypto.KeyObject or crypto.KeyObject.from:
crates/perry-api-manifest/src/entries.rs has no class("crypto", "KeyObject") or method("crypto.KeyObject", "from", ...) entry.
docs/api/perry.d.ts exports ECDH, X509Certificate, Certificate, and crypto factory functions, but no KeyObject class.
crates/perry-runtime/src/object/native_module.rs lists many ("crypto", ...) value reads but no ("crypto", "KeyObject") entry.
The current runtime representation is intentionally surrogate-based:
crates/perry-stdlib/src/crypto/keys.rs comments state that createSecretKey() returns a marked BufferHeader even though Node returns a KeyObject.
crates/perry-stdlib/src/crypto/sign.rs and crates/perry-runtime/src/object/native_call_method.rs model asymmetric KeyObjects as string-backed PEM/internal surrogates for export/sign/verify flows.
crates/perry-runtime/src/object/buffer_dispatch.rs dispatches toCryptoKey only when crate::buffer::is_secret_key(addr) is true; string-backed asymmetric key surrogates have export and equals dispatch, but no toCryptoKey path.
test-parity/node-suite/crypto/README.md lists exact CryptoKey / KeyObject.toCryptoKey() asymmetric object identity/prototype behavior as known follow-up work.
Expected compatibility
Perry should provide Node-compatible KeyObject API shape around the existing key implementations:
crypto.KeyObject is exported as a class-like value with KeyObject.from(CryptoKey).
- keys returned by
createSecretKey(), createPrivateKey(), createPublicKey(), generateKeySync(), and generateKeyPairSync() have Node-compatible instanceof crypto.KeyObject behavior where feasible.
KeyObject.from() converts supported CryptoKey values back to exportable KeyObject-compatible values.
keyObject.toCryptoKey() works for supported asymmetric KeyObjects as well as the existing secret-key path, with Node-compatible algorithm/use validation.
Notes
This is separate from #2480's encrypted PEM/DER import/export option work, #2518's WebCrypto algorithm expansion, and #2552's util.types.isKeyObject() predicate tracker. I could not run a fresh Perry binary in this issue-creator checkout; confirmation is from origin/main source, current Node docs, current parity README notes, and local Node probes.
Summary
Perry has useful KeyObject-compatible surrogates for selected crypto flows, but it does not expose Node's
crypto.KeyObjectclass/static surface or the fullKeyObject#toCryptoKey()conversion behavior. This leaves feature checks such astypeof crypto.KeyObject,typeof crypto.KeyObject.from,key instanceof crypto.KeyObject, and asymmetric-keykey.toCryptoKey(...)incompatible even when the underlying key operation itself works.Evidence
Current Node documents
KeyObjectas an exported class, sayscreateSecretKey(),createPublicKey(), andcreatePrivateKey()createKeyObjectinstances, documentsKeyObject.from(key)for converting aCryptoKeyback to aKeyObject, and documentskeyObject.toCryptoKey(algorithm, extractable, keyUsages)returning aCryptoKey.A local Node probe confirms the observable shape:
KeyObject.from(CryptoKey)also returns an exportableKeyObject:On
origin/main, the manifest and native module value-read table expose crypto factories such ascreateSecretKey,createPrivateKey, andcreatePublicKey, but notcrypto.KeyObjectorcrypto.KeyObject.from:crates/perry-api-manifest/src/entries.rshas noclass("crypto", "KeyObject")ormethod("crypto.KeyObject", "from", ...)entry.docs/api/perry.d.tsexportsECDH,X509Certificate,Certificate, and crypto factory functions, but noKeyObjectclass.crates/perry-runtime/src/object/native_module.rslists many("crypto", ...)value reads but no("crypto", "KeyObject")entry.The current runtime representation is intentionally surrogate-based:
crates/perry-stdlib/src/crypto/keys.rscomments state thatcreateSecretKey()returns a markedBufferHeadereven though Node returns aKeyObject.crates/perry-stdlib/src/crypto/sign.rsandcrates/perry-runtime/src/object/native_call_method.rsmodel asymmetric KeyObjects as string-backed PEM/internal surrogates for export/sign/verify flows.crates/perry-runtime/src/object/buffer_dispatch.rsdispatchestoCryptoKeyonly whencrate::buffer::is_secret_key(addr)is true; string-backed asymmetric key surrogates haveexportandequalsdispatch, but notoCryptoKeypath.test-parity/node-suite/crypto/README.mdlists exactCryptoKey/KeyObject.toCryptoKey()asymmetric object identity/prototype behavior as known follow-up work.Expected compatibility
Perry should provide Node-compatible KeyObject API shape around the existing key implementations:
crypto.KeyObjectis exported as a class-like value withKeyObject.from(CryptoKey).createSecretKey(),createPrivateKey(),createPublicKey(),generateKeySync(), andgenerateKeyPairSync()have Node-compatibleinstanceof crypto.KeyObjectbehavior where feasible.KeyObject.from()converts supportedCryptoKeyvalues back to exportable KeyObject-compatible values.keyObject.toCryptoKey()works for supported asymmetric KeyObjects as well as the existing secret-key path, with Node-compatible algorithm/use validation.Notes
This is separate from #2480's encrypted PEM/DER import/export option work, #2518's WebCrypto algorithm expansion, and #2552's
util.types.isKeyObject()predicate tracker. I could not run a fresh Perry binary in this issue-creator checkout; confirmation is fromorigin/mainsource, current Node docs, current parity README notes, and local Node probes.