# Implementation Coverage - NodeJS This document attempts to describe the implementation status of Crypto APIs/Interfaces from Node.js in the `react-native-quick-crypto` library. > Note: This is the status for version 1.x and higher. For version `0.x` see [this document](https://github.com/margelo/react-native-quick-crypto/blob/0.x/docs/implementation-coverage.md) and the [0.x branch](https://github.com/margelo/react-native-quick-crypto/tree/0.x). - ` ` - not implemented in Node - ❌ - implemented in Node, not RNQC - ✅ - implemented in Node and RNQC - ✨ - implemented in RNQC, not in Node (RNQC extension) - 🚧 - work in progress - `-` - not applicable to React Native ## Post-Quantum Cryptography (PQC) - **ML-DSA** (Module Lattice Digital Signature Algorithm, FIPS 204) - ML-DSA-44, ML-DSA-65, ML-DSA-87 - **ML-KEM** (Module Lattice Key Encapsulation Mechanism, FIPS 203) - ML-KEM-512, ML-KEM-768, ML-KEM-1024 - **SLH-DSA** (Stateless Hash-Based Digital Signature, FIPS 205) - SLH-DSA-SHA2-{128,192,256}{s,f}, SLH-DSA-SHAKE-{128,192,256}{s,f} These algorithms provide quantum-resistant cryptography. # `Crypto` - ✅ Class: `Certificate` - ✅ Static method: `Certificate.exportChallenge(spkac[, encoding])` - ✅ Static method: `Certificate.exportPublicKey(spkac[, encoding])` - ✅ Static method: `Certificate.verifySpkac(spkac[, encoding])` - ✅ Class: `Cipheriv` - ✅ `cipher.final([outputEncoding])` - ✅ `cipher.getAuthTag()` - ✅ `cipher.setAAD(buffer[, options])` - ✅ `cipher.setAutoPadding([autoPadding])` - ✅ `cipher.update(data[, inputEncoding][, outputEncoding])` - ✅ Class: `Decipheriv` - ✅ `decipher.final([outputEncoding])` - ✅ `decipher.setAAD(buffer[, options])` - ✅ `decipher.setAuthTag(buffer[, encoding])` - ✅ `decipher.setAutoPadding([autoPadding])` - ✅ `decipher.update(data[, inputEncoding][, outputEncoding])` - ✅ Class: `DiffieHellman` - ✅ `diffieHellman.computeSecret(otherPublicKey[, inputEncoding][, outputEncoding])` - ✅ `diffieHellman.generateKeys([encoding])` - ✅ `diffieHellman.getGenerator([encoding])` - ✅ `diffieHellman.getPrime([encoding])` - ✅ `diffieHellman.getPrivateKey([encoding])` - ✅ `diffieHellman.getPublicKey([encoding])` - ✅ `diffieHellman.setPrivateKey(privateKey[, encoding])` - ✅ `diffieHellman.setPublicKey(publicKey[, encoding])` - ✅ `diffieHellman.verifyError` - ✅ Class: `DiffieHellmanGroup` - ✅ Class: `ECDH` - ✅ static `ECDH.convertKey(key, curve[, inputEncoding[, outputEncoding[, format]]])` - ✅ `ecdh.computeSecret(otherPublicKey[, inputEncoding][, outputEncoding])` - ✅ `ecdh.generateKeys([encoding[, format]])` - ✅ `ecdh.getPrivateKey([encoding])` - ✅ `ecdh.getPublicKey([encoding][, format])` - ✅ `ecdh.setPrivateKey(privateKey[, encoding])` - ✅ `ecdh.setPublicKey(publicKey[, encoding])` - ✅ Class: `Hash` - ✅ `hash.copy([options])` - ✅ `hash.digest([encoding])` - ✅ `hash.update(data[, inputEncoding])` - ✅ Class: `Hmac` - ✅ `hmac.digest([encoding])` - ✅ `hmac.update(data[, inputEncoding])` - ✅ Class: `KeyObject` - ✅ static `KeyObject.from(key)` - ✅ `keyObject.asymmetricKeyDetails` - ✅ `keyObject.asymmetricKeyType` - ✅ `keyObject.export([options])` - ✅ `keyObject.equals(otherKeyObject)` - ✅ `keyObject.symmetricKeySize` - ✅ `keyObject.toCryptoKey(algorithm, extractable, keyUsages)` - ✅ `keyObject.type` - ✅ Class: `Sign` - ✅ `sign.sign(privateKey[, outputEncoding])` - ✅ `sign.update(data[, inputEncoding])` - ✅ Class: `Verify` - ✅ `verify.update(data[, inputEncoding])` - ✅ `verify.verify(object, signature[, signatureEncoding])` - ✅ Class: `X509Certificate` - ✅ `new X509Certificate(buffer)` - ✅ `x509.ca` - ✅ `x509.checkEmail(email[, options])` - ✅ `x509.checkHost(name[, options])` - ✅ `x509.checkIP(ip)` - ✅ `x509.checkIssued(otherCert)` - ✅ `x509.checkPrivateKey(privateKey)` - ✅ `x509.fingerprint` - ✅ `x509.fingerprint256` - ✅ `x509.fingerprint512` - ✅ `x509.infoAccess` - ✅ `x509.issuer` - ✅ `x509.issuerCertificate` - ✅ `x509.extKeyUsage` - ✅ `x509.keyUsage` - ✅ `x509.signatureAlgorithm` - ✅ `x509.signatureAlgorithmOid` - ✅ `x509.publicKey` - ✅ `x509.raw` - ✅ `x509.serialNumber` - ✅ `x509.subject` - ✅ `x509.subjectAltName` - ✅ `x509.toJSON()` - ✅ `x509.toLegacyObject()` - ✅ `x509.toString()` - ✅ `x509.validFrom` - ✅ `x509.validTo` - ✅ `x509.verify(publicKey)` - ✅ node:crypto module methods and properties - ✅ `crypto.argon2(algorithm, parameters, callback)` - ✅ `crypto.argon2Sync(algorithm, parameters)` - ✅ `crypto.checkPrime(candidate[, options], callback)` - ✅ `crypto.checkPrimeSync(candidate[, options])` - ✅ `crypto.constants` - ✅ `crypto.createCipheriv(algorithm, key, iv[, options])` - ✅ `crypto.createDecipheriv(algorithm, key, iv[, options])` - ✅ `crypto.createDiffieHellman(prime[, primeEncoding][, generator][, generatorEncoding])` - ✅ `crypto.createDiffieHellman(primeLength[, generator])` - ✅ `crypto.createDiffieHellmanGroup(groupName)` - ✅ `crypto.getDiffieHellman(groupName)` - ✅ `crypto.createECDH(curveName)` - ✅ `crypto.createHash(algorithm[, options])` - ✅ `crypto.createHmac(algorithm, key[, options])` - ✅ `crypto.createPrivateKey(key)` - ✅ `crypto.createPublicKey(key)` - ✅ `crypto.createSecretKey(key[, encoding])` - ✅ `crypto.createSign(algorithm[, options])` - ✅ `crypto.createVerify(algorithm[, options])` - ✅ `crypto.decapsulate(key, ciphertext[, callback])` - ✅ `crypto.diffieHellman(options[, callback])` - ✅ `crypto.encapsulate(key[, callback])` - `-` `crypto.fips` deprecated, not applicable to RN - ✅ `crypto.generateKey(type, options, callback)` - ✅ `crypto.generateKeyPair(type, options, callback)` - ✅ `crypto.generateKeyPairSync(type, options)` - ✅ `crypto.generateKeySync(type, options)` - ✅ `crypto.generatePrime(size[, options[, callback]])` - ✅ `crypto.generatePrimeSync(size[, options])` - ✅ `crypto.getCipherInfo(nameOrNid[, options])` - ✅ `crypto.getCiphers()` - ✅ `crypto.getCurves()` - `-` `crypto.getFips()` not applicable to RN - ✅ `crypto.getHashes()` - ✅ `crypto.getRandomValues(typedArray)` - ✅ `crypto.hash(algorithm, data[, outputEncoding])` - ✅ `crypto.hkdf(digest, ikm, salt, info, keylen, callback)` - ✅ `crypto.hkdfSync(digest, ikm, salt, info, keylen)` - ✨ `crypto.hkdfExtract(digest, ikm, salt, callback)` (RFC 5869 Extract-only) - ✨ `crypto.hkdfExtractSync(digest, ikm[, salt])` (RFC 5869 Extract-only) - ✨ `crypto.hkdfExpand(digest, prk, info, keylen, callback)` (RFC 5869 Expand-only) - ✨ `crypto.hkdfExpandSync(digest, prk, info, keylen)` (RFC 5869 Expand-only) - ✅ `crypto.pbkdf2(password, salt, iterations, keylen, digest, callback)` - ✅ `crypto.pbkdf2Sync(password, salt, iterations, keylen, digest)` - ✅ `crypto.privateDecrypt(privateKey, buffer)` - ✅ `crypto.privateEncrypt(privateKey, buffer)` - ✅ `crypto.publicDecrypt(key, buffer)` - ✅ `crypto.publicEncrypt(key, buffer)` - ✅ `crypto.randomBytes(size[, callback])` - ✅ `crypto.randomFill(buffer[, offset][, size], callback)` - ✅ `crypto.randomFillSync(buffer[, offset][, size])` - ✅ `crypto.randomInt([min, ]max[, callback])` - ✅ `crypto.randomUUID([options])` - ✅ `crypto.randomUUIDv7([options])` - ✅ `crypto.scrypt(password, salt, keylen[, options], callback)` - ✅ `crypto.scryptSync(password, salt, keylen[, options])` - `-` `crypto.secureHeapUsed()` not applicable to RN - `-` `crypto.setEngine(engine[, flags])` not applicable to RN - `-` `crypto.setFips(bool)` not applicable to RN - ✅ `crypto.sign(algorithm, data, key[, callback])` - ✅ `crypto.subtle` (see below) - ✅ `crypto.timingSafeEqual(a, b)` - ✅ `crypto.verify(algorithm, data, key, signature[, callback])` - ✅ `crypto.webcrypto` (see below) ## `crypto.diffieHellman` | type | Status | | -------- | :----: | | `dh` | ✅ | | `ec` | ✅ | | `x448` | ✅ | | `x25519` | ✅ | ## `crypto.generateKey` | type | Status | | ------ | :----: | | `aes` | ✅ | | `hmac` | ✅ | ## `crypto.generateKeyPair` | type | Status | | -------------------- | :----: | | `rsa` | ✅ | | `rsa-pss` | ✅ | | `dsa` | ✅ | | `ec` | ✅ | | `ed25519` | ✅ | | `ed448` | ✅ | | `x25519` | ✅ | | `x448` | ✅ | | `dh` | ✅ | | `slh-dsa-sha2-128s` | ✅ | | `slh-dsa-sha2-128f` | ✅ | | `slh-dsa-sha2-192s` | ✅ | | `slh-dsa-sha2-192f` | ✅ | | `slh-dsa-sha2-256s` | ✅ | | `slh-dsa-sha2-256f` | ✅ | | `slh-dsa-shake-128s` | ✅ | | `slh-dsa-shake-128f` | ✅ | | `slh-dsa-shake-192s` | ✅ | | `slh-dsa-shake-192f` | ✅ | | `slh-dsa-shake-256s` | ✅ | | `slh-dsa-shake-256f` | ✅ | ## `crypto.generateKeyPairSync` | type | Status | | -------------------- | :----: | | `rsa` | ✅ | | `rsa-pss` | ✅ | | `dsa` | ✅ | | `ec` | ✅ | | `ed25519` | ✅ | | `ed448` | ✅ | | `x25519` | ✅ | | `x448` | ✅ | | `dh` | ✅ | | `slh-dsa-sha2-128s` | ✅ | | `slh-dsa-sha2-128f` | ✅ | | `slh-dsa-sha2-192s` | ✅ | | `slh-dsa-sha2-192f` | ✅ | | `slh-dsa-sha2-256s` | ✅ | | `slh-dsa-sha2-256f` | ✅ | | `slh-dsa-shake-128s` | ✅ | | `slh-dsa-shake-128f` | ✅ | | `slh-dsa-shake-192s` | ✅ | | `slh-dsa-shake-192f` | ✅ | | `slh-dsa-shake-256s` | ✅ | | `slh-dsa-shake-256f` | ✅ | ## `crypto.generateKeySync` | type | Status | | ------ | :----: | | `aes` | ✅ | | `hmac` | ✅ | ## `crypto.sign` | Algorithm | Status | | -------------------- | :----: | | `RSASSA-PKCS1-v1_5` | ✅ | | `RSA-PSS` | ✅ | | `ECDSA` | ✅ | | `Ed25519` | ✅ | | `Ed448` | ✅ | | `HMAC` | ✅ | | `SLH-DSA-SHA2-128s` | ✅ | | `SLH-DSA-SHA2-128f` | ✅ | | `SLH-DSA-SHA2-192s` | ✅ | | `SLH-DSA-SHA2-192f` | ✅ | | `SLH-DSA-SHA2-256s` | ✅ | | `SLH-DSA-SHA2-256f` | ✅ | | `SLH-DSA-SHAKE-128s` | ✅ | | `SLH-DSA-SHAKE-128f` | ✅ | | `SLH-DSA-SHAKE-192s` | ✅ | | `SLH-DSA-SHAKE-192f` | ✅ | | `SLH-DSA-SHAKE-256s` | ✅ | | `SLH-DSA-SHAKE-256f` | ✅ | ## `crypto.verify` | Algorithm | Status | | -------------------- | :----: | | `RSASSA-PKCS1-v1_5` | ✅ | | `RSA-PSS` | ✅ | | `ECDSA` | ✅ | | `Ed25519` | ✅ | | `Ed448` | ✅ | | `HMAC` | ✅ | | `SLH-DSA-SHA2-128s` | ✅ | | `SLH-DSA-SHA2-128f` | ✅ | | `SLH-DSA-SHA2-192s` | ✅ | | `SLH-DSA-SHA2-192f` | ✅ | | `SLH-DSA-SHA2-256s` | ✅ | | `SLH-DSA-SHA2-256f` | ✅ | | `SLH-DSA-SHAKE-128s` | ✅ | | `SLH-DSA-SHAKE-128f` | ✅ | | `SLH-DSA-SHAKE-192s` | ✅ | | `SLH-DSA-SHAKE-192f` | ✅ | | `SLH-DSA-SHAKE-256s` | ✅ | | `SLH-DSA-SHAKE-256f` | ✅ | ## Extended Ciphers (Beyond Node.js API) These ciphers are **not available in Node.js** but are provided by RNQC via libsodium for mobile use cases requiring extended nonces. | Cipher | Key | Nonce | Tag | AAD | Notes | | -------------------- | :-: | :---: | :-: | :-: | ------------------------------------ | | `xchacha20-poly1305` | 32B | 24B | 16B | ✅ | AEAD with extended nonce | | `xsalsa20-poly1305` | 32B | 24B | 16B | ❌ | Authenticated encryption (secretbox) | | `xsalsa20` | 32B | 24B | - | - | Stream cipher (no authentication) | > **Note:** These ciphers require `SODIUM_ENABLED=1` on both iOS and Android. # `WebCrypto` - ✅ Class: `Crypto` - ✅ `crypto.subtle` - ✅ `crypto.getRandomValues(typedArray)` - ✅ `crypto.randomUUID()` - ✅ `crypto.randomUUIDv7()` _(extension; not in WebCrypto spec)_ - ✅ Class: `CryptoKey` - ✅ `cryptoKey.algorithm` - ✅ `cryptoKey.extractable` - ✅ `cryptoKey.type` - ✅ `cryptoKey.usages` - ✅ Class: `CryptoKeyPair` - ✅ `cryptoKeyPair.privateKey` - ✅ `cryptoKeyPair.publicKey` - ✅ Class: `CryptoSubtle` - (see below) # `SubtleCrypto` - ✅ Class: `SubtleCrypto` - ✅ static `supports(operation, algorithm[, lengthOrAdditionalAlgorithm])` - ✅ `subtle.decapsulateBits(decapsulationAlgorithm, decapsulationKey, ciphertext)` - ✅ `subtle.decapsulateKey(decapsulationAlgorithm, decapsulationKey, ciphertext, sharedKeyAlgorithm, extractable, usages)` - ✅ `subtle.decrypt(algorithm, key, data)` - ✅ `subtle.deriveBits(algorithm, baseKey, length)` - ✅ `subtle.deriveKey(algorithm, baseKey, derivedKeyAlgorithm, extractable, keyUsages)` - ✅ `subtle.digest(algorithm, data)` - ✅ `subtle.encapsulateBits(encapsulationAlgorithm, encapsulationKey)` - ✅ `subtle.encapsulateKey(encapsulationAlgorithm, encapsulationKey, sharedKeyAlgorithm, extractable, usages)` - ✅ `subtle.encrypt(algorithm, key, data)` - ✅ `subtle.exportKey(format, key)` - ✅ `subtle.generateKey(algorithm, extractable, keyUsages)` - ✅ `subtle.getPublicKey(key, keyUsages)` - ✅ `subtle.importKey(format, keyData, algorithm, extractable, keyUsages)` - ✅ `subtle.sign(algorithm, key, data)` - ✅ `subtle.unwrapKey(format, wrappedKey, unwrappingKey, unwrapAlgo, unwrappedKeyAlgo, extractable, keyUsages)` - ✅ `subtle.verify(algorithm, key, signature, data)` - ✅ `subtle.wrapKey(format, key, wrappingKey, wrapAlgo)` ## `subtle.decrypt` | Algorithm | Status | | ------------------- | :----: | | `RSA-OAEP` | ✅ | | `AES-CTR` | ✅ | | `AES-CBC` | ✅ | | `AES-GCM` | ✅ | | `AES-OCB` | ✅ | | `ChaCha20-Poly1305` | ✅ | ## `subtle.deriveBits` | Algorithm | Status | | ---------- | :----: | | `Argon2d` | ✅ | | `Argon2i` | ✅ | | `Argon2id` | ✅ | | `ECDH` | ✅ | | `X25519` | ✅ | | `X448` | ✅ | | `HKDF` | ✅ | | `PBKDF2` | ✅ | ## `subtle.deriveKey` | Algorithm | Status | | ---------- | :----: | | `Argon2d` | ✅ | | `Argon2i` | ✅ | | `Argon2id` | ✅ | | `ECDH` | ✅ | | `HKDF` | ✅ | | `PBKDF2` | ✅ | | `X25519` | ✅ | | `X448` | ✅ | ## `subtle.digest` | Algorithm | Status | | --------------- | :----: | | `cSHAKE128` | ✅ | | `cSHAKE256` | ✅ | | `KT128` | ✅ | | `KT256` | ✅ | | `SHA-1` | ✅ | | `SHA-256` | ✅ | | `SHA-384` | ✅ | | `SHA-512` | ✅ | | `SHA3-256` | ✅ | | `SHA3-384` | ✅ | | `SHA3-512` | ✅ | | `TurboSHAKE128` | ✅ | | `TurboSHAKE256` | ✅ | > **Note:** `cSHAKE128` and `cSHAKE256` provide SHAKE128/SHAKE256 (XOF) functionality with empty customization, matching Node.js behavior. The `outputLength` parameter (in bytes, must be a multiple of 8) is required to specify the output length. > > **TurboSHAKE128/256** (RFC 9861) and **KangarooTwelve** (`KT128`, `KT256`) are extendable-output functions (XOFs) requiring an `outputLength` parameter. TurboSHAKE additionally accepts a `domainSeparation` byte; KangarooTwelve accepts a `customization` byte string. ## `subtle.encrypt` | Algorithm | Status | | ------------------- | :----: | | `AES-CTR` | ✅ | | `AES-CBC` | ✅ | | `AES-GCM` | ✅ | | `AES-OCB` | ✅ | | `ChaCha20-Poly1305` | ✅ | | `RSA-OAEP` | ✅ | ## `subtle.exportKey` | Key Type | `spki` | `pkcs8` | `jwk` | `raw` | `raw-secret` | `raw-public` | `raw-seed` | | -------------------- | :----: | :-----: | :---: | :---: | :----------: | :----------: | :--------: | | `AES-CBC` | | | ✅ | ✅ | ✅ | | | | `AES-CTR` | | | ✅ | ✅ | ✅ | | | | `AES-GCM` | | | ✅ | ✅ | ✅ | | | | `AES-KW` | | | ✅ | ✅ | ✅ | | | | `AES-OCB` | | | ✅ | ✅ | ✅ | | | | `ChaCha20-Poly1305` | | | ✅ | | ✅ | | | | `ECDH` | ✅ | ✅ | ✅ | ✅ | | ✅ | | | `ECDSA` | ✅ | ✅ | ✅ | ✅ | | ✅ | | | `Ed25519` | ✅ | ✅ | ✅ | ✅ | | ✅ | | | `Ed448` | ✅ | ✅ | ✅ | ✅ | | ✅ | | | `HMAC` | | | ✅ | ✅ | ✅ | | | | `KMAC128` | | | ✅ | ✅ | ✅ | | | | `KMAC256` | | | ✅ | ✅ | ✅ | | | | `ML-DSA-44` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `ML-DSA-65` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `ML-DSA-87` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `ML-KEM-512` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `ML-KEM-768` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `ML-KEM-1024` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `RSA-OAEP` | ✅ | ✅ | ✅ | | | | | | `RSA-PSS` | ✅ | ✅ | ✅ | | | | | | `RSASSA-PKCS1-v1_5` | ✅ | ✅ | ✅ | | | | | | `SLH-DSA-SHA2-128s` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `SLH-DSA-SHA2-128f` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `SLH-DSA-SHA2-192s` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `SLH-DSA-SHA2-192f` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `SLH-DSA-SHA2-256s` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `SLH-DSA-SHA2-256f` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `SLH-DSA-SHAKE-128s` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `SLH-DSA-SHAKE-128f` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `SLH-DSA-SHAKE-192s` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `SLH-DSA-SHAKE-192f` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `SLH-DSA-SHAKE-256s` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `SLH-DSA-SHAKE-256f` | ✅ | ✅ | ❌ | | | ✅ | ✅ | - ` ` - not implemented in Node - ❌ - implemented in Node, not RNQC - ✅ - implemented in Node and RNQC ## `subtle.generateKey` ### `CryptoKeyPair` algorithms | Algorithm | Status | | -------------------- | :----: | | `ECDH` | ✅ | | `ECDSA` | ✅ | | `Ed25519` | ✅ | | `Ed448` | ✅ | | `ML-DSA-44` | ✅ | | `ML-DSA-65` | ✅ | | `ML-DSA-87` | ✅ | | `ML-KEM-512` | ✅ | | `ML-KEM-768` | ✅ | | `ML-KEM-1024` | ✅ | | `RSA-OAEP` | ✅ | | `RSA-PSS` | ✅ | | `RSASSA-PKCS1-v1_5` | ✅ | | `SLH-DSA-SHA2-128s` | ✅ | | `SLH-DSA-SHA2-128f` | ✅ | | `SLH-DSA-SHA2-192s` | ✅ | | `SLH-DSA-SHA2-192f` | ✅ | | `SLH-DSA-SHA2-256s` | ✅ | | `SLH-DSA-SHA2-256f` | ✅ | | `SLH-DSA-SHAKE-128s` | ✅ | | `SLH-DSA-SHAKE-128f` | ✅ | | `SLH-DSA-SHAKE-192s` | ✅ | | `SLH-DSA-SHAKE-192f` | ✅ | | `SLH-DSA-SHAKE-256s` | ✅ | | `SLH-DSA-SHAKE-256f` | ✅ | | `X25519` | ✅ | | `X448` | ✅ | ### `CryptoKey` algorithms | Algorithm | Status | | ------------------- | :----: | | `AES-CTR` | ✅ | | `AES-CBC` | ✅ | | `AES-GCM` | ✅ | | `AES-KW` | ✅ | | `AES-OCB` | ✅ | | `ChaCha20-Poly1305` | ✅ | | `HMAC` | ✅ | | `KMAC128` | ✅ | | `KMAC256` | ✅ | ## `subtle.importKey` | Key Type | `spki` | `pkcs8` | `jwk` | `raw` | `raw-secret` | `raw-public` | `raw-seed` | | -------------------- | :----: | :-----: | :---: | :---: | :----------: | :----------: | :--------: | | `Argon2d` | | | | | ✅ | | | | `Argon2i` | | | | | ✅ | | | | `Argon2id` | | | | | ✅ | | | | `AES-CBC` | | | ✅ | ✅ | ✅ | | | | `AES-CTR` | | | ✅ | ✅ | ✅ | | | | `AES-GCM` | | | ✅ | ✅ | ✅ | | | | `AES-KW` | | | ✅ | ✅ | ✅ | | | | `AES-OCB` | | | ✅ | ✅ | ✅ | | | | `ChaCha20-Poly1305` | | | ✅ | | ✅ | | | | `ECDH` | ✅ | ✅ | ✅ | ✅ | | ✅ | | | `ECDSA` | ✅ | ✅ | ✅ | ✅ | | ✅ | | | `Ed25519` | ✅ | ✅ | ✅ | ✅ | | ✅ | | | `Ed448` | ✅ | ✅ | ✅ | ✅ | | ✅ | | | `HKDF` | | | | ✅ | ✅ | | | | `HMAC` | | | ✅ | ✅ | ✅ | | | | `KMAC128` | | | ✅ | ✅ | ✅ | | | | `KMAC256` | | | ✅ | ✅ | ✅ | | | | `ML-DSA-44` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `ML-DSA-65` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `ML-DSA-87` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `ML-KEM-512` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `ML-KEM-768` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `ML-KEM-1024` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `PBKDF2` | | | | ✅ | ✅ | | | | `RSA-OAEP` | ✅ | ✅ | ✅ | | | | | | `RSA-PSS` | ✅ | ✅ | ✅ | | | | | | `RSASSA-PKCS1-v1_5` | ✅ | ✅ | ✅ | | | | | | `SLH-DSA-SHA2-128s` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `SLH-DSA-SHA2-128f` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `SLH-DSA-SHA2-192s` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `SLH-DSA-SHA2-192f` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `SLH-DSA-SHA2-256s` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `SLH-DSA-SHA2-256f` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `SLH-DSA-SHAKE-128s` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `SLH-DSA-SHAKE-128f` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `SLH-DSA-SHAKE-192s` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `SLH-DSA-SHAKE-192f` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `SLH-DSA-SHAKE-256s` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `SLH-DSA-SHAKE-256f` | ✅ | ✅ | ❌ | | | ✅ | ✅ | | `X25519` | ✅ | ✅ | ✅ | ✅ | | ✅ | | | `X448` | ✅ | ✅ | ✅ | ✅ | | ✅ | | ## `subtle.sign` | Algorithm | Status | | -------------------- | :----: | | `ECDSA` | ✅ | | `Ed25519` | ✅ | | `Ed448` | ✅ | | `HMAC` | ✅ | | `KMAC128` | ✅ | | `KMAC256` | ✅ | | `ML-DSA-44` | ✅ | | `ML-DSA-65` | ✅ | | `ML-DSA-87` | ✅ | | `RSA-PSS` | ✅ | | `RSASSA-PKCS1-v1_5` | ✅ | | `SLH-DSA-SHA2-128s` | ✅ | | `SLH-DSA-SHA2-128f` | ✅ | | `SLH-DSA-SHA2-192s` | ✅ | | `SLH-DSA-SHA2-192f` | ✅ | | `SLH-DSA-SHA2-256s` | ✅ | | `SLH-DSA-SHA2-256f` | ✅ | | `SLH-DSA-SHAKE-128s` | ✅ | | `SLH-DSA-SHAKE-128f` | ✅ | | `SLH-DSA-SHAKE-192s` | ✅ | | `SLH-DSA-SHAKE-192f` | ✅ | | `SLH-DSA-SHAKE-256s` | ✅ | | `SLH-DSA-SHAKE-256f` | ✅ | ## `subtle.unwrapKey` ### wrapping algorithms | Algorithm | Status | | ------------------- | :----: | | `AES-CBC` | ✅ | | `AES-CTR` | ✅ | | `AES-GCM` | ✅ | | `AES-KW` | ✅ | | `AES-OCB` | ✅ | | `ChaCha20-Poly1305` | ✅ | | `RSA-OAEP` | ✅ | ### unwrapped key algorithms | Algorithm | Status | | -------------------- | :----: | | `AES-CBC` | ✅ | | `AES-CTR` | ✅ | | `AES-GCM` | ✅ | | `AES-KW` | ✅ | | `AES-OCB` | ✅ | | `ChaCha20-Poly1305` | ✅ | | `ECDH` | ✅ | | `ECDSA` | ✅ | | `Ed25519` | ✅ | | `Ed448` | ✅ | | `HMAC` | ✅ | | `ML-DSA-44` | ✅ | | `ML-DSA-65` | ✅ | | `ML-DSA-87` | ✅ | | `ML-KEM-512` | ✅ | | `ML-KEM-768` | ✅ | | `ML-KEM-1024` | ✅ | | `RSA-OAEP` | ✅ | | `RSA-PSS` | ✅ | | `RSASSA-PKCS1-v1_5` | ✅ | | `SLH-DSA-SHA2-128s` | ✅ | | `SLH-DSA-SHA2-128f` | ✅ | | `SLH-DSA-SHA2-192s` | ✅ | | `SLH-DSA-SHA2-192f` | ✅ | | `SLH-DSA-SHA2-256s` | ✅ | | `SLH-DSA-SHA2-256f` | ✅ | | `SLH-DSA-SHAKE-128s` | ✅ | | `SLH-DSA-SHAKE-128f` | ✅ | | `SLH-DSA-SHAKE-192s` | ✅ | | `SLH-DSA-SHAKE-192f` | ✅ | | `SLH-DSA-SHAKE-256s` | ✅ | | `SLH-DSA-SHAKE-256f` | ✅ | | `X25519` | ✅ | | `X448` | ✅ | ## `subtle.verify` | Algorithm | Status | | -------------------- | :----: | | `ECDSA` | ✅ | | `Ed25519` | ✅ | | `Ed448` | ✅ | | `HMAC` | ✅ | | `KMAC128` | ✅ | | `KMAC256` | ✅ | | `ML-DSA-44` | ✅ | | `ML-DSA-65` | ✅ | | `ML-DSA-87` | ✅ | | `RSA-PSS` | ✅ | | `RSASSA-PKCS1-v1_5` | ✅ | | `SLH-DSA-SHA2-128s` | ✅ | | `SLH-DSA-SHA2-128f` | ✅ | | `SLH-DSA-SHA2-192s` | ✅ | | `SLH-DSA-SHA2-192f` | ✅ | | `SLH-DSA-SHA2-256s` | ✅ | | `SLH-DSA-SHA2-256f` | ✅ | | `SLH-DSA-SHAKE-128s` | ✅ | | `SLH-DSA-SHAKE-128f` | ✅ | | `SLH-DSA-SHAKE-192s` | ✅ | | `SLH-DSA-SHAKE-192f` | ✅ | | `SLH-DSA-SHAKE-256s` | ✅ | | `SLH-DSA-SHAKE-256f` | ✅ | ## `subtle.wrapKey` ### wrapping algorithms | Algorithm | Status | | ------------------- | :----: | | `AES-CBC` | ✅ | | `AES-CTR` | ✅ | | `AES-GCM` | ✅ | | `AES-KW` | ✅ | | `AES-OCB` | ✅ | | `ChaCha20-Poly1305` | ✅ | | `RSA-OAEP` | ✅ |