Modern Algorithms in the Web Cryptography API

Draft Community Group Report

Latest published version:
https://www.w3.org/webcrypto-modern-algos/
Latest editor's draft:
https://twiss.github.io/webcrypto-modern-algos/
Editor:
(Proton AG)
Feedback:
GitHub twiss/webcrypto-modern-algos (pull requests, new issue, open issues)

Abstract

This specification defines a number of post-quantum secure and modern cryptographic algorithms for the Web Cryptography API, namely ML-KEM, ML-DSA, SLH-DSA, AES-OCB, ChaCha20-Poly1305, SHA-3, cSHAKE, KMAC, and Argon2.

Status of This Document

This specification was published by the Web Platform Incubator Community Group. It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Contributor License Agreement (CLA) there is a limited opt-out and other conditions apply. Learn more about W3C Community and Business Groups.

This is an unofficial proposal.

GitHub Issues are preferred for discussion of this specification.

1. Introduction

This section is non-normative.

This proposal aims to modernize the set of cryptographic algorithms available in the Web Cryptography API, such that web applications can make use of post-quantum secure and performant cryptographic algorithms. To this end, the following cryptographic algorithms are added:

Additionally, this proposal introduces functions for key encapsulation and decapsulation; SubtleCrypto.encapsulateKey, SubtleCrypto.encapsulateBits, SubtleCrypto.decapsulateKey and SubtleCrypto.decapsulateBits.

Finally, this proposal aims to make feature detection easier, by adding a SubtleCrypto.supports function, which can be used to detect whether a given algorithm identifier (including any parameters) is supported for the given operation.

2. Specification Conventions

This specification follows the conventions laid out in Section 18.3 of [WebCryptoAPI]. None of the algorithms defined here are required to be implemented, but if a conforming User Agent implements an algorithm, it MUST implement all of the supported operations specified in this document, and must perform the steps to define an algorithm specified in section 18.4.3 of [WebCryptoAPI] for each of the supported operations.

3. Partial SubtleCrypto interface

This section extends the SubtleCrypto interface of [WebCryptoAPI].

WebIDL[SecureContext,Exposed=(Window,Worker)]
partial interface SubtleCrypto {
  Promise<EncapsulatedKey> encapsulateKey(
    AlgorithmIdentifier encapsulationAlgorithm,
    CryptoKey encapsulationKey,
    AlgorithmIdentifier sharedKeyAlgorithm,
    boolean extractable,
    sequence<KeyUsage> keyUsages
  );
  Promise<EncapsulatedBits> encapsulateBits(
    AlgorithmIdentifier encapsulationAlgorithm,
    CryptoKey encapsulationKey
  );

  Promise<CryptoKey> decapsulateKey(
    AlgorithmIdentifier decapsulationAlgorithm,
    CryptoKey decapsulationKey,
    BufferSource ciphertext,
    AlgorithmIdentifier sharedKeyAlgorithm,
    boolean extractable,
    sequence<KeyUsage> keyUsages
  );
  Promise<ArrayBuffer> decapsulateBits(
    AlgorithmIdentifier decapsulationAlgorithm,
    CryptoKey decapsulationKey,
    BufferSource ciphertext
  );

  static boolean supports(DOMString operation,
                   AlgorithmIdentifier algorithm,
                   optional unsigned long? length = null);
  static boolean supports(DOMString operation,
                   AlgorithmIdentifier algorithm,
                   AlgorithmIdentifier additionalAlgorithm);
};

3.1 Data Types

This specification replaces the definition of KeyFormat in [WebCryptoAPI] with the following:

WebIDLenum KeyFormat { "raw-public", "raw-private", "raw-seed", "raw-secret", "raw", "spki", "pkcs8", "jwk" };

This specification specifies a number of new recognized key format values:

raw-public
An unformatted sequence of public key bytes.
raw-private
An unformatted sequence of private key bytes.
raw-seed
An unformatted sequence of private key seed bytes.
raw-secret
An unformatted sequence of secret key bytes.

For all existing symmetric algorithms in [WebCryptoAPI], "raw-secret" acts as an alias of "raw".

For all existing asymmetric algorithms in [WebCryptoAPI], "raw-public" acts as an alias of "raw".

In the deriveKey() method, in the import key step, "raw-secret" must be used as the format instead of "raw".

3.2 Methods and Parameters

3.2.1 The encapsulateKey method

The encapsulateKey(encapsulationAlgorithm, encapsulationKey, sharedKeyAlgorithm, extractable, usages) method encapsulates a key and returns an EncapsulatedKey object. It behaves as follows:

  1. Let encapsulationAlgorithm, encapsulationKey, sharedKeyAlgorithm, extractable and usages be the encapsulationAlgorithm, encapsulationKey, sharedKeyAlgorithm, extractable and keyUsages parameters passed to the encapsulateKey() method, respectively.

  2. Let normalizedEncapsulationAlgorithm be the result of normalizing an algorithm, with alg set to encapsulationAlgorithm and op set to "encapsulate".

  3. If an error occurred, return a Promise rejected with normalizedEncapsulationAlgorithm.

  4. Let normalizedSharedKeyAlgorithm be the result of normalizing an algorithm, with alg set to sharedKeyAlgorithm and op set to "importKey".

  5. If an error occurred, return a Promise rejected with normalizedSharedKeyAlgorithm.

  6. Let realm be the relevant realm of this.

  7. Let promise be a new Promise.

  8. Return promise and perform the remaining steps in parallel.

  9. If the following steps or referenced procedures say to throw an error, queue a global task on the crypto task source, given realm's global object, to reject promise with the returned error; and then terminate the algorithm.

  10. If the name member of normalizedEncapsulationAlgorithm is not equal to the name attribute of the [[algorithm]] internal slot of encapsulationKey then throw an InvalidAccessError.

  11. If the [[usages]] internal slot of encapsulationKey does not contain an entry that is "encapsulateKey", then throw an InvalidAccessError.

  12. Let encapsulatedBits be the result of performing the encapsulate operation specified by the [[algorithm]] internal slot of encapsulationKey using encapsulationKey.

  13. Let sharedKey be the result of performing the import key operation specified by normalizedSharedKeyAlgorithm using "raw-secret" as format, the sharedKey field of encapsulatedBits as keyData, sharedKeyAlgorithm as algorithm and using extractable and usages.

  14. Let encapsulatedKey be a new EncapsulatedKey dictionary with sharedKey set to sharedKey and ciphertext set to the ciphertext field of encapsulatedBits.

  15. Queue a global task on the crypto task source, given realm's global object, to perform the remaining steps.

  16. Let result be the result of converting encapsulatedKey to an ECMAScript Object in realm, as defined by [WebIDL].

  17. Resolve promise with result.

3.2.2 The encapsulateBits method

The encapsulateBits(encapsulationAlgorithm, encapsulationKey) method encapsulates a key and returns an EncapsulatedBits object. It behaves as follows:

  1. Let encapsulationAlgorithm and encapsulationKey be the encapsulationAlgorithm and encapsulationKey parameters passed to the encapsulateBits() method, respectively.

  2. Let normalizedEncapsulationAlgorithm be the result of normalizing an algorithm, with alg set to encapsulationAlgorithm and op set to "encapsulate".

  3. If an error occurred, return a Promise rejected with normalizedEncapsulationAlgorithm.

  4. Let realm be the relevant realm of this.

  5. Let promise be a new Promise.

  6. Return promise and perform the remaining steps in parallel.

  7. If the following steps or referenced procedures say to throw an error, queue a global task on the crypto task source, given realm's global object, to reject promise with the returned error; and then terminate the algorithm.

  8. If the name member of normalizedEncapsulationAlgorithm is not equal to the name attribute of the [[algorithm]] internal slot of encapsulationKey then throw an InvalidAccessError.

  9. If the [[usages]] internal slot of encapsulationKey does not contain an entry that is "encapsulateBits", then throw an InvalidAccessError.

  10. Let encapsulatedBits be the result of performing the encapsulate operation specified by the [[algorithm]] internal slot of encapsulationKey using encapsulationKey.

  11. Queue a global task on the crypto task source, given realm's global object, to perform the remaining steps.

  12. Let result be the result of converting encapsulatedBits to an ECMAScript Object in realm, as defined by [WebIDL].

  13. Resolve promise with result.

3.2.3 The decapsulateKey method

The decapsulateKey(decapsulationAlgorithm, decapsulationKey, ciphertext, sharedKeyAlgorithm, extractable, usages) method decapsulates a key and returns an CryptoKey object. It behaves as follows:

  1. Let decapsulationAlgorithm, decapsulationKey, sharedKeyAlgorithm, extractable and usages be the decapsulationAlgorithm, decapsulationKey, sharedKeyAlgorithm, extractable and keyUsages parameters passed to the decapsulateKey() method, respectively.

  2. Let ciphertext be the result of getting a copy of the bytes held by the ciphertext parameter passed to the decapsulateKey() method.

  3. Let normalizedDecapsulationAlgorithm be the result of normalizing an algorithm, with alg set to decapsulationAlgorithm and op set to "decapsulate".

  4. If an error occurred, return a Promise rejected with normalizedDecapsulationAlgorithm.

  5. Let normalizedSharedKeyAlgorithm be the result of normalizing an algorithm, with alg set to sharedKeyAlgorithm and op set to "importKey".

  6. If an error occurred, return a Promise rejected with normalizedSharedKeyAlgorithm.

  7. Let realm be the relevant realm of this.

  8. Let promise be a new Promise.

  9. Return promise and perform the remaining steps in parallel.

  10. If the following steps or referenced procedures say to throw an error, queue a global task on the crypto task source, given realm's global object, to reject promise with the returned error; and then terminate the algorithm.

  11. If the name member of normalizedDecapsulationAlgorithm is not equal to the name attribute of the [[algorithm]] internal slot of decapsulationKey then throw an InvalidAccessError.

  12. If the [[usages]] internal slot of decapsulationKey does not contain an entry that is "decapsulateKey", then throw an InvalidAccessError.

  13. Let decapsulatedBits be the result of performing the decapsulate operation specified by the [[algorithm]] internal slot of decapsulationKey using decapsulationKey and ciphertext.

  14. Let sharedKey be the result of performing the import key operation specified by normalizedSharedKeyAlgorithm using "raw-secret" as format, the decapsulatedBits as keyData, sharedKeyAlgorithm as algorithm and using extractable and usages.

  15. Queue a global task on the crypto task source, given realm's global object, to perform the remaining steps.

  16. Let result be the result of converting sharedKey to an ECMAScript Object in realm, as defined by [WebIDL].

  17. Resolve promise with result.

3.2.4 The decapsulateBits method

The decapsulateBits(decapsulationAlgorithm, decapsulationKey, ciphertext) method decapsulates a key and returns an ArrayBuffer object. It behaves as follows:

  1. Let decapsulationAlgorithm and decapsulationKey be the decapsulationAlgorithm and decapsulationKey parameters passed to the decapsulateBits() method, respectively.

  2. Let ciphertext be the result of getting a copy of the bytes held by the ciphertext parameter passed to the decapsulateBits() method.

  3. Let normalizedDecapsulationAlgorithm be the result of normalizing an algorithm, with alg set to decapsulationAlgorithm and op set to "decapsulate".

  4. If an error occurred, return a Promise rejected with normalizedDecapsulationAlgorithm.

  5. Let realm be the relevant realm of this.

  6. Let promise be a new Promise.

  7. Return promise and perform the remaining steps in parallel.

  8. If the following steps or referenced procedures say to throw an error, queue a global task on the crypto task source, given realm's global object, to reject promise with the returned error; and then terminate the algorithm.

  9. If the name member of normalizedDecapsulationAlgorithm is not equal to the name attribute of the [[algorithm]] internal slot of decapsulationKey then throw an InvalidAccessError.

  10. If the [[usages]] internal slot of decapsulationKey does not contain an entry that is "decapsulateBits", then throw an InvalidAccessError.

  11. Let decapsulatedBits be the result of performing the decapsulate operation specified by the [[algorithm]] internal slot of decapsulationKey using decapsulationKey and ciphertext.

  12. Queue a global task on the crypto task source, given realm's global object, to perform the remaining steps.

  13. Let result be the result of creating an ArrayBuffer in realm, containing decapsulatedBits.

  14. Resolve promise with result.

3.2.5 The supports method

The supports(operation, algorithm, length) method returns a boolean indicating whether the implementation supports the given operation using the specified AlgorithmIdentifier, with an optional length parameter to indicate the number of bits to be derived when operation is "deriveBits". It behaves as follows:

  1. If operation is not one of "encrypt", "decrypt", "sign", "verify", "digest", "generateKey", "deriveKey", "deriveBits", "importKey", "exportKey", "wrapKey", "unwrapKey", "encapsulateKey", "encapsulateBits", "decapsulateKey" or "decapsulateBits", return false.

  2. Return the result of checking support for an algorithm, with op set to operation, alg set to algorithm, and length set to length.

The supports(operation, algorithm, additionalAlgorithm) method returns a boolean indicating whether the implementation supports the given operation using the specified AlgorithmIdentifier. The additional algorithm indicates the type of key to be derived when operation is "deriveKey", the type of key to be exported before wrapping when operation is "wrapKey", and the type of key to be imported after unwrapping when operation is "unwrapKey". It behaves as follows:

  1. If operation is not one of "encrypt", "decrypt", "sign", "verify", "digest", "generateKey", "deriveKey", "deriveBits", "importKey", "exportKey", "wrapKey", "unwrapKey", "encapsulateKey", "encapsulateBits", "decapsulateKey" or "decapsulateBits", return false.

  2. If operation is "deriveKey":

    If the result of checking support for an algorithm with op set to "importKey" and alg set to additionalAlgorithm is false, or the result of checking support for an algorithm with op set to "get key length" and alg set to additionalAlgorithm is false, return false.

    If operation is "wrapKey":

    If the result of checking support for an algorithm with op set to "exportKey" and alg set to additionalAlgorithm is false, return false.

    If operation is "unwrapKey":

    If the result of checking support for an algorithm with op set to "importKey" and alg set to additionalAlgorithm is false, return false.

    If operation is "encapsulateKey" or "decapsulateKey":

    If the result of checking support for an algorithm with op set to "importKey" and alg set to additionalAlgorithm is false, return false.

  3. Return the result of checking support for an algorithm, with op set to operation and alg set to algorithm.

3.3 Checking support for an algorithm

The check support for an algorithm algorithm defines a process for checking whether the given algorithm is supported for the given operation. Its input is an operation name op, an AlgorithmIdentifier alg, and an optional length parameter. Its output is a boolean. It behaves as follows:

  1. If op is "deriveKey", set op is "deriveBits".

  2. If op is "encapsulateKey" or "encapsulateBits", set op is "encapsulate".

  3. If op is "decapsulateKey" or "decapsulateBits", set op is "decapsulate".

  4. Let normalizedAlgorithm be the result of normalizing an algorithm, with alg set to alg and op set to op.

  5. If an error occurred:
    1. If op is "wrapKey", return the result of checking support for an algorithm with op set to "encrypt" and alg set to alg.

    2. If op is "unwrapKey", return the result of checking support for an algorithm with op set to "decrypt" and alg set to alg.

    3. Otherwise, return false.

  6. If the specified operation or algorithm (or one of its parameter values) is expected to fail (for any key and/or data) for an implementation-specific reason (e.g. known nonconformance to the specification), return false.

  7. If op is "generateKey" or "importKey", let usages be the empty list.

  8. For each of the steps of the operation specified by op of the algorithm specified by normalizedAlgorithm:

    If the step says to throw an error:
    Return false.
    If the step says to generate a key:
    Return true.
    If the step relies on an unavailable parameter, such as key, plaintext or ciphertext:
    Return true.
    If the step says to return a value:
    Return true.
    Otherwise:
    Execute the step.
    Note

    The steps in the referenced algorithm may access the normalizedAlgorithm, length, and usages variables from this context.

  9. Assert: this step is never reached, because one of the steps of the operation will have said to return a value or throw an error, causing us to return true or false, respectively.

4. Encapsulation dictionaries

WebIDLdictionary EncapsulatedKey {
  CryptoKey sharedKey;
  ArrayBuffer ciphertext;
};

dictionary EncapsulatedBits {
  ArrayBuffer sharedKey;
  ArrayBuffer ciphertext;
};

The EncapsulatedKey dictionary represents an encapsulated key comprised of a sharedKey and a ciphertext.

The EncapsulatedBits dictionary represents encapsulated key bits comprised of a sharedKey and a ciphertext.

5. ML-KEM

5.1 Description

This section is non-normative.

This describes using ML-KEM for key encapsulation and decapsulation, as specified by [FIPS-203].

5.2 Registration

The recognized algorithm names for this algorithm are "ML-KEM-512", "ML-KEM-768" and "ML-KEM-1024".

Operation Parameters Result
encapsulate None EncapsulatedBits
decapsulate None byte sequence
generateKey None CryptoKeyPair
importKey None CryptoKey
exportKey None object

5.3 Operations

Encapsulate
  1. If the [[type]] internal slot of key is not "public", then throw an InvalidAccessError.

  2. Perform the encapsulation key check described in Section 7.2 of [FIPS-203] with the parameter set indicated by the name member of algorithm, using the key represented by the [[handle]] internal slot of key as the ek input parameter.

    Note

    The result of this check may be cached or precomputed for the CryptoKey object if desirable for performance.

  3. If the encapsulation key check failed, return an OperationError.

  4. Let sharedKey and ciphertext be the outputs that result from performing the ML-KEM.Encaps function described in Section 7.2 of [FIPS-203] with the parameter set indicated by the name member of algorithm, using the key represented by the [[handle]] internal slot of key as the ek input parameter.

  5. If the ML-KEM.Encaps function returned an error, return an OperationError.

  6. Let result be a new EncapsulatedBits dictionary.

  7. Set the sharedKey attribute of result to the result of creating an ArrayBuffer containing sharedKey.

  8. Set the ciphertext attribute of result to the result of creating an ArrayBuffer containing ciphertext.

  9. Return result.

Decapsulate
  1. If the [[type]] internal slot of key is not "private", then throw an InvalidAccessError.

  2. Perform the decapsulation input check described in Section 7.3 of [FIPS-203] with the parameter set indicated by the name member of algorithm, using the key represented by the [[handle]] internal slot of key as the dk input parameter, and ciphertext as the c input parameter.

    Note

    The result of the decapsulation key type check and the hash check may be cached or precomputed for the CryptoKey object if desirable for performance.

  3. If the decapsulation key check failed, return an OperationError.

  4. Let sharedKey be the output that results from performing the ML-KEM.Decaps function described in Section 7.3 of [FIPS-203] with the parameter set indicated by the name member of algorithm, using the key represented by the [[handle]] internal slot of key as the dk input parameter, and ciphertext as the c input parameter.

  5. Return sharedKey.

Generate Key
  1. If usages contains any entry which is not one of "encapsulateKey", "encapsulateBits", "decapsulateKey" or "decapsulateBits", then throw a SyntaxError.

  2. Generate an ML-KEM key pair, as described in Section 7.1 of [FIPS-203], with the parameter set indicated by the name member of normalizedAlgorithm.

    Note

    In order to be able to export the seed (d, z), d and z need to be stored as part of the generated key material.

  3. If the key generation step fails, then throw an OperationError.

  4. Let algorithm be a new KeyAlgorithm object.

  5. Set the name attribute of algorithm to the name attribute of normalizedAlgorithm.

  6. Let publicKey be a new CryptoKey representing the encapsulation key of the generated key pair.

  7. Set the [[type]] internal slot of publicKey to "public".

  8. Set the [[algorithm]] internal slot of publicKey to algorithm.

  9. Set the [[extractable]] internal slot of publicKey to true.

  10. Set the [[usages]] internal slot of publicKey to be the usage intersection of usages and [ "encapsulateKey", "encapsulateBits" ].

  11. Let privateKey be a new CryptoKey representing the decapsulation key of the generated key pair.

  12. Set the [[type]] internal slot of privateKey to "private".

  13. Set the [[algorithm]] internal slot of privateKey to algorithm.

  14. Set the [[extractable]] internal slot of privateKey to extractable.

  15. Set the [[usages]] internal slot of privateKey to be the usage intersection of usages and [ "decapsulateKey", "decapsulateBits" ].

  16. Let result be a new CryptoKeyPair dictionary.

  17. Set the publicKey attribute of result to be publicKey.

  18. Set the privateKey attribute of result to be privateKey.

  19. Return result.

Import Key
  1. If format is "raw-public":
    1. If usages contains an entry which is not "encapsulateKey" or "encapsulateBits" then throw a SyntaxError.

    2. Let data be keyData.

    3. Let key be a new CryptoKey that represents the ML-KEM public key data in data.

    4. Set the [[type]] internal slot of key to "public"

    5. Let algorithm be a new KeyAlgorithm.

    6. Set the name attribute of algorithm to the name attribute of normalizedAlgorithm.

    7. Set the [[algorithm]] internal slot of key to algorithm.

    If format is "raw-seed":
    1. If usages contains an entry which is not "decapsulateKey" or "decapsulateBits" then throw a SyntaxError.

    2. Let data be keyData.

    3. If the length in bits of data is not 512 then throw a DataError.

    4. Let privateKey be the result of performing the ML-KEM.KeyGen_internal function described in Section 6.1 of [FIPS-203] with the parameter set indicated by the name member of normalizedAlgorithm, using the first 256 bits of data as d and the last 256 bits of data as z.

    5. Let key be a new CryptoKey that represents the ML-KEM private key identified by privateKey.

    6. Set the [[type]] internal slot of key to "private"

    7. Let algorithm be a new KeyAlgorithm.

    8. Set the name attribute of algorithm to the name attribute of normalizedAlgorithm.

    9. Set the [[algorithm]] internal slot of key to algorithm.

    Otherwise:
    throw a NotSupportedError.
  2. Return key.

Export Key
  1. If the underlying cryptographic key material represented by the [[handle]] internal slot of key cannot be accessed, then throw an OperationError.

  2. If format is "raw-public":
    1. If the [[type]] internal slot of key is not "public", then throw an InvalidAccessError.

    2. Let data be a byte sequence containing the raw octets of the key represented by the [[handle]] internal slot of key.

    3. Let result be data.

    If format is "raw-seed":
    1. If the [[type]] internal slot of key is not "private", then throw an InvalidAccessError.

    2. Let data be a byte sequence containing the concatenation of the d and z seed variables of the key represented by the [[handle]] internal slot of key.

      Note

      The d and z seed variables were sampled in the ML-KEM.KeyGen function as described in Section 7.1 of [FIPS-203].

    3. Let result be data.

    Otherwise:

    throw a NotSupportedError.

  3. Return result.

6. ML-DSA

6.1 Description

This section is non-normative.

This describes using ML-DSA for signing and verification, as specified by [FIPS-204].

6.2 Registration

The recognized algorithm names for this algorithm are "ML-DSA-44", "ML-DSA-65" and "ML-DSA-87".

Operation Parameters Result
sign ContextParams byte sequence
verify ContextParams boolean
generateKey None CryptoKeyPair
importKey None CryptoKey
exportKey None object

6.3 ContextParams dictionary

WebIDLdictionary ContextParams : Algorithm {
  BufferSource context;
};

The context member represents the optional context data to associate with the message.

6.4 Operations

Sign
When signing, the following algorithm should be used:
  1. If the [[type]] internal slot of key is not "private", then throw an InvalidAccessError.

  2. Let context be the context member of normalizedAlgorithm or the empty octet string if the context member of normalizedAlgorithm is not present.

  3. Let result be the result of performing the ML-DSA.Sign signing algorithm, as specified in Section 5.2 of [FIPS-204], with the parameter set indicated by the name member of normalizedAlgorithm, using the ML-DSA private key associated with key as sk, message as M and context as ctx.

  4. If the ML-DSA.Sign algorithm returned an error, return an OperationError.

  5. Return result.

Verify
When verifying, the following algorithm should be used:
  1. If the [[type]] internal slot of key is not "public", then throw an InvalidAccessError.

  2. Let context be the context member of normalizedAlgorithm or the empty octet string if the context member of normalizedAlgorithm is not present.

  3. Let result be the result of performing the ML-DSA.Verify verification algorithm, as specified in Section 5.3 of [FIPS-204], with the parameter set indicated by the name member of normalizedAlgorithm, using the ML-DSA public key associated with key as pk, message as M, signature as σ and context as ctx.

  4. If the ML-DSA.Verify algorithm returned an error, return an OperationError.

  5. Return result.

Generate Key
  1. If usages contains a value which is not one of "sign" or "verify", then throw a SyntaxError.

  2. Generate an ML-DSA key pair, as described in Section 5.1 of [FIPS-204], with the parameter set indicated by the name member of normalizedAlgorithm.

    Note

    In order to be able to export the seed ξ, it needs to be stored as part of the generated key material.

  3. If the key generation step fails, then throw an OperationError.

  4. Let algorithm be a new KeyAlgorithm object.

  5. Set the name attribute of algorithm to the name attribute of normalizedAlgorithm.

  6. Let publicKey be a new CryptoKey representing the public key of the generated key pair.

  7. Set the [[type]] internal slot of publicKey to "public".

  8. Set the [[algorithm]] internal slot of publicKey to algorithm.

  9. Set the [[extractable]] internal slot of publicKey to true.

  10. Set the [[usages]] internal slot of publicKey to be the usage intersection of usages and [ "verify" ].

  11. Let privateKey be a new CryptoKey representing the private key of the generated key pair.

  12. Set the [[type]] internal slot of privateKey to "private".

  13. Set the [[algorithm]] internal slot of privateKey to algorithm.

  14. Set the [[extractable]] internal slot of privateKey to extractable.

  15. Set the [[usages]] internal slot of privateKey to be the usage intersection of usages and [ "sign" ].

  16. Let result be a new CryptoKeyPair dictionary.

  17. Set the publicKey attribute of result to be publicKey.

  18. Set the privateKey attribute of result to be privateKey.

  19. Return result.

Import Key
  1. Let keyData be the key data to be imported.

  2. If format is "raw-public":
    1. If usages contains a value which is not "verify" then throw a SyntaxError.

    2. Let algorithm be a new KeyAlgorithm object.

    3. Set the name attribute of algorithm to the name attribute of normalizedAlgorithm.

    4. Let key be a new CryptoKey representing the key data provided in keyData.

    5. Set the [[type]] internal slot of key to "public"

    6. Set the [[algorithm]] internal slot of key to algorithm.

    If format is "raw-seed":
    1. If usages contains an entry which is not "sign" then throw a SyntaxError.

    2. Let data be keyData.

    3. If the length in bits of data is not 256 then throw a DataError.

    4. Let privateKey be the result of performing the ML-DSA.KeyGen_internal function described in Section 6.1 of [FIPS-204] with the parameter set indicated by the name member of normalizedAlgorithm, using data as ξ.

    5. Let key be a new CryptoKey that represents the ML-DSA private key identified by privateKey.

    6. Set the [[type]] internal slot of key to "private"

    7. Let algorithm be a new KeyAlgorithm.

    8. Set the name attribute of algorithm to the name attribute of normalizedAlgorithm.

    9. Set the [[algorithm]] internal slot of key to algorithm.

    Otherwise:

    throw a NotSupportedError.

  3. Return key

Export Key
  1. Let key be the CryptoKey to be exported.

  2. If the underlying cryptographic key material represented by the [[handle]] internal slot of key cannot be accessed, then throw an OperationError.

  3. If format is "raw-public":
    1. If the [[type]] internal slot of key is not "public", then throw an InvalidAccessError.

    2. Let data be a byte sequence containing the ML-DSA public key represented by the [[handle]] internal slot of key.

    3. Let result be data.

    If format is "raw-seed":
    1. If the [[type]] internal slot of key is not "private", then throw an InvalidAccessError.

    2. Let data be a byte sequence containing the ξ seed variable of the key represented by the [[handle]] internal slot of key.

      Note

      The ξ seed variable was sampled in the ML-DSA.KeyGen function as described in Section 5.1 of [FIPS-204].

    3. Let result be data.

    Otherwise:

    throw a NotSupportedError.

  4. Return result.

7. SLH-DSA

7.1 Description

This section is non-normative.

This describes using SLH-DSA for signing and verification, as specified by [FIPS-205].

7.2 Registration

The recognized algorithm names for this algorithm are "SLH-DSA-SHA2-128s", "SLH-DSA-SHAKE-128s", "SLH-DSA-SHA2-128f", "SLH-DSA-SHAKE-128f", "SLH-DSA-SHA2-192s", "SLH-DSA-SHAKE-192s", "SLH-DSA-SHA2-192f", "SLH-DSA-SHAKE-192f", "SLH-DSA-SHA2-256s", "SLH-DSA-SHAKE-256s", "SLH-DSA-SHA2-256f" and "SLH-DSA-SHAKE-256f".

Operation Parameters Result
sign ContextParams byte sequence
verify ContextParams boolean
generateKey None CryptoKeyPair
importKey None CryptoKey
exportKey None object

7.3 Operations

Sign
When signing, the following algorithm should be used:
  1. If the [[type]] internal slot of key is not "private", then throw an InvalidAccessError.

  2. Let context be the context member of normalizedAlgorithm or the empty octet string if the context member of normalizedAlgorithm is not present.

  3. Let result be the result of performing the slh_sign signing algorithm, as specified in Section 10.2.1 of [FIPS-205], with the parameter set indicated by the name member of normalizedAlgorithm, using the SLH-DSA private key associated with key as SK, message as M and context as ctx.

  4. If the slh_sign algorithm returned an error, return an OperationError.

  5. Return result.

Verify
When verifying, the following algorithm should be used:
  1. If the [[type]] internal slot of key is not "public", then throw an InvalidAccessError.

  2. Let context be the context member of normalizedAlgorithm or the empty octet string if the context member of normalizedAlgorithm is not present.

  3. Let result be the result of performing the slh_verify verification algorithm, as specified in Section 10.3 of [FIPS-205], with the parameter set indicated by the name member of normalizedAlgorithm, using the SLH-DSA public key associated with key as PK, message as M, signature as SIG and context as ctx.

  4. If the slh_verify algorithm returned an error, return an OperationError.

  5. Return result.

Generate Key
  1. If usages contains a value which is not one of "sign" or "verify", then throw a SyntaxError.

  2. Generate an SLH-DSA key pair, as described in Section 10.1 of [FIPS-205], with the parameter set indicated by the name member of normalizedAlgorithm.

  3. If the key generation step fails, then throw an OperationError.

  4. Let algorithm be a new KeyAlgorithm object.

  5. Set the name attribute of algorithm to the name attribute of normalizedAlgorithm.

  6. Let publicKey be a new CryptoKey representing the public key of the generated key pair.

  7. Set the [[type]] internal slot of publicKey to "public".

  8. Set the [[algorithm]] internal slot of publicKey to algorithm.

  9. Set the [[extractable]] internal slot of publicKey to true.

  10. Set the [[usages]] internal slot of publicKey to be the usage intersection of usages and [ "verify" ].

  11. Let privateKey be a new CryptoKey representing the private key of the generated key pair.

  12. Set the [[type]] internal slot of privateKey to "private".

  13. Set the [[algorithm]] internal slot of privateKey to algorithm.

  14. Set the [[extractable]] internal slot of privateKey to extractable.

  15. Set the [[usages]] internal slot of privateKey to be the usage intersection of usages and [ "sign" ].

  16. Let result be a new CryptoKeyPair dictionary.

  17. Set the publicKey attribute of result to be publicKey.

  18. Set the privateKey attribute of result to be privateKey.

  19. Return result.

Import Key
  1. Let keyData be the key data to be imported.

  2. If format is "raw-public":
    1. If usages contains a value which is not "verify" then throw a SyntaxError.

    2. Let algorithm be a new KeyAlgorithm object.

    3. Set the name attribute of algorithm to the name attribute of normalizedAlgorithm.

    4. If the length of keyData is not the pk length specified by Table 2 of [FIPS-205] for the parameter set indicated by the name member of normalizedAlgorithm, then throw a DataError.

    5. Let key be a new CryptoKey representing the key data provided in keyData.

    6. Set the [[type]] internal slot of key to "public"

    7. Set the [[algorithm]] internal slot of key to algorithm.

    If format is "raw-private":
    1. If usages contains an entry which is not "sign" then throw a SyntaxError.

    2. If the length of keyData is not 2 * the pk length specified by Table 2 of [FIPS-205] for the parameter set indicated by the name member of normalizedAlgorithm, then throw a DataError.

    3. Let key be a new CryptoKey representing the key data provided in keyData.

    4. Set the [[type]] internal slot of key to "private"

    5. Let algorithm be a new KeyAlgorithm.

    6. Set the name attribute of algorithm to the name attribute of normalizedAlgorithm.

    7. Set the [[algorithm]] internal slot of key to algorithm.

    Otherwise:

    throw a NotSupportedError.

  3. Return key

Export Key
  1. Let key be the CryptoKey to be exported.

  2. If the underlying cryptographic key material represented by the [[handle]] internal slot of key cannot be accessed, then throw an OperationError.

  3. If format is "raw-public":
    1. If the [[type]] internal slot of key is not "public", then throw an InvalidAccessError.

    2. Let data be a byte sequence containing the SLH-DSA public key represented by the [[handle]] internal slot of key.

    3. Let result be data.

    If format is "raw-private":
    1. If the [[type]] internal slot of key is not "private", then throw an InvalidAccessError.

    2. Let data be a byte sequence containing the SLH-DSA private key represented by the [[handle]] internal slot of key.

    3. Let result be data.

    Otherwise:

    throw a NotSupportedError.

  4. Return result.

8. AES-OCB

8.1 Description

This section is non-normative.

The "AES-OCB" algorithm identifier is used to perform authenticated encryption and decryption using AES in OCB mode, as described in [RFC7253].

8.2 Registration

The recognized algorithm name for this algorithm is "AES-OCB".

Operation Parameters Result
encrypt AeadParams byte sequence
decrypt AeadParams byte sequence
generateKey AesKeyGenParams CryptoKey
importKey None CryptoKey
exportKey None object
get key length AesDerivedKeyParams Integer

8.3 AeadParams dictionary

WebIDLdictionary AeadParams : Algorithm {
  required BufferSource iv;
  BufferSource additionalData;
  [EnforceRange] octet tagLength;
};

The iv member represents the initialization vector to use.

The additionalData member represents the additional authentication data to include.

The tagLength member represents the desired length of the authentication tag.

Note

The AeadParams dictionary is identical to the AesGcmParams dictionary of [WebCryptoAPI], and the latter may be replaced by the former when merging this proposal.

8.4 Operations

Encrypt
  1. If the iv member of normalizedAlgorithm has a length greater than 15 bytes, then throw an OperationError.

  2. If the tagLength member of normalizedAlgorithm is not present:
    Let tagLength be 128.
    If the tagLength member of normalizedAlgorithm is one of 64, 96 or 128:
    Let tagLength be equal to the tagLength member of normalizedAlgorithm
    Otherwise:
    throw an OperationError.
  3. Let additionalData be the additionalData member of normalizedAlgorithm if present or the empty octet string otherwise.

  4. Let C be the output that results from performing the OCB-ENCRYPT function described in Section 4.2 of [RFC7253] using AES as the block cipher, using the key represented by [[handle]] internal slot of key as the K input parameter, the iv member of normalizedAlgorithm as the N input parameter, additionalData as the A input parameter, plaintext as the P input parameter, and tagLength as the TAGLEN global parameter.

  5. Return C.

Decrypt
  1. If the iv member of normalizedAlgorithm has a length greater than 15 bytes, then throw an OperationError.

  2. If the tagLength member of normalizedAlgorithm is not present:
    Let tagLength be 128.
    If the tagLength member of normalizedAlgorithm is one of 64, 96 or 128:
    Let tagLength be equal to the tagLength member of normalizedAlgorithm
    Otherwise:
    throw an OperationError.
  3. If ciphertext has a length less than tagLength bits, then throw an OperationError.

  4. Let additionalData be the additionalData member of normalizedAlgorithm if present or the empty octet string otherwise.

  5. Perform the OCB-DECRYPT function described in Section 4.3 of [RFC7253] using AES as the block cipher, using the key represented by [[handle]] internal slot of key as the K input parameter, the iv member of normalizedAlgorithm as the N input parameter, additionalData as the A input parameter, ciphertext as the C input parameter, and tagLength as the TAGLEN global parameter.

    If the result of the algorithm is the indication of authentication failure, "INVALID":
    throw an OperationError
    Otherwise:
    Let plaintext be the output P of OCB-DECRYPT.
  6. Return plaintext.

Generate Key
  1. If usages contains any entry which is not one of "encrypt", "decrypt", "wrapKey" or "unwrapKey", then throw a SyntaxError.

  2. If the length member of normalizedAlgorithm is not equal to one of 128, 192 or 256, then throw an OperationError.

  3. Generate an AES key of length equal to the length member of normalizedAlgorithm.

  4. If the key generation step fails, then throw an OperationError.

  5. Let key be a new CryptoKey object representing the generated AES key.

  6. Let algorithm be a new AesKeyAlgorithm.

  7. Set the name attribute of algorithm to "AES-OCB".

  8. Set the length attribute of algorithm to equal the length member of normalizedAlgorithm.

  9. Set the [[algorithm]] internal slot of key to algorithm.

  10. Set the [[extractable]] internal slot of key to be extractable.

  11. Set the [[usages]] internal slot of key to be usages.

  12. Return key.

Import Key
  1. If usages contains an entry which is not one of "encrypt", "decrypt", "wrapKey" or "unwrapKey", then throw a SyntaxError.

  2. If format is "raw-secret":
    1. Let data be keyData.

    2. If the length in bits of data is not 128, 192 or 256 then throw a DataError.

    If format is "jwk":
    1. If keyData is a JsonWebKey dictionary:

      Let jwk equal keyData.

      Otherwise:

      Throw a DataError.

    2. If the kty field of jwk is not "oct", then throw a DataError.

    3. If jwk does not meet the requirements of Section 6.4 of JSON Web Algorithms [JWA], then throw a DataError.

    4. Let data be the byte sequence obtained by decoding the k field of jwk.

    5. If data has length 128 bits:
      If the alg field of jwk is present, and is not "A128OCB", then throw a DataError.
      If data has length 192 bits:
      If the alg field of jwk is present, and is not "A192OCB", then throw a DataError.
      If data has length 256 bits:
      If the alg field of jwk is present, and is not "A256OCB", then throw a DataError.
      Otherwise:
      throw a DataError.
    6. If usages is non-empty and the use field of jwk is present and is not "enc", then throw a DataError.

    7. If the key_ops field of jwk is present, and is invalid according to the requirements of JSON Web Key [JWK] or does not contain all of the specified usages values, then throw a DataError.

    8. If the ext field of jwk is present and has the value false and extractable is true, then throw a DataError.

    Otherwise:
    throw a NotSupportedError.
  3. Let key be a new CryptoKey object representing an AES key with value data.

  4. Let algorithm be a new AesKeyAlgorithm.

  5. Set the name attribute of algorithm to "AES-OCB".

  6. Set the length attribute of algorithm to the length, in bits, of data.

  7. Set the [[algorithm]] internal slot of key to algorithm.

  8. Return key.

Export Key
  1. If the underlying cryptographic key material represented by the [[handle]] internal slot of key cannot be accessed, then throw an OperationError.

  2. If format is "raw-secret":
    1. Let data be a byte sequence containing the raw octets of the key represented by [[handle]] internal slot of key.

    2. Let result be data.

    If format is "jwk":
    1. Let jwk be a new JsonWebKey dictionary.

    2. Set the kty attribute of jwk to the string "oct".

    3. Set the k attribute of jwk to be a string containing the raw octets of the key represented by [[handle]] internal slot of key, encoded according to Section 6.4 of JSON Web Algorithms [JWA].

    4. If the length attribute of key is 128:
      Set the alg attribute of jwk to the string "A128OCB".
      If the length attribute of key is 192:
      Set the alg attribute of jwk to the string "A192OCB".
      If the length attribute of key is 256:
      Set the alg attribute of jwk to the string "A256OCB".
    5. Set the key_ops attribute of jwk to equal the usages attribute of key.

    6. Set the ext attribute of jwk to equal the [[extractable]] internal slot of key.

    7. Let result be the result of converting jwk to an ECMAScript Object, as defined by [WebIDL].

    Otherwise:

    throw a NotSupportedError.

  3. Return result.

Get key length
  1. If the length member of normalizedDerivedKeyAlgorithm is not 128, 192 or 256, then throw an OperationError.

  2. Return the length member of normalizedDerivedKeyAlgorithm.

9. ChaCha20-Poly1305

9.1 Description

This section is non-normative.

The "ChaCha20-Poly1305" algorithm identifier is used to perform authenticated encryption and decryption using AEAD_CHACHA20_POLY1305, as described in [RFC8439].

9.2 Registration

The recognized algorithm name for this algorithm is "ChaCha20-Poly1305".

Operation Parameters Result
encrypt AeadParams byte sequence
decrypt AeadParams byte sequence
generateKey None CryptoKey
importKey None CryptoKey
exportKey None object
get key length None Integer

9.3 Operations

Encrypt
  1. If the iv member of normalizedAlgorithm does not have a length of 12 bytes, then throw an OperationError.

  2. If the tagLength member of normalizedAlgorithm is present and is not 128, then throw an OperationError.

  3. Let additionalData be the additionalData member of normalizedAlgorithm if present or the empty octet string otherwise.

  4. Let ciphertext be the output that results from performing the AEAD_CHACHA20_POLY1305 encryption algorithm described in Section 2.8 of [RFC8439], using the key represented by [[handle]] internal slot of key as the key input parameter, the iv member of normalizedAlgorithm as the nonce input parameter, plaintext as the plaintext input parameter, and additionalData as the additional authenticated data (AAD) input parameter.

  5. Return ciphertext.

Decrypt
  1. If the iv member of normalizedAlgorithm does not have a length of 12 bytes, then throw an OperationError.

  2. If the tagLength member of normalizedAlgorithm is present and is not 128, then throw an OperationError.

  3. If ciphertext has a length less than 128 bits, then throw an OperationError.

  4. Let additionalData be the additionalData member of normalizedAlgorithm if present or the empty octet string otherwise.

  5. Perform the AEAD_CHACHA20_POLY1305 decryption algorithm described in Section 2.8 of [RFC8439], using the key represented by [[handle]] internal slot of key as the key input parameter, the iv member of normalizedAlgorithm as the nonce input parameter, ciphertext as the ciphertext input parameter, and additionalData as the additional authenticated data (AAD) input parameter.

    If the result of the algorithm is the indication of authentication failure:
    throw an OperationError
    Otherwise:
    Let plaintext be the resulting plaintext.
  6. Return plaintext.

Generate Key
  1. If usages contains any entry which is not one of "encrypt", "decrypt", "wrapKey" or "unwrapKey", then throw a SyntaxError.

  2. Generate a 256-bit key.

  3. If the key generation step fails, then throw an OperationError.

  4. Let key be a new CryptoKey object representing the generated key.

  5. Let algorithm be a new KeyAlgorithm.

  6. Set the name attribute of algorithm to "ChaCha20-Poly1305".

  7. Set the [[algorithm]] internal slot of key to algorithm.

  8. Set the [[extractable]] internal slot of key to be extractable.

  9. Set the [[usages]] internal slot of key to be usages.

  10. Return key.

Import Key
  1. If usages contains an entry which is not one of "encrypt", "decrypt", "wrapKey" or "unwrapKey", then throw a SyntaxError.

  2. If format is "raw-secret":
    1. Let data be keyData.

    2. If the length in bits of data is not 256 then throw a DataError.

    If format is "jwk":
    1. If keyData is a JsonWebKey dictionary:

      Let jwk equal keyData.

      Otherwise:

      Throw a DataError.

    2. If the kty field of jwk is not "oct", then throw a DataError.

    3. If jwk does not meet the requirements of Section 6.4 of JSON Web Algorithms [JWA], then throw a DataError.

    4. Let data be the byte sequence obtained by decoding the k field of jwk.

    5. If the alg field of jwk is present, and is not "CC20P1305", then throw a DataError.

    6. If usages is non-empty and the use field of jwk is present and is not "enc", then throw a DataError.

    7. If the key_ops field of jwk is present, and is invalid according to the requirements of JSON Web Key [JWK] or does not contain all of the specified usages values, then throw a DataError.

    8. If the ext field of jwk is present and has the value false and extractable is true, then throw a DataError.

    Otherwise:
    throw a NotSupportedError.
  3. Let key be a new CryptoKey object representing a key with value data.

  4. Let algorithm be a new KeyAlgorithm.

  5. Set the name attribute of algorithm to "ChaCha20-Poly1305".

  6. Set the [[algorithm]] internal slot of key to algorithm.

  7. Return key.

Export Key
  1. If the underlying cryptographic key material represented by the [[handle]] internal slot of key cannot be accessed, then throw an OperationError.

  2. If format is "raw-secret":
    1. Let data be a byte sequence containing the raw octets of the key represented by [[handle]] internal slot of key.

    2. Let result be data.

    If format is "jwk":
    1. Let jwk be a new JsonWebKey dictionary.

    2. Set the kty attribute of jwk to the string "oct".

    3. Set the k attribute of jwk to be a string containing the raw octets of the key represented by [[handle]] internal slot of key, encoded according to Section 6.4 of JSON Web Algorithms [JWA].

    4. Set the alg attribute of jwk to the string "CC20P1305".

    5. Set the key_ops attribute of jwk to equal the usages attribute of key.

    6. Set the ext attribute of jwk to equal the [[extractable]] internal slot of key.

    7. Let result be the result of converting jwk to an ECMAScript Object, as defined by [WebIDL].

    Otherwise:

    throw a NotSupportedError.

  3. Return result.

Get key length
  1. Return 256.

10. SHA-3

10.1 Description

This section is non-normative.

This describes the SHA-3 family of hash functions, as specified by [FIPS-202].

10.2 Registration

The recognized algorithm names are "SHA3-256", "SHA3-384", and "SHA3-512" for the respective SHA-3 algorithms.

Operation Parameters Result
digest None byte sequence

10.3 Operations

Digest
  1. If the name member of normalizedAlgorithm is a case-sensitive string match for "SHA3-256":
    Let result be the result of performing the SHA3-256 hash function defined in Section 6.1 of [FIPS-202] using message as the input message, M.
    If the name member of normalizedAlgorithm is a case-sensitive string match for "SHA3-384":
    Let result be the result of performing the SHA3-384 hash function defined in Section 6.1 of [FIPS-202] using message as the input message, M.
    If the name member of normalizedAlgorithm is a case-sensitive string match for "SHA3-512":
    Let result be the result of performing the SHA3-512 hash function defined in Section 6.1 of [FIPS-202] using message as the input message, M.
  2. If performing the operation results in an error, then throw an OperationError.

  3. Return result.

11. cSHAKE

11.1 Description

This section is non-normative.

This describes cSHAKE128 and cSHAKE256, as specified by [NIST-SP800-185].

11.2 Registration

The recognized algorithm names are "cSHAKE128" and "cSHAKE256".

Operation Parameters Result
digest CShakeParams byte sequence

11.3 CShakeParams dictionary

WebIDLdictionary CShakeParams : Algorithm {
  required [EnforceRange] unsigned long length;
  BufferSource functionName;
  BufferSource customization;
};

The length member represents the requested output length in bits.

The functionName member represents the function name, used by NIST to define functions based on cSHAKE. When used, it should only be set to values defined by NIST.

The customization member represents the customization string. The application selects this string to define a variant of the function.

11.4 Operations

Digest
  1. Let length be the length member of normalizedAlgorithm.

  2. Let functionName be the functionName member of normalizedAlgorithm if present or the empty octet string otherwise.

  3. Let customization be the customization member of normalizedAlgorithm if present or the empty octet string otherwise.

  4. If the name member of normalizedAlgorithm is a case-sensitive string match for "cSHAKE128":
    Let result be the result of performing the cSHAKE128 function defined in Section 3 of [NIST-SP800-185] using message as the X input parameter, length as the L input parameter, functionName as the N input parameter, and customization as the S input parameter.
    If the name member of normalizedAlgorithm is a case-sensitive string match for "cSHAKE256":
    Let result be the result of performing the cSHAKE256 function defined in Section 3 of [NIST-SP800-185] using message as the X input parameter, length as the L input parameter, functionName as the N input parameter, and customization as the S input parameter.
  5. If performing the operation results in an error, then throw an OperationError.

  6. Return result.

12. KMAC

12.1 Description

This section is non-normative.

This describes KMAC128 and KMAC256, as specified by [NIST-SP800-185].

12.2 Registration

The recognized algorithm names are "KMAC128" and "KMAC256".

Operation Parameters Result
sign KmacParams byte sequence
verify KmacParams boolean
generateKey KmacKeyGenParams CryptoKey
importKey KmacImportParams CryptoKey
exportKey None object
get key length KmacImportParams Integer

12.3 KmacKeyGenParams dictionary

WebIDLdictionary KmacKeyGenParams : Algorithm {
  [EnforceRange] unsigned long length;
};

The length member represents the length (in bits) of the key to generate. If unspecified, the recommended length will be used, which is 128 for KMAC128 and 256 for KMAC256.

12.4 KmacImportParams dictionary

WebIDLdictionary KmacImportParams : Algorithm {
  [EnforceRange] unsigned long length;
};

The length member represents the length (in bits) of the key.

12.5 KmacKeyAlgorithm dictionary

WebIDLdictionary KmacKeyAlgorithm : KeyAlgorithm {
  required unsigned long length;
};

The length member represents the length (in bits) of the key.

12.6 KmacParams dictionary

WebIDLdictionary KmacParams : Algorithm {
  required [EnforceRange] unsigned long length;
  BufferSource customization;
};

The length member represents the requested output length in bits.

The customization member represents the customization string. The application selects this string to define a variant of the function.

12.7 Operations

Sign
  1. Let customization be the customization member of normalizedAlgorithm if present or the empty octet string otherwise.

  2. If the name member of normalizedAlgorithm is a case-sensitive string match for "KMAC128":
    Let mac be the result of performing the KMAC128 function defined in Section 4 of [NIST-SP800-185] using the key represented by [[handle]] internal slot of key as the K input parameter, message as the X input parameter, the length member of normalizedAlgorithm as the L input parameter, and customization as the S input parameter.
    If the name member of normalizedAlgorithm is a case-sensitive string match for "KMAC256":
    Let mac be the result of performing the KMAC256 function defined in Section 4 of [NIST-SP800-185] using the key represented by [[handle]] internal slot of key as the K input parameter, message as the X input parameter, the length member of normalizedAlgorithm as the L input parameter, and customization as the S input parameter.
  3. Return mac.

Verify
  1. Let customization be the customization member of normalizedAlgorithm if present or the empty octet string otherwise.

  2. If the name member of normalizedAlgorithm is a case-sensitive string match for "KMAC128":
    Let mac be the result of performing the KMAC128 function defined in Section 4 of [NIST-SP800-185] using the key represented by [[handle]] internal slot of key as the K input parameter, message as the X input parameter, the length member of normalizedAlgorithm as the L input parameter, and customization as the S input parameter.
    If the name member of normalizedAlgorithm is a case-sensitive string match for "KMAC256":
    Let mac be the result of performing the KMAC256 function defined in Section 4 of [NIST-SP800-185] using the key represented by [[handle]] internal slot of key as the K input parameter, message as the X input parameter, the length member of normalizedAlgorithm as the L input parameter, and customization as the S input parameter.
  3. Return true if mac is equal to signature and false otherwise.

Generate Key
  1. If usages contains any entry which is not "sign" or "verify", then throw a SyntaxError.

  2. If the length member of normalizedAlgorithm is present:
    Let length be equal to the length member of normalizedAlgorithm.
    Otherwise, if the name member of normalizedAlgorithm is a case-sensitive string match for "KMAC128":
    Let length be 128.
    Otherwise, if the name member of normalizedAlgorithm is a case-sensitive string match for "KMAC256":
    Let length be 256.
  3. Generate a key of length length bits.

  4. If the key generation step fails, then throw an OperationError.

  5. Let key be a new CryptoKey object representing the generated key.

  6. Let algorithm be a new KmacKeyAlgorithm.

  7. Set the name attribute of algorithm to "KMAC".

  8. Set the [[algorithm]] internal slot of key to algorithm.

  9. Set the [[extractable]] internal slot of key to be extractable.

  10. Set the [[usages]] internal slot of key to be usages.

  11. Return key.

Import Key
  1. Let keyData be the key data to be imported.

  2. If usages contains an entry which is not "sign" or "verify", then throw a SyntaxError.

  3. If format is "raw-secret":
    1. Let data be keyData.

    If format is "jwk":
    1. If keyData is a JsonWebKey dictionary:

      Let jwk equal keyData.

      Otherwise:

      Throw a DataError.

    2. If the kty field of jwk is not "oct", then throw a DataError.

    3. If jwk does not meet the requirements of Section 6.4 of JSON Web Algorithms [JWA], then throw a DataError.

    4. Let data be the byte sequence obtained by decoding the k field of jwk.

    5. If the name member of normalizedAlgorithm is a case-sensitive string match for "KMAC128":
      If the alg field of jwk is present and is not "K128", then throw a DataError.
      If the name member of normalizedAlgorithm is a case-sensitive string match for "KMAC256":
      If the alg field of jwk is present and is not "K256", then throw a DataError.
    6. If usages is non-empty and the use field of jwk is present and is not "sign", then throw a DataError.

    7. If the key_ops field of jwk is present, and is invalid according to the requirements of JSON Web Key [JWK] or does not contain all of the specified usages values, then throw a DataError.

    8. If the ext field of jwk is present and has the value false and extractable is true, then throw a DataError.

    Otherwise:
    throw a NotSupportedError.
  4. Let length be equivalent to the length, in octets, of data, multiplied by 8.

  5. If length is zero then throw a DataError.

  6. If the length member of normalizedAlgorithm is present:
    If the length member of normalizedAlgorithm is greater than length:
    throw a DataError.
    If the length member of normalizedAlgorithm, is less than or equal to length minus eight:
    throw a DataError.
    Otherwise:
    Set length equal to the length member of normalizedAlgorithm.
  7. Let key be a new CryptoKey object representing an KMAC key with the first length bits of data.

  8. Let algorithm be a new KmacKeyAlgorithm.

  9. Set the name attribute of algorithm to "KMAC".

  10. Set the length attribute of algorithm to length.

  11. Set the [[algorithm]] internal slot of key to algorithm.

  12. Return key.

Export Key
  1. If the underlying cryptographic key material represented by the [[handle]] internal slot of key cannot be accessed, then throw an OperationError.

  2. Let bits be the raw bits of the key represented by [[handle]] internal slot of key.

  3. Let data be an byte sequence containing bits.

  4. If format is "raw-secret":
    1. Let result be data.

    If format is "jwk":
    1. Let jwk be a new JsonWebKey dictionary.

    2. Set the kty attribute of jwk to the string "oct".

    3. Set the k attribute of jwk to be a string containing data, encoded according to Section 6.4 of JSON Web Algorithms [JWA].

    4. Let algorithm be the [[algorithm]] internal slot of key.

    5. If the name member of normalizedAlgorithm is a case-sensitive string match for "KMAC128":
      Set the alg attribute of jwk to the string "K128".
      If the name member of normalizedAlgorithm is a case-sensitive string match for "KMAC256":
      Set the alg attribute of jwk to the string "K256".
    6. Set the key_ops attribute of jwk to equal the usages attribute of key.

    7. Set the ext attribute of jwk to equal the [[extractable]] internal slot of key.

    8. Let result be the result of converting jwk to an ECMAScript Object, as defined by [WebIDL].

    Otherwise:

    throw a NotSupportedError.

  5. Return result.

Get key length
  1. If the length member of normalizedAlgorithm is present:
    Let length be equal to the length member of normalizedAlgorithm.
    Otherwise, if the name member of normalizedAlgorithm is a case-sensitive string match for "KMAC128":
    Let length be 128.
    Otherwise, if the name member of normalizedAlgorithm is a case-sensitive string match for "KMAC256":
    Let length be 256.
  2. Return length.

13. Argon2

13.1 Description

This section is non-normative.

This describes the Argon2 function for password hashing and key derivation, as defined in [RFC9106].

13.2 Registration

The recognized algorithm names are "Argon2d", "Argon2i", and "Argon2id" for the respective Argon2 types.

Operation Parameters Result
deriveBits Argon2Params byte sequence
importKey None CryptoKey
Get key length None null

13.3 Argon2Params dictionary

WebIDLdictionary Argon2Params : Algorithm {
  required BufferSource nonce;
  required [EnforceRange] unsigned long parallelism;
  required [EnforceRange] unsigned long memory;
  required [EnforceRange] unsigned long passes;
  [EnforceRange] octet version;
  BufferSource secretValue;
  BufferSource associatedData;
};

The nonce member represents the nonce, which is a salt for password hashing applications.

The parallelism member represents the degree of parallelism.

The memory member represents the memory size in kibibytes. It must be at least 8 times the degree of parallelism.

The passes member represents the number of passes.

The version member represents the version number. The default and currently only defined version is 19 (0x13).

The secretValue member represents the optional secret value.

The associatedData member represents the optional associated data.

Note

For the recommended values of the parameters, see section 4 of [RFC9106].

13.4 Operations

Derive Bits
  1. If length is null, or is less than 32 (4*8), then throw an OperationError.

  2. If the version member of normalizedAlgorithm is present and is not 19 (0x13), then throw an OperationError.

  3. If the parallelism member of normalizedAlgorithm is zero, or greater than 16777215 (2^24-1), then throw an OperationError.

  4. If the memory member of normalizedAlgorithm is less than 8 times the parallelism member of normalizedAlgorithm, then throw an OperationError.

  5. If the passes member of normalizedAlgorithm is zero, then throw an OperationError.

  6. If the name member of normalizedAlgorithm is a case-sensitive string match for "Argon2d":
    Let type be 0.
    If the name member of normalizedAlgorithm is a case-sensitive string match for "Argon2i":
    Let type be 1.
    If the name member of normalizedAlgorithm is a case-sensitive string match for "Argon2id":
    Let type be 2.
  7. Let secretValue be the secretValue member of normalizedAlgorithm, if present.

  8. Let associatedData be the associatedData member of normalizedAlgorithm, if present.

  9. Let result be the result of performing the Argon2 function defined in Section 3 of [RFC9106] using the password represented by [[handle]] internal slot of key as the message, P, the nonce attribute of normalizedAlgorithm as the nonce, S, the value of the parallelism attribute of normalizedAlgorithm as the degree of parallelism, p, the value of the memory attribute of normalizedAlgorithm as the memory size, m, the value of the passes attribute of normalizedAlgorithm as the number of passes, t, 0x13 as the version number, v, secretValue (if present) as the secret value, K, associatedData (if present) as the associated data, X, type as the type, y, and length divided by 8 as the tag length, T.

  10. If the key derivation operation fails, then throw an OperationError.

  11. Return result.

Import key
  1. If format is not "raw-secret", throw a NotSupportedError

  2. If usages contains a value that is not "deriveKey" or "deriveBits", then throw a SyntaxError.

  3. If extractable is not false, then throw a SyntaxError.

  4. Let key be a new CryptoKey representing keyData.

  5. Set the [[type]] internal slot of key to "secret".

  6. Set the [[extractable]] internal slot of key to false.

  7. Let algorithm be a new KeyAlgorithm object.

  8. Set the name attribute of algorithm to the name member of normalizedAlgorithm.

  9. Set the [[algorithm]] internal slot of key to algorithm.

  10. Return key.

Get key length
  1. Return null.

14. Usage Example

This example derives a key from a password using Argon2, if available, or PBKDF2, otherwise; and then encrypts and decrypts some text with it using AES-OCB, if available, and AES-GCM, otherwise.

Example 1: Encrypt some data using a key derived from a password
const password = 'correct horse battery staple';
const derivationAlg =
  SubtleCrypto.supports?.('importKey', 'Argon2id') ?
    'Argon2id' :
    'PBKDF2';
const encryptionAlg =
  SubtleCrypto.supports?.('importKey', 'AES-OCB') ?
    'AES-OCB' :
    'AES-GCM';
const passwordKey = await crypto.subtle.importKey(
  'raw',
  new TextEncoder().encode(password),
  derivationAlg,
  /* extractable: */ false,
  ['deriveKey']
);
const nonce = crypto.getRandomValues(new Uint8Array(16));
const derivationParams =
  derivationAlg === 'Argon2id' ?
    {
      nonce,
      parallelism: 4,
      memory: 2 ** 21,
      passes: 1
    } :
    {
      salt: nonce,
      iterations: 100_000,
      hash: 'SHA-256'
    };
const key = await crypto.subtle.deriveKey(
  {
    name: derivationAlg,
    ...derivationParams
  },
  passwordKey,
  {
    name: encryptionAlg,
    length: 256
  },
  /* extractable: */ false,
  ['encrypt', 'decrypt']
);
const plaintext = 'Hello, world!';
const iv = crypto.getRandomValues(new Uint8Array(16));
const encrypted = await crypto.subtle.encrypt(
  { name: encryptionAlg, iv },
  key,
  new TextEncoder().encode(plaintext)
);
// Store the derivation and encryption algorithm and parameters
// as well as the ciphertext (e.g. in IndexedDB or a database),
// and retrieve them later. Then, derive the key using the
// original parameters and the password. Here we immediately
// use the same key object to decrypt again.
const decrypted = new TextDecoder().decode(await crypto.subtle.decrypt(
  { name: encryptionAlg, iv },
  key,
  encrypted
));

A. Mapping between JSON Web Key / JSON Web Algorithm

This section is non-normative.

Refer to algorithm-specific sections for the normative requirements of importing and exporting JWK.

A.1 Algorithm mappings

JSON Web Key AlgorithmIdentifier
{ kty: "oct",
alg: "A128OCB" }
{ name: "AES-OCB",
length: 128 }
{ kty: "oct",
alg: "A192OCB" }
{ name: "AES-OCB",
length: 192 }
{ kty: "oct",
alg: "A256OCB" }
{ name: "AES-OCB",
length: 256 }
{ kty: "oct",
alg: "CC20P1305" }
{ name: "ChaCha20-Poly1305" }
{ kty: "oct",
alg: "K128" }
{ name: "KMAC128" }
{ kty: "oct",
alg: "K256" }
{ name: "KMAC256" }
TODO: register A128OCB, A192OCB, A256OCB, CC20P1305, K128 and K256(?) with IANA in the JSON Web Signature and Encryption Algorithms registry.
TODO: define JWK algorithms for ML-KEM, ML-DSA and SLH-DSA.

B. Conformance

As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

The key word MUST in this document is to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

C. References

C.1 Normative references

[FIPS-202]
SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions. NIST. August 2015. URL: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
[FIPS-203]
Module-Lattice-Based Key-Encapsulation Mechanism Standard. NIST. August 2024. URL: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.203.pdf
[FIPS-204]
Module-Lattice-Based Digital Signature Standard. NIST. August 2024. URL: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.204.pdf
[FIPS-205]
Stateless Hash-Based Digital Signature Standard. NIST. August 2024. URL: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.205.pdf
[html]
HTML Standard. Anne van Kesteren; Domenic Denicola; Dominic Farolino; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[infra]
Infra Standard. Anne van Kesteren; Domenic Denicola. WHATWG. Living Standard. URL: https://infra.spec.whatwg.org/
[JWA]
JSON Web Algorithms (JWA). M. Jones. IETF. May 2015. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc7518
[JWK]
JSON Web Key (JWK). M. Jones. IETF. May 2015. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc7517
[NIST-SP800-185]
NIST Special Publication 800-185: SHA-3 Derived Functions: cSHAKE, KMAC, TupleHash and ParallelHash. NIST. December 2016. URL: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-185.pdf
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. March 1997. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC7253]
The OCB Authenticated-Encryption Algorithm. T. Krovetz; P. Rogaway. IETF. May 2014. Informational. URL: https://www.rfc-editor.org/rfc/rfc7253
[RFC8174]
Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words. B. Leiba. IETF. May 2017. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc8174
[RFC8439]
ChaCha20 and Poly1305 for IETF Protocols. Y. Nir; A. Langley. IETF. June 2018. Informational. URL: https://www.rfc-editor.org/rfc/rfc8439
[RFC9106]
Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applications. A. Biryukov; D. Dinu; D. Khovratovich; S. Josefsson. IETF. September 2021. Informational. URL: https://www.rfc-editor.org/rfc/rfc9106
[WebCryptoAPI]
Web Cryptography API. Mark Watson. W3C. 26 January 2017. W3C Recommendation. URL: https://www.w3.org/TR/WebCryptoAPI/
[WebIDL]
Web IDL Standard. Edgar Chen; Timothy Gu. WHATWG. Living Standard. URL: https://webidl.spec.whatwg.org/