From 817812779f3d06570525bf552bb3fc97263f7ecd Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Sat, 21 Mar 2026 20:37:52 +0100 Subject: [PATCH 1/7] add signDigest and verifyDigest operations --- spec/Overview.html | 897 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 887 insertions(+), 10 deletions(-) diff --git a/spec/Overview.html b/spec/Overview.html index 7f88a4c..cfbf723 100644 --- a/spec/Overview.html +++ b/spec/Overview.html @@ -1269,6 +1269,17 @@

SubtleCrypto interface

BufferSource signature, BufferSource data ); + Promise<ArrayBuffer> signDigest( + AlgorithmIdentifier algorithm, + CryptoKey key, + BufferSource digest + ); + Promise<boolean> verifyDigest( + AlgorithmIdentifier algorithm, + CryptoKey key, + BufferSource signature, + BufferSource digest + ); Promise<ArrayBuffer> digest( AlgorithmIdentifier algorithm, BufferSource data @@ -1827,6 +1838,222 @@

The verify method

+
+

The signDigest method

+

+ The signDigest method returns a + new Promise object that will sign a pre-computed digest using the specified {{AlgorithmIdentifier}} with the supplied + {{CryptoKey}}. + It must act as follows: +

+
    +
  1. +

    + Let |algorithm| and |key| be the + `algorithm` and `key` parameters + passed to the {{SubtleCrypto/signDigest()}} method, + respectively. +

    +
  2. +
  3. +

    + Let |normalizedAlgorithm| be the result of + normalizing an algorithm, with + `alg` set to |algorithm| and `op` set to + "`signDigest`". +

    +
  4. +
  5. +

    + If an error occurred, return a Promise rejected with + |normalizedAlgorithm|. +

    +
  6. +
  7. +

    + Let |data| be the result of + [= get a copy of the buffer source | + getting a copy of the bytes held by =] the `digest` parameter passed to the + {{SubtleCrypto/signDigest()}} method. +

    +
  8. +
  9. +

    + Let |realm| be the [= relevant realm =] of [= this =]. +

    +
  10. +
  11. +

    + Let |promise| be a new Promise. +

    +
  12. +
  13. +

    + Return |promise| and perform the remaining steps [= in parallel =]. +

    +
  14. +
  15. +

    + If the following steps or referenced procedures say to + [= exception/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 =]. +

    +
  16. +
  17. +

    + If the {{Algorithm/name}} member of + |normalizedAlgorithm| is not equal to the + {{KeyAlgorithm/name}} attribute of the + {{CryptoKey/[[algorithm]]}} internal slot of + |key| then [= exception/throw =] an {{InvalidAccessError}}. +

    +
  18. +
  19. +

    + If the {{CryptoKey/[[usages]]}} internal slot of + |key| does not contain an entry that is "`sign`", then [= exception/throw =] an {{InvalidAccessError}}. +

    +
  20. +
  21. +

    + Let |signature| be the result of performing the signDigest operation + specified by |normalizedAlgorithm| using |key| and + |algorithm| and with |data| as |digest|. +

    +
  22. +
  23. +

    + [= Queue a global task =] on the [= crypto task source =], + given |realm|'s global object, to perform the remaining steps. +

    +
  24. +
  25. +

    + Let |result| be the result of [= ArrayBuffer/create | creating =] an {{ArrayBuffer}} + in |realm|, containing |signature|. +

    +
  26. +
  27. +

    + Resolve |promise| with + |result|. +

    +
  28. +
+
+ +
+

The verifyDigest method

+

+ The verifyDigest method returns + a new Promise object that will verify a signature against a pre-computed digest using the specified {{AlgorithmIdentifier}} with the supplied + {{CryptoKey}}. + It must act as follows: +

+
    +
  1. +

    + Let |algorithm| and |key| + be the `algorithm` and `key` parameters passed to the + {{SubtleCrypto/verifyDigest()}} method, respectively. +

    +
  2. +
  3. +

    + Let |normalizedAlgorithm| be the result of + normalizing an algorithm, with + `alg` set to |algorithm| and `op` set to + "`verifyDigest`". +

    +
  4. +
  5. +

    + If an error occurred, return a Promise rejected with + |normalizedAlgorithm|. +

    +
  6. +
  7. +

    + Let |signature| be the result of + [= get a copy of the buffer source | + getting a copy of the bytes held by =] the `signature` parameter passed to the + {{SubtleCrypto/verifyDigest()}} method. +

    +
  8. +
  9. +

    + Let |data| be the result of + [= get a copy of the buffer source | + getting a copy of the bytes held by =] the `digest` parameter passed to the + {{SubtleCrypto/verifyDigest()}} method. +

    +
  10. +
  11. +

    + Let |realm| be the [= relevant realm =] of [= this =]. +

    +
  12. +
  13. +

    + Let |promise| be a new Promise. +

    +
  14. +
  15. +

    + Return |promise| and perform the remaining steps [= in parallel =]. +

    +
  16. +
  17. +

    + If the following steps or referenced procedures say to + [= exception/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 =]. +

    +
  18. +
  19. +

    + If the {{Algorithm/name}} member of + |normalizedAlgorithm| is not equal to the + {{KeyAlgorithm/name}} attribute of the + {{CryptoKey/[[algorithm]]}} internal slot of + |key| then [= exception/throw =] an {{InvalidAccessError}}. +

    +
  20. +
  21. +

    + If the {{CryptoKey/[[usages]]}} internal slot of + |key| does not contain an entry that is "`verify`", then [= exception/throw =] an {{InvalidAccessError}}. +

    +
  22. +
  23. +

    + Let |result| be the result of performing the verifyDigest operation + specified by |normalizedAlgorithm| using |key|, + |algorithm| and + |signature| and with |data| as |digest|. +

    +
  24. +
  25. +

    + [= Queue a global task =] on the [= crypto task source =], + given |realm|'s global object, to perform the remaining steps. +

    +
  26. +
  27. +

    + Resolve |promise| with + |result|. +

    +
  28. +
+
+

The digest method

@@ -3118,6 +3345,8 @@

Supported Operations

  • decrypt
  • sign
  • verify
  • +
  • signDigest
  • +
  • verifyDigest
  • digest
  • deriveBits
  • wrapKey
  • @@ -3490,6 +3719,12 @@

    Algorithm Overview

  • The {{SubtleCrypto/verify}} method requires the verify operation.

  • +
  • +

    The {{SubtleCrypto/signDigest}} method requires the signDigest operation.

    +
  • +
  • +

    The {{SubtleCrypto/verifyDigest}} method requires the verifyDigest operation.

    +
  • The {{SubtleCrypto/generateKey}} method requires the generateKey operation.

  • @@ -3537,6 +3772,8 @@

    Algorithm Overview

    decrypt sign verify + signDigest + verifyDigest digest generateKey deriveKey @@ -3554,6 +3791,8 @@

    Algorithm Overview

    ✔ ✔ + ✔ + ✔ ✔ @@ -3569,6 +3808,8 @@

    Algorithm Overview

    ✔ ✔ + ✔ + ✔ ✔ @@ -3585,6 +3826,8 @@

    Algorithm Overview

    + + ✔ @@ -3599,6 +3842,8 @@

    Algorithm Overview

    ✔ ✔ + ✔ + ✔ ✔ @@ -3615,6 +3860,8 @@

    Algorithm Overview

    + + ✔ ✔ ✔ @@ -3629,6 +3876,8 @@

    Algorithm Overview

    ✔ ✔ + ✔ + ✔ ✔ @@ -3645,6 +3894,8 @@

    Algorithm Overview

    + + ✔ ✔ ✔ @@ -3660,6 +3911,8 @@

    Algorithm Overview

    + + ✔ @@ -3675,6 +3928,8 @@

    Algorithm Overview

    + + ✔ @@ -3690,6 +3945,8 @@

    Algorithm Overview

    + + ✔ @@ -3705,6 +3962,8 @@

    Algorithm Overview

    + + ✔ @@ -3720,6 +3979,8 @@

    Algorithm Overview

    ✔ ✔ + + ✔ @@ -3734,6 +3995,8 @@

    Algorithm Overview

    + + ✔ @@ -3749,6 +4012,8 @@

    Algorithm Overview

    + + ✔ @@ -3764,6 +4029,8 @@

    Algorithm Overview

    + + ✔ @@ -3779,6 +4046,8 @@

    Algorithm Overview

    + + ✔ @@ -3796,6 +4065,8 @@

    Algorithm Overview

    + + ✔ ✔ ✔ @@ -3811,6 +4082,8 @@

    Algorithm Overview

    + + ✔ ✔ ✔ @@ -3865,6 +4138,16 @@

    Registration

    None boolean + + signDigest + None + [= byte sequence =] + + + verifyDigest + None + boolean + generateKey {{RsaHashedKeyGenParams}} @@ -4010,6 +4293,99 @@
    Verify
    +
    +
    Sign Digest
    + +
      +
    1. +

      + If the {{CryptoKey/[[type]]}} internal slot of + |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. +

      +
    2. +
    3. +

      + If the [= byte sequence/length =] of |digest| is not equal to + the digest length of the hash function identified by the + {{RsaHashedKeyAlgorithm/hash}} attribute of the + {{CryptoKey/[[algorithm]]}} internal slot of |key|, + then [= exception/throw =] an {{OperationError}}. +

      +
    4. +
    5. +

      + Perform the signature generation operation defined in Section 8.2 of [[RFC3447]] with the key represented by the {{CryptoKey/[[handle]]}} internal slot of |key| + as the signer's private key and |digest| as + the digest for the EMSA-PKCS1-v1_5 encoding method, and using the hash function specified in the {{RsaHashedKeyAlgorithm/hash}} attribute of the {{CryptoKey/[[algorithm]]}} internal slot of + |key| as the Hash option for identifying the hash in the DigestInfo encoding. +

      +
    6. +
    7. +

      + If performing the operation results in an error, + then [= exception/throw =] an + {{OperationError}}. +

      +
    8. +
    9. +

      + Let |signature| be the value |S| that results from + performing the operation. +

      +
    10. +
    11. +

      + Return |signature|. +

      +
    12. +
    +
    + +
    +
    Verify Digest
    + +
      +
    1. +

      + If the {{CryptoKey/[[type]]}} internal slot of + |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. +

      +
    2. +
    3. +

      + If the [= byte sequence/length =] of |digest| is not equal to + the digest length of the hash function identified by the + {{RsaHashedKeyAlgorithm/hash}} attribute of the + {{CryptoKey/[[algorithm]]}} internal slot of |key|, + then [= exception/throw =] an {{OperationError}}. +

      +
    4. +
    5. +

      + Perform the signature verification operation defined in Section 8.2 of + [[RFC3447]] with the key represented by the + {{CryptoKey/[[handle]]}} internal slot of + |key| as the signer's RSA public key and |digest| as + the digest for the EMSA-PKCS1-v1_5 encoding method and + |signature| as |S| and using the hash function specified + in the {{RsaHashedKeyAlgorithm/hash}} attribute of the + {{CryptoKey/[[algorithm]]}} internal slot of + |key| as the Hash option for identifying the hash in the DigestInfo encoding. +

      +
    6. +
    7. +

      + Let |result| be a boolean with value true if the + result of the operation was "valid signature" and the value + false otherwise. +

      +
    8. +
    9. +

      Return |result|.

      +
    10. +
    +
    +
    Generate Key
    @@ -4939,6 +5315,16 @@

    Registration

    {{RsaPssParams}} boolean + + signDigest + {{RsaPssParams}} + [= byte sequence =] + + + verifyDigest + {{RsaPssParams}} + boolean + generateKey {{RsaHashedKeyGenParams}} @@ -5047,6 +5433,102 @@
    Verify
    +
    +
    Sign Digest
    + +
      +
    1. +

      + If the {{CryptoKey/[[type]]}} internal slot of + |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. +

      +
    2. +
    3. +

      + If the [= byte sequence/length =] of |digest| is not equal to + the digest length of the hash function identified by the + {{RsaHashedKeyAlgorithm/hash}} attribute of the + {{CryptoKey/[[algorithm]]}} internal slot of |key|, + then [= exception/throw =] an {{OperationError}}. +

      +
    4. +
    5. +

      + Perform the signature generation operation defined in Section 8.1 of [[RFC3447]] with the key represented by the {{CryptoKey/[[handle]]}} internal slot of |key| + as the signer's private key, |K|, and |digest| as + the hash value for the EMSA-PSS-ENCODE operation, and using the hash function specified + by the {{RsaHashedKeyAlgorithm/hash}} attribute of the + {{CryptoKey/[[algorithm]]}} internal slot of + |key| as the Hash option, MGF1 (defined in Section B.2.1 of [[RFC3447]]) as the MGF option and the saltLength member of + |normalizedAlgorithm| as the salt length option for the + EMSA-PSS-ENCODE operation. +

      +
    6. +
    7. +

      + If performing the operation results in an error, + then [= exception/throw =] an + {{OperationError}}. +

      +
    8. +
    9. +

      + Let |signature| be the + signature, S, that results from performing the operation. +

      +
    10. +
    11. +

      + Return |signature|. +

      +
    12. +
    +
    + +
    +
    Verify Digest
    + +
      +
    1. +

      + If the {{CryptoKey/[[type]]}} internal slot of + |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. +

      +
    2. +
    3. +

      + If the [= byte sequence/length =] of |digest| is not equal to + the digest length of the hash function identified by the + {{RsaHashedKeyAlgorithm/hash}} attribute of the + {{CryptoKey/[[algorithm]]}} internal slot of |key|, + then [= exception/throw =] an {{OperationError}}. +

      +
    4. +
    5. +

      + Perform the signature verification operation defined in Section 8.1 of + [[RFC3447]] with the key represented by the + {{CryptoKey/[[handle]]}} internal slot of + |key| as the signer's RSA public key and |digest| as + the hash value for the EMSA-PSS-VERIFY operation and + |signature| as |S| and using the hash function specified + by the {{RsaHashedKeyAlgorithm/hash}} attribute of the + {{CryptoKey/[[algorithm]]}} internal slot of + |key| as the Hash option, MGF1 (defined in Section B.2.1 of [[RFC3447]]) as the MGF option and the saltLength member of + |normalizedAlgorithm| as the salt length option for the + EMSA-PSS-VERIFY operation. +

      +
    6. +
    7. +

      + Let |result| be a boolean with the value true if the + result of the operation was "valid signature" and the value + false otherwise. +

      +
    8. +
    +
    +
    Generate Key
    @@ -7008,6 +7490,16 @@

    Registration

    {{EcdsaParams}} boolean + + signDigest + {{EcdsaParams}} + [= byte sequence =] + + + verifyDigest + {{EcdsaParams}} + boolean + generateKey {{EcKeyGenParams}} @@ -7083,11 +7575,222 @@

    EcKeyImportParams dictionary<

    The namedCurve member represents a named curve.

    -
    -

    Operations

    +
    +

    Operations

    + +
    +
    Sign
    + +
      +
    1. +

      + If the {{CryptoKey/[[type]]}} internal slot of + |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. +

      +
    2. +
    3. +

      + Let |hashAlgorithm| be the {{EcdsaParams/hash}} + member of |normalizedAlgorithm|. +

      +
    4. +
    5. +

      + Let |M| be the result of performing the digest operation specified by + |hashAlgorithm| using |message|. +

      +
    6. +
    7. +

      + Let |d| be the ECDSA private key associated with |key|. +

      +
    8. +
    9. +

      + Let |params| be the EC domain parameters associated with + |key|. +

      +
    10. +
    11. +
      +
      + If the {{EcKeyAlgorithm/namedCurve}} attribute of the + {{CryptoKey/[[algorithm]]}} internal slot of + |key| is "`P-256`", "`P-384`" or "`P-521`": +
      +
      +
        +
      1. +

        + Perform the ECDSA signing process, as specified in [[RFC6090]], + Section 5.4.2, with |M| as the message, using |params| as the + EC domain parameters, and with |d| as the private key. +

        +
      2. +
      3. +

        + Let |r| and |s| be the pair of integers resulting from + performing the ECDSA signing process. +

        +
      4. +
      5. +

        + Let |result| be an empty [= byte sequence =]. +

        +
      6. +
      7. +

        + Let |n| be the smallest integer such that |n| * 8 is greater than + the logarithm to base 2 of the order of the base point of the elliptic curve identified + by |params|. +

        +
      8. +
      9. +

        + Convert |r| to a byte sequence of + length |n| and append it to |result|. +

        +
      10. +
      11. +

        + Convert |s| to a byte sequence of + length |n| and append it to |result|. +

        +
      12. +
      +
      +
      + Otherwise, the {{EcKeyAlgorithm/namedCurve}} attribute + of the {{CryptoKey/[[algorithm]]}} internal slot of + |key| is a value specified in an + applicable specification: +
      +
      +

      + Perform the [= ECDSA signature steps =] + specified in that specification, passing in |M|, |params| + and |d| and resulting in |result|. +

      +
      +
      +
    12. +
    13. +

      + Return |result|. +

      +
    14. +
    +
    + +
    +
    Verify
    +
      +
    1. +

      + If the {{CryptoKey/[[type]]}} internal slot of + |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. +

      +
    2. +
    3. +

      + Let |hashAlgorithm| be the {{EcdsaParams/hash}} + member of + |normalizedAlgorithm|. +

      +
    4. +
    5. +

      + Let |M| be the result of performing the digest operation specified by + |hashAlgorithm| using |message|. +

      +
    6. +
    7. +

      + Let |Q| be the ECDSA public key associated with |key|. +

      +
    8. +
    9. +

      + Let |params| be the EC domain parameters associated with + |key|. +

      +
    10. +
    11. +
      +
      + If the {{EcKeyAlgorithm/namedCurve}} attribute of the + {{CryptoKey/[[algorithm]]}} internal slot of + |key| is "`P-256`", "`P-384`" or "`P-521`": +
      +
      +
        +
      1. +

        + Let |n| be the smallest integer such that |n| * 8 is greater than + the logarithm to base 2 of the order of the base point of the elliptic curve identified + by |params|. +

        +
      2. +
      3. +

        + If |signature| does not have a [= byte sequence/length =] of |n| * 2 bytes, + then return false. +

        +
      4. +
      5. +

        + Let |r| be the result of + converting the first |n| bytes of |signature| to an integer. +

        +
      6. +
      7. +

        + Let |s| be the result of + converting the last |n| bytes of |signature| to an integer. +

        +
      8. +
      9. +

        + Perform the ECDSA verifying process, as specified in [[RFC6090]], Section 5.4.3, with |M| as the received + message, (|r|, |s|) as the signature and using + |params| as the EC domain parameters, and + |Q| as the public key. +

        +
      10. +
      +
      +
      + Otherwise, the {{EcKeyAlgorithm/namedCurve}} attribute + of the {{CryptoKey/[[algorithm]]}} internal slot of + |key| is a value specified in an + applicable specification: +
      +
      +

      + Perform the [= ECDSA verification steps =] + specified in that specification passing in |M|, |signature|, + |params| and |Q| and resulting in an indication of whether + or not the purported signature is valid. +

      +
      +
      +
    12. +
    13. +

      + Let |result| be a boolean with the value `true` if the signature is valid + and the value `false` otherwise. +

      +
    14. +
    15. +

      + Return |result|. +

      +
    16. +
    +
    -
    -
    Sign
    +
    +
    Sign Digest
    1. @@ -7104,8 +7807,15 @@
      Sign
    2. - Let |M| be the result of performing the digest operation specified by - |hashAlgorithm| using |message|. + If the [= byte sequence/length =] of |digest| is not equal to + the digest length of the hash function identified by + |hashAlgorithm|, + then [= exception/throw =] an {{OperationError}}. +

      +
    3. +
    4. +

      + Let |M| be |digest|.

    5. @@ -7190,8 +7900,8 @@
      Sign
    -
    -
    Verify
    +
    +
    Verify Digest
    1. @@ -7208,8 +7918,15 @@

      Verify
    2. - Let |M| be the result of performing the digest operation specified by - |hashAlgorithm| using |message|. + If the [= byte sequence/length =] of |digest| is not equal to + the digest length of the hash function identified by + |hashAlgorithm|, + then [= exception/throw =] an {{OperationError}}. +

      +
    3. +
    4. +

      + Let |M| be |digest|.

    5. @@ -10346,6 +11063,16 @@

      Registration

      None boolean + + signDigest + {{ContextParams}} + [= byte sequence =] + + + verifyDigest + {{ContextParams}} + boolean + generateKey None @@ -10364,9 +11091,33 @@

      Registration

    +
    +

    ContextParams dictionary

    +
    +dictionary ContextParams : Algorithm {
    +  BufferSource context;
    +};
    +          
    +

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

    +

    Operations

    +

    + The sign and + verify operations + use Ed25519 (pure EdDSA), while the + sign digest and + verify digest + operations use Ed25519ph (prehashed EdDSA). These produce + cryptographically distinct signatures. A signature produced with + sign cannot be verified + with verify digest, + and a signature produced with + sign digest + cannot be verified with + verify. +

    Sign
    @@ -10450,6 +11201,132 @@
    Verify
    +
    +
    Sign Digest
    + +
      +
    1. +

      + If the {{CryptoKey/[[type]]}} internal slot of + |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. +

      +
    2. +
    3. +

      + If the [= byte sequence/length =] of |digest| is not 64, + then [= exception/throw =] an {{OperationError}}. +

      +
    4. +
    5. +

      + Let |context| be the {{ContextParams/context}} member of + |normalizedAlgorithm|, or the empty octet string if + the {{ContextParams/context}} member of + |normalizedAlgorithm| is not present. +

      +
    6. +
    7. +

      + If the [= byte sequence/length =] of |context| is greater + than 255 bytes, + then [= exception/throw =] an {{OperationError}}. +

      +
    8. +
    9. +

      + Let |result| be the result of performing the Ed25519ph + signing process, as specified in [[RFC8032]], + Section 5.1, with |digest| as PH(M), + phflag set to 1, and |context| as the context C, + using the Ed25519 private key associated with |key|. +

      +

      + Some implementations may (wish to) generate randomized signatures + as per draft-irtf-cfrg-det-sigs-with-noise + instead of deterministic signatures as per [[RFC8032]]. +

      +
    10. +
    11. +

      + Return |result|. +

      +
    12. +
    +
    + +
    +
    Verify Digest
    + +
      +
    1. +

      + If the {{CryptoKey/[[type]]}} internal slot of + |key| is not {{KeyType/"public"}}, then [= exception/throw =] an {{InvalidAccessError}}. +

      +
    2. +
    3. +

      + If the [= byte sequence/length =] of |digest| is not 64, + then [= exception/throw =] an {{OperationError}}. +

      +
    4. +
    5. +

      + If the key data of |key| represents an invalid point or a small-order element + on the Elliptic Curve of Ed25519, return `false`. +

      +

      + Not all implementations perform this check. +

      +
    6. +
    7. +

      + If the point R, encoded in the first half of |signature|, + represents an invalid point or a small-order element + on the Elliptic Curve of Ed25519, return `false`. +

      +

      + Not all implementations perform this check. +

      +
    8. +
    9. +

      + Let |context| be the {{ContextParams/context}} member of + |normalizedAlgorithm|, or the empty octet string if + the {{ContextParams/context}} member of + |normalizedAlgorithm| is not present. +

      +
    10. +
    11. +

      + If the [= byte sequence/length =] of |context| is greater + than 255 bytes, + then [= exception/throw =] an {{OperationError}}. +

      +
    12. +
    13. +

      + Perform the Ed25519ph verification steps, as specified in [[RFC8032]], + Section 5.1, using the cofactorless (unbatched) equation, + `[S]B = R + [k]A'`, on the |signature|, with |digest| as PH(M), + phflag set to 1, and |context| as the context C, + using the Ed25519 public key associated with |key|. +

      +
    14. +
    15. +

      + Let |result| be a boolean with the value `true` if the signature is valid + and the value `false` otherwise. +

      +
    16. +
    17. +

      + Return |result|. +

      +
    18. +
    +
    +
    Generate Key
    From c611e0876440d819916a11c8c299aeede3c11a68 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Sun, 22 Mar 2026 09:51:38 +0100 Subject: [PATCH 2/7] fixup! add signDigest and verifyDigest operations --- spec/Overview.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/Overview.html b/spec/Overview.html index cfbf723..8dd445d 100644 --- a/spec/Overview.html +++ b/spec/Overview.html @@ -4357,7 +4357,7 @@
    Verify Digest
    the digest length of the hash function identified by the {{RsaHashedKeyAlgorithm/hash}} attribute of the {{CryptoKey/[[algorithm]]}} internal slot of |key|, - then [= exception/throw =] an {{OperationError}}. + then return `false`.

  • @@ -5501,7 +5501,7 @@
    Verify Digest
    the digest length of the hash function identified by the {{RsaHashedKeyAlgorithm/hash}} attribute of the {{CryptoKey/[[algorithm]]}} internal slot of |key|, - then [= exception/throw =] an {{OperationError}}. + then return `false`.

  • @@ -7921,7 +7921,7 @@
    Verify Digest
    If the [= byte sequence/length =] of |digest| is not equal to the digest length of the hash function identified by |hashAlgorithm|, - then [= exception/throw =] an {{OperationError}}. + then return `false`.

  • @@ -11267,7 +11267,7 @@
    Verify Digest
  • If the [= byte sequence/length =] of |digest| is not 64, - then [= exception/throw =] an {{OperationError}}. + then return `false`.

  • From 4b77e4d96e06afa73813f7fa3e7287df6615d2c5 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Sun, 22 Mar 2026 09:55:06 +0100 Subject: [PATCH 3/7] fixup! add signDigest and verifyDigest operations --- spec/Overview.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/Overview.html b/spec/Overview.html index 8dd445d..37ec07e 100644 --- a/spec/Overview.html +++ b/spec/Overview.html @@ -4357,7 +4357,7 @@
    Verify Digest
    the digest length of the hash function identified by the {{RsaHashedKeyAlgorithm/hash}} attribute of the {{CryptoKey/[[algorithm]]}} internal slot of |key|, - then return `false`. + then return false.

  • @@ -5501,7 +5501,7 @@
    Verify Digest
    the digest length of the hash function identified by the {{RsaHashedKeyAlgorithm/hash}} attribute of the {{CryptoKey/[[algorithm]]}} internal slot of |key|, - then return `false`. + then return false.

  • @@ -7921,7 +7921,7 @@
    Verify Digest
    If the [= byte sequence/length =] of |digest| is not equal to the digest length of the hash function identified by |hashAlgorithm|, - then return `false`. + then return false.

  • @@ -11267,7 +11267,7 @@
    Verify Digest
  • If the [= byte sequence/length =] of |digest| is not 64, - then return `false`. + then return false.

  • From b1456aa6291445d7c5f9319f223d1d26f7f1ef59 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Mon, 23 Mar 2026 12:39:05 +0100 Subject: [PATCH 4/7] fixup! add signDigest and verifyDigest operations --- spec/Overview.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec/Overview.html b/spec/Overview.html index 37ec07e..4471251 100644 --- a/spec/Overview.html +++ b/spec/Overview.html @@ -5430,6 +5430,9 @@
    Verify
    false otherwise.

  • +
  • +

    Return |result|.

    +
  • From 8dee9a781be43c45d67ca6c8f6b232d08aabe5e4 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Mon, 23 Mar 2026 12:44:22 +0100 Subject: [PATCH 5/7] fixup! add signDigest and verifyDigest operations --- spec/Overview.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec/Overview.html b/spec/Overview.html index 4471251..fcd37af 100644 --- a/spec/Overview.html +++ b/spec/Overview.html @@ -5529,6 +5529,9 @@
    Verify Digest
    false otherwise.

    +
  • +

    Return |result|.

    +
  • From f861898adceee085479c95076b56e8313bb6bbba Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Mon, 23 Mar 2026 12:55:21 +0100 Subject: [PATCH 6/7] fixup! add signDigest and verifyDigest operations --- spec/Overview.html | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/spec/Overview.html b/spec/Overview.html index fcd37af..38bee3c 100644 --- a/spec/Overview.html +++ b/spec/Overview.html @@ -11209,6 +11209,13 @@
    Verify
    Sign Digest
    +

    + Ed25519ph, as defined in [[RFC8032]] Section 5.1, + uses SHA-512 as the pre-hash function PH. The |digest| + passed to this operation is therefore expected to be + a SHA-512 hash of the original message, which is 64 bytes + in length. +

    1. @@ -11262,6 +11269,13 @@
      Sign Digest
      Verify Digest
      +

      + Ed25519ph, as defined in [[RFC8032]] Section 5.1, + uses SHA-512 as the pre-hash function PH. The |digest| + passed to this operation is therefore expected to be + a SHA-512 hash of the original message, which is 64 bytes + in length. +

      1. From ddba849439794207847d4dd94f383ab877224af9 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Mon, 23 Mar 2026 16:08:59 +0100 Subject: [PATCH 7/7] fixup! add signDigest and verifyDigest operations --- spec/Overview.html | 179 +-------------------------------------------- 1 file changed, 2 insertions(+), 177 deletions(-) diff --git a/spec/Overview.html b/spec/Overview.html index 38bee3c..29ecfc9 100644 --- a/spec/Overview.html +++ b/spec/Overview.html @@ -3876,8 +3876,8 @@

        Algorithm Overview

        ✔ ✔ - ✔ - ✔ + + ✔ @@ -11069,16 +11069,6 @@

        Registration

        None boolean - - signDigest - {{ContextParams}} - [= byte sequence =] - - - verifyDigest - {{ContextParams}} - boolean - generateKey None @@ -11097,33 +11087,8 @@

        Registration

      -
      -

      ContextParams dictionary

      -
      -dictionary ContextParams : Algorithm {
      -  BufferSource context;
      -};
      -          
      -

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

      -
      -

      Operations

      -

      - The sign and - verify operations - use Ed25519 (pure EdDSA), while the - sign digest and - verify digest - operations use Ed25519ph (prehashed EdDSA). These produce - cryptographically distinct signatures. A signature produced with - sign cannot be verified - with verify digest, - and a signature produced with - sign digest - cannot be verified with - verify. -

      Sign
      @@ -11207,146 +11172,6 @@
      Verify
    -
    -
    Sign Digest
    -

    - Ed25519ph, as defined in [[RFC8032]] Section 5.1, - uses SHA-512 as the pre-hash function PH. The |digest| - passed to this operation is therefore expected to be - a SHA-512 hash of the original message, which is 64 bytes - in length. -

    - -
      -
    1. -

      - If the {{CryptoKey/[[type]]}} internal slot of - |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. -

      -
    2. -
    3. -

      - If the [= byte sequence/length =] of |digest| is not 64, - then [= exception/throw =] an {{OperationError}}. -

      -
    4. -
    5. -

      - Let |context| be the {{ContextParams/context}} member of - |normalizedAlgorithm|, or the empty octet string if - the {{ContextParams/context}} member of - |normalizedAlgorithm| is not present. -

      -
    6. -
    7. -

      - If the [= byte sequence/length =] of |context| is greater - than 255 bytes, - then [= exception/throw =] an {{OperationError}}. -

      -
    8. -
    9. -

      - Let |result| be the result of performing the Ed25519ph - signing process, as specified in [[RFC8032]], - Section 5.1, with |digest| as PH(M), - phflag set to 1, and |context| as the context C, - using the Ed25519 private key associated with |key|. -

      -

      - Some implementations may (wish to) generate randomized signatures - as per draft-irtf-cfrg-det-sigs-with-noise - instead of deterministic signatures as per [[RFC8032]]. -

      -
    10. -
    11. -

      - Return |result|. -

      -
    12. -
    -
    - -
    -
    Verify Digest
    -

    - Ed25519ph, as defined in [[RFC8032]] Section 5.1, - uses SHA-512 as the pre-hash function PH. The |digest| - passed to this operation is therefore expected to be - a SHA-512 hash of the original message, which is 64 bytes - in length. -

    - -
      -
    1. -

      - If the {{CryptoKey/[[type]]}} internal slot of - |key| is not {{KeyType/"public"}}, then [= exception/throw =] an {{InvalidAccessError}}. -

      -
    2. -
    3. -

      - If the [= byte sequence/length =] of |digest| is not 64, - then return false. -

      -
    4. -
    5. -

      - If the key data of |key| represents an invalid point or a small-order element - on the Elliptic Curve of Ed25519, return `false`. -

      -

      - Not all implementations perform this check. -

      -
    6. -
    7. -

      - If the point R, encoded in the first half of |signature|, - represents an invalid point or a small-order element - on the Elliptic Curve of Ed25519, return `false`. -

      -

      - Not all implementations perform this check. -

      -
    8. -
    9. -

      - Let |context| be the {{ContextParams/context}} member of - |normalizedAlgorithm|, or the empty octet string if - the {{ContextParams/context}} member of - |normalizedAlgorithm| is not present. -

      -
    10. -
    11. -

      - If the [= byte sequence/length =] of |context| is greater - than 255 bytes, - then [= exception/throw =] an {{OperationError}}. -

      -
    12. -
    13. -

      - Perform the Ed25519ph verification steps, as specified in [[RFC8032]], - Section 5.1, using the cofactorless (unbatched) equation, - `[S]B = R + [k]A'`, on the |signature|, with |digest| as PH(M), - phflag set to 1, and |context| as the context C, - using the Ed25519 public key associated with |key|. -

      -
    14. -
    15. -

      - Let |result| be a boolean with the value `true` if the signature is valid - and the value `false` otherwise. -

      -
    16. -
    17. -

      - Return |result|. -

      -
    18. -
    -
    -
    Generate Key