diff --git a/README.md b/README.md index 51ebe2b..3b1e71d 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ # Secure Curves in the Web Cryptography API -This repository contains a proposal to add support for [Curve25519 and -Curve448](https://tools.ietf.org/html/rfc7748) in the Web Cryptography API. +This repository contains a proposal to add support for [Curve448](https://tools.ietf.org/html/rfc7748) in the Web Cryptography API. There is an [explainer](./explainer.md) and a [draft specification](https://WICG.github.io/webcrypto-secure-curves/). @@ -9,3 +8,5 @@ See the [implementation status](https://github.com/WICG/webcrypto-secure-curves/ Acknowledgement: this proposal was based on [a previous proposal by Qingsi Wang to include Curve25519 in WebCrypto](https://github.com/tQsW/webcrypto-curve25519). + +Note: Curve25519 has already been added to [Web Cryptography](https://w3c.github.io/webcrypto/) diff --git a/index.html b/index.html index 8e1a5f7..725530b 100644 --- a/index.html +++ b/index.html @@ -35,8 +35,8 @@

- This specification defines a number of algorithms for the [[webcrypto | Web Cryptography API]], - namely X25519 and X448 [[RFC7748]], and Ed25519 and Ed448 [[RFC8032]]. + This specification defines a number of algorithms for the [[[webcrypto | Web Cryptography API]]], + namely X448 [[RFC7748]] and Ed448 [[RFC8032]].

@@ -55,882 +55,23 @@

Introduction

the [[webcrypto | Web Cryptography API]], namely key agreement using X25519 and X448 [[RFC7748]], and signing and verifying using Ed25519 and Ed448 [[RFC8032]].

+

+ Note: This introduction does not reflect the fact that Curve25519 has already been + added to [[[webcrypto | Web Cryptography API]]]. +

Specification Conventions

- This specification follows the conventions + This specification follows the conventions laid out in Section 18.3 of [[webcrypto]]. 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 + document, and must perform the steps to define an algorithm specified in section 18.4.3 of [[webcrypto]] for each of the supported operations.

-
-

X25519

-
-

Description

-

- The "`X25519`" algorithm identifier is used to perform - key agreement using the X25519 algorithm specified in - [[RFC7748]]. -

-
-
-

Registration

-

- The recognized algorithm name - for this algorithm is "`X25519`". -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OperationParametersResult
deriveBits{{EcdhKeyDeriveParams}}octet string
generateKeyNone{{CryptoKeyPair}}
importKeyNone{{CryptoKey}}
exportKeyNoneobject
-
- -
-

Operations

-
-
Derive Bits
-
-
    -
  1. -

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

    -
  2. -
  3. -

    - Let |publicKey| be the - {{EcdhKeyDeriveParams/public}} member of - |normalizedAlgorithm|. -

    -
  4. -
  5. -

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

    -
  6. -
  7. -

    - If the {{KeyAlgorithm/name}} attribute of - the [[\algorithm]] internal slot of - |publicKey| is not equal to the {{KeyAlgorithm/name}} property of the [[\algorithm]] internal slot of - |key|, then [= exception/throw =] an {{InvalidAccessError}}. -

    -
  8. -
  9. -

    - Let |secret| be the result of performing the X25519 function specified in - [[RFC7748]] Section 5 with |key| as the X25519 private key |k| - and the X25519 public key represented by the [[\handle]] - internal slot of |publicKey| as the X25519 public key |u|. -

    -
  10. -
  11. -

    - If |secret| is the all-zero value, - then [= exception/throw =] a {{OperationError}}. - This check must be performed in constant-time, as per [[RFC7748]] Section 6.1. -

    -
  12. -
  13. -
    -
    If |length| is null:
    -
    Return |secret|
    -
    Otherwise:
    -
    -
    -
    - If the length of |secret| in bits is less than - |length|: -
    -
    - [= exception/throw =] an - {{OperationError}}. -
    -
    Otherwise:
    -
    - Return an octet string containing the first |length| bits of |secret|. -
    -
    -
    -
    -
  14. -
-
-
Generate Key
-
-
    -
  1. -

    - If |usages| contains an entry which is not - "`deriveKey`" or "`deriveBits`" - then [= exception/throw =] a - {{SyntaxError}}. -

    -
  2. -
  3. -

    - Generate an X25519 key pair, with the private key being 32 random bytes, - and the public key being `X25519(a, 9)`, - as defined in [[RFC7748]], section 6.1. -

    -
  4. -
  5. -

    - Let |algorithm| be a new {{KeyAlgorithm}} object. -

    -
  6. -
  7. -

    - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`X25519`". -

    -
  8. -
  9. -

    - Let |publicKey| be a new {{CryptoKey}} associated with the - [= relevant global object =] - of `this` [[HTML]], and - representing the public key of the generated key pair. -

    -
  10. -
  11. -

    - Set the [[\type]] internal slot of - |publicKey| to "`public`" -

    -
  12. -
  13. -

    - Set the [[\algorithm]] internal - slot of |publicKey| to |algorithm|. -

    -
  14. -
  15. -

    - Set the [[\extractable]] internal - slot of |publicKey| to true. -

    -
  16. -
  17. -

    - Set the [[\usages]] internal slot of - |publicKey| to be the empty list. -

    -
  18. -
  19. -

    - Let |privateKey| be a new {{CryptoKey}} associated with the - [= relevant global object =] - of `this` [[HTML]], and - representing the private key of the generated key pair. -

    -
  20. -
  21. -

    - Set the [[\type]] internal slot of - |privateKey| to {{KeyType/"private"}} -

    -
  22. -
  23. -

    - Set the [[\algorithm]] internal - slot of |privateKey| to |algorithm|. -

    -
  24. -
  25. -

    - Set the [[\extractable]] internal - slot of |privateKey| to |extractable|. -

    -
  26. -
  27. -

    - Set the [[\usages]] internal slot of - |privateKey| to be the - usage intersection of - |usages| and `[ "deriveKey", "deriveBits" ]`. -

    -
  28. -
  29. -

    - Let |result| be a new {{CryptoKeyPair}} - dictionary. -

    -
  30. -
  31. -

    - Set the {{CryptoKeyPair/publicKey}} attribute - of |result| to be |publicKey|. -

    -
  32. -
  33. -

    - Set the {{CryptoKeyPair/privateKey}} attribute - of |result| to be |privateKey|. -

    -
  34. -
  35. -

    - Return the result of converting |result| to an ECMAScript Object, as - defined by [[WebIDL]]. -

    -
  36. -
-
- -
Import Key
-
-
    -
  1. -

    Let |keyData| be the key data to be imported.

    -
  2. -
  3. -
    -
    If |format| is {{KeyFormat/"spki"}}:
    -
    -
      -
    1. -

      - If |usages| is not empty - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -

      - Let |spki| be the result of running the - parse a subjectPublicKeyInfo - algorithm over |keyData|. -

      -
    4. -
    5. -

      - If an error occurred while parsing, - then [= exception/throw =] a - {{DataError}}. -

      -
    6. -
    7. -

      - If the `algorithm` object identifier field of the - `algorithm` AlgorithmIdentifier field of |spki| is - not equal to the `id-X25519` - object identifier defined in [[RFC8410]], - then [= exception/throw =] a - {{DataError}}. -

      -
    8. -
    9. -

      - If the `parameters` field of the `algorithm` - AlgorithmIdentifier field of |spki| is present, - then [= exception/throw =] a - {{DataError}}. -

      -
    10. -
    11. -

      - Let |publicKey| be the X25519 public key identified by - the `subjectPublicKey` field of |spki|. -

      -
    12. -
    13. -

      - Let |key| be a new {{CryptoKey}} associated with the - [= relevant global object =] - of `this` [[HTML]], and - that represents |publicKey|. -

      -
    14. -
    15. -

      - Set the [[\type]] internal slot - of |key| to "`public`" -

      -
    16. -
    17. -

      - Let |algorithm| be a new {{KeyAlgorithm}}. -

      -
    18. -
    19. -

      - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`X25519`". -

      -
    20. -
    21. -

      - Set the [[\algorithm]] - internal slot of |key| to |algorithm|. -

      -
    22. -
    -
    -
    If |format| is {{KeyFormat/"pkcs8"}}:
    -
    -
      -
    1. -

      - If |usages| contains an entry which is not - "`deriveKey`" or "`deriveBits`" - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -

      - Let |privateKeyInfo| be the result of running the - parse a privateKeyInfo - algorithm over |keyData|. -

      -
    4. -
    5. -

      - If an error occurs while parsing, - then [= exception/throw =] a - {{DataError}}. -

      -
    6. -
    7. -

      - If the `algorithm` object identifier field of the - `privateKeyAlgorithm` PrivateKeyAlgorithm field of - |privateKeyInfo| is not equal to the - `id-X25519` object identifier defined in [[RFC8410]], - then [= exception/throw =] a - {{DataError}}. -

      -
    8. -
    9. -

      - If the `parameters` field of the - `privateKeyAlgorithm` PrivateKeyAlgorithmIdentifier field - of |privateKeyInfo| is present, - then [= exception/throw =] a - {{DataError}}. -

      -
    10. -
    11. -

      - Let |curvePrivateKey| be the result of performing the parse an ASN.1 structure - algorithm, with |data| as the `privateKey` field - of |privateKeyInfo|, |structure| as the ASN.1 - `CurvePrivateKey` structure specified in Section 7 of [[RFC8410]], and |exactData| set to true. -

      -
    12. -
    13. -

      - If an error occurred while parsing, - then [= exception/throw =] a - {{DataError}}. -

      -
    14. -
    15. -

      - Let |key| be a new {{CryptoKey}} associated with the - [= relevant global object =] - of `this` [[HTML]], and - that represents the X25519 private key identified by |curvePrivateKey|. -

      -
    16. -
    17. -

      - Set the [[\type]] internal slot - of |key| to {{KeyType/"private"}} -

      -
    18. -
    19. -

      - Let |algorithm| be a new {{KeyAlgorithm}}. -

      -
    20. -
    21. -

      - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`X25519`". -

      -
    22. -
    23. -

      - Set the [[\algorithm]] - internal slot of |key| to |algorithm|. -

      -
    24. -
    -
    -
    If |format| is {{KeyFormat/"jwk"}}:
    -
    -
      -
    1. -
      -
      If |keyData| is a {{JsonWebKey}} dictionary:
      -

      Let |jwk| equal |keyData|.

      -
      Otherwise:
      -

      [= exception/Throw =] a {{DataError}}.

      -
      -
    2. -
    3. -

      - If the {{JsonWebKey/d}} field is present and if |usages| - contains an entry which is not - "`deriveKey`" or "`deriveBits`" - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    4. -
    5. -

      - If the {{JsonWebKey/d}} field is not present and if |usages| is not - empty - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    6. -
    7. -

      - If the {{JsonWebKey/kty}} field of |jwk| is not - "`OKP`", - then [= exception/throw =] a - {{DataError}}. -

      -
    8. -
    9. -

      - If the {{JsonWebKey/crv}} field of |jwk| is not - "`X25519`", - then [= exception/throw =] a - {{DataError}}. -

      -
    10. -
    11. -

      - If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present - and is not equal to "`enc`" then [= exception/throw =] a - {{DataError}}. -

      -
    12. -
    13. -

      - If the {{JsonWebKey/key_ops}} field of |jwk| is present, and - is invalid according to the requirements of JSON Web - Key [[JWK]], or it does not contain all of the specified |usages| - values, - then [= exception/throw =] a - {{DataError}}. -

      -
    14. -
    15. -

      - If the {{JsonWebKey/ext}} field of |jwk| is present and - has the value false and |extractable| is true, - then [= exception/throw =] a - {{DataError}}. -

      -
    16. -
    17. -
      -
      If the {{JsonWebKey/d}} field is present:
      -
      -
        -
      1. -

        - If |jwk| does not meet the requirements of - the JWK private key format described in Section 2 - of [[RFC8037]], then [= exception/throw =] a {{DataError}}. -

        -
      2. -
      3. -

        - Let |key| be a new {{CryptoKey}} object that represents the - X25519 private key identified by interpreting - |jwk| according to Section 2 of [[RFC8037]]. -

        -
      4. -
      5. -

        - Set the [[\type]] - internal slot of |Key| to {{KeyType/"private"}}. -

        -
      6. -
      -
      -
      Otherwise:
      -
      -
        -
      1. -

        - If |jwk| does not meet the requirements of - the JWK public key format described in Section 2 - of [[RFC8037]], then [= exception/throw =] a {{DataError}}. -

        -
      2. -
      3. -

        - Let |key| be a new {{CryptoKey}} object that represents the - X25519 public key identified by interpreting - |jwk| according to Section 2 of [[RFC8037]]. -

        -
      4. -
      5. -

        - Set the [[\type]] - internal slot of |Key| to {{KeyType/"public"}}. -

        -
      6. -
      -
      -
      -
    18. -
    19. -

      - Let |algorithm| be a new instance of a {{KeyAlgorithm}} object. -

      -
    20. -
    21. -

      - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`X25519`". -

      -
    22. -
    23. -

      - Set the [[\algorithm]] - internal slot of |key| to |algorithm|. -

      -
    24. -
    -
    -
    If |format| is {{KeyFormat/"raw"}}:
    -
    -
      -
    1. -

      - If |usages| is not empty - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -

      - Let |data| be |keyData|. -

      -
    4. -
    5. -

      - If the length in bits of |data| is not 256 then [= exception/throw =] a {{DataError}}. -

      -
    6. -
    7. -

      - Let |algorithm| be a new {{KeyAlgorithm}} object. -

      -
    8. -
    9. -

      - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`X25519`". -

      -
    10. -
    11. -

      - Let |key| be a new {{CryptoKey}} associated with the - [= relevant global object =] - of `this` [[HTML]], and that represents |data|. -

      -
    12. -
    13. -

      - Set the [[\type]] internal slot - of |key| to "`public`" -

      -
    14. -
    15. -

      - Set the [[\algorithm]] - internal slot of |key| to |algorithm|. -

      -
    16. -
    -
    -
    Otherwise:
    -
    -

    - [= exception/throw =] a - {{NotSupportedError}}. -

    -
    -
    -
  4. -
  5. -

    - Return |key| -

    -
  6. -
-
- -
Export Key
-
-
    -
  1. -

    - Let |key| be the {{CryptoKey}} to be - exported. -

    -
  2. -
  3. -

    - If the underlying cryptographic key material represented by the [[\handle]] internal slot of |key| - cannot be accessed, then [= exception/throw =] an {{OperationError}}. -

    -
  4. -
  5. -
    -
    If |format| is {{KeyFormat/"spki"}}:
    -
    -
      -
    1. -

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

      -
    2. -
    3. -

      - Let |data| be an instance of the `subjectPublicKeyInfo` - ASN.1 structure defined in [[RFC5280]] - with the following properties: -

      -
        -
      • -

        - Set the |algorithm| field to an - `AlgorithmIdentifier` ASN.1 type with the following - properties: -

        -
          -
        • -

          - Set the |algorithm| object identifier to the - `id-X25519` OID defined in [[RFC8410]]. -

          -
        • -
        -
      • -
      • -

        - Set the |subjectPublicKey| field to |keyData|. -

        -
      • -
      -
    4. -
    5. -

      - Let |result| be a new {{ArrayBuffer}} associated with the - [= relevant global object =] - of `this` [[HTML]], and containing - |data|. -

      -
    6. -
    -
    -
    If |format| is {{KeyFormat/"pkcs8"}}:
    -
    -
      -
    1. -

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

      -
    2. -
    3. -

      - Let |data| be an instance of the `privateKeyInfo` - ASN.1 structure defined in [[RFC5208]] - with the following properties: -

      -
        -
      • -

        - Set the |version| field to `0`. -

        -
      • -
      • -

        - Set the |privateKeyAlgorithm| field to a - `PrivateKeyAlgorithmIdentifier` ASN.1 type with the - following properties: -

        -
          -
        • -

          - Set the |algorithm| object identifier to the - `id-X25519` OID defined in [[RFC8410]]. -

          -
        • -
        -
      • -
      • -

        - Set the |privateKey| field to the result of DER-encoding - a `CurvePrivateKey` ASN.1 type, as defined in Section 7 of [[RFC8410]], that represents the - X25519 private key represented by the [[\handle]] internal slot of - |key| -

        -
      • -
      -
    4. -
    5. -

      - Let |result| be a new {{ArrayBuffer}} associated with the - [= relevant global object =] - of `this` [[HTML]], and containing - |data|. -

      -
    6. -
    -
    -
    If |format| is {{KeyFormat/"jwk"}}:
    -
    -
      -
    1. -

      - Let |jwk| be a new {{JsonWebKey}} - dictionary. -

      -
    2. -
    3. -

      - Set the `kty` attribute of |jwk| to - "`OKP`". -

      -
    4. -
    5. -

      - Set the `crv` attribute of |jwk| to - "`X25519`". -

      -
    6. -
    7. -

      - Set the {{JsonWebKey/x}} attribute of |jwk| according to the - definition in Section 2 of [[RFC8037]]. -

      -
    8. -
    9. -
      -
      - If the [[\type]] internal slot - of |key| is {{KeyType/"private"}} -
      -
      - Set the {{JsonWebKey/d}} attribute of |jwk| according to the - definition in Section 2 of [[RFC8037]]. -
      -
      -
    10. -
    11. -

      - Set the `key_ops` attribute of |jwk| to the {{CryptoKey/usages}} attribute of |key|. -

      -
    12. -
    13. -

      - Set the `ext` attribute of |jwk| to the [[\extractable]] internal slot - of |key|. -

      -
    14. -
    15. -

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

      -
    16. -
    -
    -
    - If |format| is {{KeyFormat/"raw"}}: -
    -
    -
      -
    1. -

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

      -
    2. -
    3. -

      - Let |data| be an octet string representing the X25519 - public key represented by the [[\handle]] internal slot of - |key|. -

      -
    4. -
    5. -

      - Let |result| be a new {{ArrayBuffer}} associated with the - [= relevant global object =] - of `this` [[HTML]], and containing - |data|. -

      -
    6. -
    -
    -
    Otherwise:
    -
    -

    - [= exception/throw =] a - {{NotSupportedError}}. -

    -
    -
    -
  6. -
  7. -

    - Return |result|. -

    -
  8. -
-
-
-
-
-

X448

@@ -944,22 +85,22 @@

Description

Registration

- The recognized algorithm name + The recognized algorithm name for this algorithm is "`X448`".

- - - + + + - + @@ -982,1706 +123,814 @@

Registration

Operations

-
-
Derive Bits
-
-
    -
  1. -

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

    -
  2. -
  3. -

    - Let |publicKey| be the - {{EcdhKeyDeriveParams/public}} member of - |normalizedAlgorithm|. -

    -
  4. -
  5. -

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

    -
  6. -
  7. -

    - If the {{KeyAlgorithm/name}} attribute of - the [[\algorithm]] internal slot of - |publicKey| is not equal to the {{KeyAlgorithm/name}} property of the [[\algorithm]] internal slot of - |key|, then [= exception/throw =] an {{InvalidAccessError}}. -

    -
  8. -
  9. -

    - Let |secret| be the result of performing the X448 function specified in - [[RFC7748]] Section 5 with |key| as the X448 private key |k| - and the X448 public key represented by the [[\handle]] - internal slot of |publicKey| as the X448 public key |u|. -

    -
  10. -
  11. -

    - If |secret| is the all-zero value, - then [= exception/throw =] a {{OperationError}}. - This check must be performed in constant-time, as per [[RFC7748]] Section 6.2. -

    -
  12. -
  13. -
    -
    If |length| is null:
    -
    Return |secret|
    -
    Otherwise:
    -
    -
    -
    - If the length of |secret| in bits is less than - |length|: -
    -
    - [= exception/throw =] an - {{OperationError}}. -
    -
    Otherwise:
    -
    - Return an octet string containing the first |length| bits of |secret|. -
    -
    -
    -
    -
  14. -
-
-
Generate Key
-
-
    -
  1. -

    - If |usages| contains an entry which is not - "`deriveKey`" or "`deriveBits`" - then [= exception/throw =] a - {{SyntaxError}}. -

    -
  2. -
  3. -

    - Generate an X448 key pair, with the private key being 56 random bytes, - and the public key being `X448(a, 5)`, - as defined in [[RFC7748]], section 6.2. -

    -
  4. -
  5. -

    - Let |algorithm| be a new {{KeyAlgorithm}} object. -

    -
  6. -
  7. -

    - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`X448`". -

    -
  8. -
  9. -

    - Let |publicKey| be a new {{CryptoKey}} associated with the - [= relevant global object =] - of `this` [[HTML]], and - representing the public key of the generated key pair. -

    -
  10. -
  11. -

    - Set the [[\type]] internal slot of - |publicKey| to "`public`" -

    -
  12. -
  13. -

    - Set the [[\algorithm]] internal - slot of |publicKey| to |algorithm|. -

    -
  14. -
  15. -

    - Set the [[\extractable]] internal - slot of |publicKey| to true. -

    -
  16. -
  17. -

    - Set the [[\usages]] internal slot of - |publicKey| to be the empty list. -

    -
  18. -
  19. -

    - Let |privateKey| be a new {{CryptoKey}} associated with the - [= relevant global object =] - of `this` [[HTML]], and - representing the private key of the generated key pair. -

    -
  20. -
  21. -

    - Set the [[\type]] internal slot of - |privateKey| to {{KeyType/"private"}} -

    -
  22. -
  23. -

    - Set the [[\algorithm]] internal - slot of |privateKey| to |algorithm|. -

    -
  24. -
  25. -

    - Set the [[\extractable]] internal - slot of |privateKey| to |extractable|. -

    -
  26. -
  27. -

    - Set the [[\usages]] internal slot of - |privateKey| to be the - usage intersection of - |usages| and `[ "deriveKey", "deriveBits" ]`. -

    -
  28. -
  29. -

    - Let |result| be a new {{CryptoKeyPair}} - dictionary. -

    -
  30. -
  31. -

    - Set the {{CryptoKeyPair/publicKey}} attribute - of |result| to be |publicKey|. -

    -
  32. -
  33. -

    - Set the {{CryptoKeyPair/privateKey}} attribute - of |result| to be |privateKey|. -

    -
  34. -
  35. -

    - Return the result of converting |result| to an ECMAScript Object, as - defined by [[WebIDL]]. -

    -
  36. -
-
- -
Import Key
-
-
    -
  1. -

    Let |keyData| be the key data to be imported.

    -
  2. -
  3. -
    -
    If |format| is {{KeyFormat/"spki"}}:
    -
    -
      -
    1. -

      - If |usages| is not empty - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -

      - Let |spki| be the result of running the - parse a subjectPublicKeyInfo - algorithm over |keyData|. -

      -
    4. -
    5. -

      - If an error occurred while parsing, - then [= exception/throw =] a - {{DataError}}. -

      -
    6. -
    7. -

      - If the `algorithm` object identifier field of the - `algorithm` AlgorithmIdentifier field of |spki| is - not equal to the `id-X448` - object identifier defined in [[RFC8410]], - then [= exception/throw =] a - {{DataError}}. -

      -
    8. -
    9. -

      - If the `parameters` field of the `algorithm` - AlgorithmIdentifier field of |spki| is present, - then [= exception/throw =] a - {{DataError}}. -

      -
    10. -
    11. -

      - Let |publicKey| be the X448 public key identified by - the `subjectPublicKey` field of |spki|. -

      -
    12. -
    13. -

      - Let |key| be a new {{CryptoKey}} associated with the - [= relevant global object =] - of `this` [[HTML]], and - that represents |publicKey|. -

      -
    14. -
    15. -

      - Set the [[\type]] internal slot - of |key| to "`public`" -

      -
    16. -
    17. -

      - Let |algorithm| be a new {{KeyAlgorithm}}. -

      -
    18. -
    19. -

      - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`X448`". -

      -
    20. -
    21. -

      - Set the [[\algorithm]] - internal slot of |key| to |algorithm|. -

      -
    22. -
    -
    -
    If |format| is {{KeyFormat/"pkcs8"}}:
    -
    -
      -
    1. -

      - If |usages| contains an entry which is not - "`deriveKey`" or "`deriveBits`" - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -

      - Let |privateKeyInfo| be the result of running the - parse a privateKeyInfo - algorithm over |keyData|. -

      -
    4. -
    5. -

      - If an error occurs while parsing, - then [= exception/throw =] a - {{DataError}}. -

      -
    6. -
    7. -

      - If the `algorithm` object identifier field of the - `privateKeyAlgorithm` PrivateKeyAlgorithm field of - |privateKeyInfo| is not equal to the - `id-X448` object identifier defined in [[RFC8410]], - then [= exception/throw =] a - {{DataError}}. -

      -
    8. -
    9. -

      - If the `parameters` field of the - `privateKeyAlgorithm` PrivateKeyAlgorithmIdentifier field - of |privateKeyInfo| is present, - then [= exception/throw =] a - {{DataError}}. -

      -
    10. -
    11. -

      - Let |curvePrivateKey| be the result of performing the parse an ASN.1 structure - algorithm, with |data| as the `privateKey` field - of |privateKeyInfo|, |structure| as the ASN.1 - `CurvePrivateKey` structure specified in Section 7 of [[RFC8410]], and |exactData| set to true. -

      -
    12. -
    13. -

      - If an error occurred while parsing, - then [= exception/throw =] a - {{DataError}}. -

      -
    14. -
    15. -

      - Let |key| be a new {{CryptoKey}} associated with the - [= relevant global object =] - of `this` [[HTML]], and - that represents the X448 private key identified by |curvePrivateKey|. -

      -
    16. -
    17. -

      - Set the [[\type]] internal slot - of |key| to {{KeyType/"private"}} -

      -
    18. -
    19. -

      - Let |algorithm| be a new {{KeyAlgorithm}}. -

      -
    20. -
    21. -

      - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`X448`". -

      -
    22. -
    23. -

      - Set the [[\algorithm]] - internal slot of |key| to |algorithm|. -

      -
    24. -
    -
    -
    If |format| is {{KeyFormat/"jwk"}}:
    -
    -
      -
    1. -
      -
      If |keyData| is a {{JsonWebKey}} dictionary:
      -

      Let |jwk| equal |keyData|.

      -
      Otherwise:
      -

      [= exception/Throw =] a {{DataError}}.

      -
      -
    2. -
    3. -

      - If the {{JsonWebKey/d}} field is present and if |usages| - contains an entry which is not - "`deriveKey`" or "`deriveBits`" - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    4. -
    5. -

      - If the {{JsonWebKey/d}} field is not present and if |usages| is not - empty - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    6. -
    7. -

      - If the {{JsonWebKey/kty}} field of |jwk| is not - "`OKP`", - then [= exception/throw =] a - {{DataError}}. -

      -
    8. -
    9. -

      - If the {{JsonWebKey/crv}} field of |jwk| is not - "`X448`", - then [= exception/throw =] a - {{DataError}}. -

      -
    10. -
    11. -

      - If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present - and is not equal to "`enc`" then [= exception/throw =] a - {{DataError}}. -

      -
    12. -
    13. -

      - If the {{JsonWebKey/key_ops}} field of |jwk| is present, and - is invalid according to the requirements of JSON Web - Key [[JWK]], or it does not contain all of the specified |usages| - values, - then [= exception/throw =] a - {{DataError}}. -

      -
    14. -
    15. -

      - If the {{JsonWebKey/ext}} field of |jwk| is present and - has the value false and |extractable| is true, - then [= exception/throw =] a - {{DataError}}. -

      -
    16. -
    17. -
      -
      If the {{JsonWebKey/d}} field is present:
      -
      -
        -
      1. -

        - If |jwk| does not meet the requirements of - the JWK private key format described in Section 2 - of [[RFC8037]], then [= exception/throw =] a {{DataError}}. -

        -
      2. -
      3. -

        - Let |key| be a new {{CryptoKey}} object that represents the - X448 private key identified by interpreting - |jwk| according to Section 2 of [[RFC8037]]. -

        -
      4. -
      5. -

        - Set the [[\type]] - internal slot of |Key| to {{KeyType/"private"}}. -

        -
      6. -
      -
      -
      Otherwise:
      -
      -
        -
      1. -

        - If |jwk| does not meet the requirements of - the JWK public key format described in Section 2 - of [[RFC8037]], then [= exception/throw =] a {{DataError}}. -

        -
      2. -
      3. -

        - Let |key| be a new {{CryptoKey}} object that represents the - X448 public key identified by interpreting - |jwk| according to Section 2 of [[RFC8037]]. -

        -
      4. -
      5. -

        - Set the [[\type]] - internal slot of |Key| to {{KeyType/"public"}}. -

        -
      6. -
      -
      -
      -
    18. -
    19. -

      - Let |algorithm| be a new instance of a {{KeyAlgorithm}} object. -

      -
    20. -
    21. -

      - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`X448`". -

      -
    22. -
    23. -

      - Set the [[\algorithm]] - internal slot of |key| to |algorithm|. -

      -
    24. -
    -
    -
    If |format| is {{KeyFormat/"raw"}}:
    -
    -
      -
    1. -

      - If |usages| is not empty - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -

      - Let |data| be |keyData|. -

      -
    4. -
    5. -

      - If the length in bits of |data| is not 448 then [= exception/throw =] a {{DataError}}. -

      -
    6. -
    7. -

      - Let |algorithm| be a new {{KeyAlgorithm}} object. -

      -
    8. -
    9. -

      - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`X448`". -

      -
    10. -
    11. -

      - Let |key| be a new {{CryptoKey}} associated with the - [= relevant global object =] - of `this` [[HTML]], and that represents |data|. -

      -
    12. -
    13. -

      - Set the [[\type]] internal slot - of |key| to "`public`" -

      -
    14. -
    15. -

      - Set the [[\algorithm]] - internal slot of |key| to |algorithm|. -

      -
    16. -
    -
    -
    Otherwise:
    -
    -

    - [= exception/throw =] a - {{NotSupportedError}}. -

    -
    -
    -
  4. -
  5. -

    - Return |key| -

    -
  6. -
-
- -
Export Key
-
-
    -
  1. -

    - Let |key| be the {{CryptoKey}} to be - exported. -

    -
  2. -
  3. -

    - If the underlying cryptographic key material represented by the [[\handle]] internal slot of |key| - cannot be accessed, then [= exception/throw =] an {{OperationError}}. -

    -
  4. -
  5. -
    -
    If |format| is {{KeyFormat/"spki"}}:
    -
    -
      -
    1. -

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

      -
    2. -
    3. -

      - Let |data| be an instance of the `subjectPublicKeyInfo` - ASN.1 structure defined in [[RFC5280]] - with the following properties: -

      -
        -
      • -

        - Set the |algorithm| field to an - `AlgorithmIdentifier` ASN.1 type with the following - properties: -

        -
          -
        • -

          - Set the |algorithm| object identifier to the - `id-X448` OID defined in [[RFC8410]]. -

          -
        • -
        -
      • -
      • -

        - Set the |subjectPublicKey| field to |keyData|. -

        -
      • -
      -
    4. -
    5. -

      - Let |result| be a new {{ArrayBuffer}} associated with the - [= relevant global object =] - of `this` [[HTML]], and containing - |data|. -

      -
    6. -
    -
    -
    If |format| is {{KeyFormat/"pkcs8"}}:
    -
    -
      -
    1. -

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

      -
    2. -
    3. -

      - Let |data| be an instance of the `privateKeyInfo` - ASN.1 structure defined in [[RFC5208]] - with the following properties: -

      -
        -
      • -

        - Set the |version| field to `0`. -

        -
      • -
      • -

        - Set the |privateKeyAlgorithm| field to a - `PrivateKeyAlgorithmIdentifier` ASN.1 type with the - following properties: -

        -
          -
        • -

          - Set the |algorithm| object identifier to the - `id-X448` OID defined in [[RFC8410]]. -

          -
        • -
        -
      • -
      • -

        - Set the |privateKey| field to the result of DER-encoding - a `CurvePrivateKey` ASN.1 type, as defined in Section 7 of [[RFC8410]], that represents the - X448 private key represented by the [[\handle]] internal slot of - |key| -

        -
      • -
      -
    4. -
    5. -

      - Let |result| be a new {{ArrayBuffer}} associated with the - [= relevant global object =] - of `this` [[HTML]], and containing - |data|. -

      -
    6. -
    -
    -
    If |format| is {{KeyFormat/"jwk"}}:
    -
    -
      -
    1. -

      - Let |jwk| be a new {{JsonWebKey}} - dictionary. -

      -
    2. -
    3. -

      - Set the `kty` attribute of |jwk| to - "`OKP`". -

      -
    4. -
    5. -

      - Set the `crv` attribute of |jwk| to - "`X448`". -

      -
    6. -
    7. -

      - Set the {{JsonWebKey/x}} attribute of |jwk| according to the - definition in Section 2 of [[RFC8037]]. -

      -
    8. -
    9. -
      -
      - If the [[\type]] internal slot - of |key| is {{KeyType/"private"}} -
      -
      - Set the {{JsonWebKey/d}} attribute of |jwk| according to the - definition in Section 2 of [[RFC8037]]. -
      -
      -
    10. -
    11. -

      - Set the `key_ops` attribute of |jwk| to the {{CryptoKey/usages}} attribute of |key|. -

      -
    12. -
    13. -

      - Set the `ext` attribute of |jwk| to the [[\extractable]] internal slot - of |key|. -

      -
    14. -
    15. -

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

      -
    16. -
    -
    -
    - If |format| is {{KeyFormat/"raw"}}: -
    -
    -
      -
    1. -

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

      -
    2. -
    3. -

      - Let |data| be an octet string representing the X448 - public key represented by the [[\handle]] internal slot of - |key|. -

      -
    4. -
    5. -

      - Let |result| be a new {{ArrayBuffer}} associated with the - [= relevant global object =] - of `this` [[HTML]], and containing - |data|. -

      -
    6. -
    -
    -
    Otherwise:
    -
    -

    - [= exception/throw =] a - {{NotSupportedError}}. -

    -
    -
    -
  6. -
  7. -

    - Return |result|. -

    -
  8. -
-
-
-
- - -
-

Ed25519

-
-

Description

-

- The "`Ed25519`" algorithm identifier is used to perform signing - and verification using the Ed25519 algorithm specified in - [[RFC8032]]. -

-
-
-

Registration

-

- The recognized algorithm name - for this algorithm is "`Ed25519`". -

-
OperationParametersResultOperationParametersResult
deriveBits {{EcdhKeyDeriveParams}}octet stringoctet string
generateKey
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OperationParametersResult
signNone{{ArrayBuffer}}
verifyNoneboolean
generateKeyNone{{CryptoKeyPair}}
importKeyNone{{CryptoKey}}
exportKeyNoneobject
-
-
-

Operations

-
-
Sign
-
- When signing, the following algorithm should be used: -
    -
  1. -

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

    -
  2. -
  3. -

    - Perform the Ed25519 signing process, as specified in [[RFC8032]], - Section 5.1.6, with |message| as |M|, - 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]]. -

    -
  4. -
  5. -

    - Return a new {{ArrayBuffer}} associated with the - [= relevant global object =] - of `this` [[HTML]], and containing the - bytes of the signature resulting from performing - the Ed25519 signing process. -

    -
  6. -
-
-
Verify
-
- When verifying, the following algorithm should be used: -
    -
  1. -

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

    -
  2. -
  3. -

    - 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. -

    -
  4. -
  5. -

    - 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. -

    -
  6. -
  7. -

    - Perform the Ed25519 verification steps, as specified in [[RFC8032]], - Section 5.1.7, using the cofactorless (unbatched) equation, - `[S]B = R + [k]A'`, on the |signature|, with |message| as |M|, - using the Ed25519 public key associated with |key|. -

    -
  8. -
  9. -

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

    -
  10. -
  11. -

    - Return |result|. -

    -
  12. -
-
-
Generate Key
-
-
    -
  1. -

    - If |usages| contains a value which is not - one of "`sign`" or "`verify`", - then [= exception/throw =] a - {{SyntaxError}}. -

    -
  2. -
  3. -

    - Generate an Ed25519 key pair, as defined in [[RFC8032]], section 5.1.5. -

    -
  4. -
  5. -

    - Let |algorithm| be a new {{KeyAlgorithm}} object. -

    -
  6. -
  7. -

    - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`Ed25519`". -

    -
  8. -
  9. -

    - Let |publicKey| be a new {{CryptoKey}} associated with the - [= relevant global object =] - of `this` [[HTML]], and - representing the public key of the generated key pair. -

    -
  10. -
  11. -

    - Set the [[\type]] internal slot of - |publicKey| to "`public`" -

    -
  12. -
  13. -

    - Set the [[\algorithm]] internal - slot of |publicKey| to |algorithm|. -

    -
  14. -
  15. -

    - Set the [[\extractable]] internal - slot of |publicKey| to true. -

    -
  16. -
  17. -

    - Set the [[\usages]] internal slot of - |publicKey| to be the usage intersection - of |usages| and `[ "verify" ]`. -

    -
  18. -
  19. -

    - Let |privateKey| be a new {{CryptoKey}} associated with the - [= relevant global object =] - of `this` [[HTML]], and - representing the private key of the generated key pair. -

    -
  20. -
  21. -

    - Set the [[\type]] internal slot of - |privateKey| to {{KeyType/"private"}} -

    -
  22. -
  23. -

    - Set the [[\algorithm]] internal - slot of |privateKey| to |algorithm|. -

    -
  24. -
  25. -

    - Set the [[\extractable]] internal - slot of |privateKey| to |extractable|. -

    -
  26. -
  27. -

    - Set the [[\usages]] internal slot of - |privateKey| to be the usage intersection - of |usages| and `[ "sign" ]`. -

    -
  28. -
  29. -

    - Let |result| be a new {{CryptoKeyPair}} - dictionary. -

    -
  30. -
  31. -

    - Set the {{CryptoKeyPair/publicKey}} attribute - of |result| to be |publicKey|. -

    -
  32. -
  33. -

    - Set the {{CryptoKeyPair/privateKey}} attribute - of |result| to be |privateKey|. -

    -
  34. -
  35. -

    - Return the result of converting |result| to an ECMAScript Object, as - defined by [[WebIDL]]. -

    -
  36. -
-
+
+
Derive Bits
+
    +
  1. +

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

    +
  2. +
  3. +

    + Let |publicKey| be the + {{EcdhKeyDeriveParams/public}} member of + |normalizedAlgorithm|. +

    +
  4. +
  5. +

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

    +
  6. +
  7. +

    + If the {{KeyAlgorithm/name}} attribute of + the [[\algorithm]] internal slot of + |publicKey| is not equal to the {{KeyAlgorithm/name}} property of the [[\algorithm]] internal slot of + |key|, then [= exception/throw =] an {{InvalidAccessError}}. +

    +
  8. +
  9. +

    + Let |secret| be the result of performing the X448 function specified in + [[RFC7748]] Section 5 with |key| as the X448 private key |k| + and the X448 public key represented by the [[\handle]] + internal slot of |publicKey| as the X448 public key |u|. +

    +
  10. +
  11. +

    + If |secret| is the all-zero value, + then [= exception/throw =] a {{OperationError}}. + This check must be performed in constant-time, as per [[RFC7748]] Section 6.2. +

    +
  12. +
  13. +
    +
    If |length| is null:
    +
    Return |secret|
    +
    Otherwise:
    +
    +
    +
    + If the length of |secret| in bits is less than + |length|: +
    +
    + [= exception/throw =] an + {{OperationError}}. +
    +
    Otherwise:
    +
    + Return an octet string containing the first |length| bits of |secret|. +
    +
    +
    +
    +
  14. +
+
+
+
Generate Key
+
    +
  1. +

    + If |usages| contains an entry which is not + "`deriveKey`" or "`deriveBits`" + then [= exception/throw =] a + {{SyntaxError}}. +

    +
  2. +
  3. +

    + Generate an X448 key pair, with the private key being 56 random bytes, + and the public key being `X448(a, 5)`, + as defined in [[RFC7748]], section 6.2. +

    +
  4. +
  5. +

    + Let |algorithm| be a new {{KeyAlgorithm}} object. +

    +
  6. +
  7. +

    + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`X448`". +

    +
  8. +
  9. +

    + Let |publicKey| be a new {{CryptoKey}} associated with the + [= relevant global object =] + of `this` [[HTML]], and + representing the public key of the generated key pair. +

    +
  10. +
  11. +

    + Set the [[\type]] internal slot of + |publicKey| to "`public`" +

    +
  12. +
  13. +

    + Set the [[\algorithm]] internal + slot of |publicKey| to |algorithm|. +

    +
  14. +
  15. +

    + Set the [[\extractable]] internal + slot of |publicKey| to true. +

    +
  16. +
  17. +

    + Set the [[\usages]] internal slot of + |publicKey| to be the empty list. +

    +
  18. +
  19. +

    + Let |privateKey| be a new {{CryptoKey}} associated with the + [= relevant global object =] + of `this` [[HTML]], and + representing the private key of the generated key pair. +

    +
  20. +
  21. +

    + Set the [[\type]] internal slot of + |privateKey| to {{KeyType/"private"}} +

    +
  22. +
  23. +

    + Set the [[\algorithm]] internal + slot of |privateKey| to |algorithm|. +

    +
  24. +
  25. +

    + Set the [[\extractable]] internal + slot of |privateKey| to |extractable|. +

    +
  26. +
  27. +

    + Set the [[\usages]] internal slot of + |privateKey| to be the + usage intersection of + |usages| and `[ "deriveKey", "deriveBits" ]`. +

    +
  28. +
  29. +

    + Let |result| be a new {{CryptoKeyPair}} + dictionary. +

    +
  30. +
  31. +

    + Set the {{CryptoKeyPair/publicKey}} attribute + of |result| to be |publicKey|. +

    +
  32. +
  33. +

    + Set the {{CryptoKeyPair/privateKey}} attribute + of |result| to be |privateKey|. +

    +
  34. +
  35. +

    + Return the result of converting |result| to an ECMAScript Object, as + defined by [[WebIDL]]. +

    +
  36. +
+
-
Import Key
-
-
    -
  1. -

    Let |keyData| be the key data to be imported.

    -
  2. -
  3. -
    -
    If |format| is {{KeyFormat/"spki"}}:
    -
    -
      -
    1. -

      - If |usages| contains a value which is not - "`verify`" - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -

      - Let |spki| be the result of running the - parse a subjectPublicKeyInfo - algorithm over |keyData|. -

      -
    4. -
    5. -

      - If an error occurred while parsing, - then [= exception/throw =] a - {{DataError}}. -

      -
    6. -
    7. -

      - If the `algorithm` object identifier field of the - `algorithm` AlgorithmIdentifier field of |spki| is - not equal to the `id-Ed25519` - object identifier defined in [[RFC8410]], - then [= exception/throw =] a - {{DataError}}. -

      -
    8. -
    9. -

      - If the `parameters` field of the `algorithm` - AlgorithmIdentifier field of |spki| is present, - then [= exception/throw =] a - {{DataError}}. -

      -
    10. -
    11. -

      - Let |publicKey| be the Ed25519 public key identified by - the `subjectPublicKey` field of |spki|. -

      -
    12. -
    13. -

      - Let |key| be a new {{CryptoKey}} associated with the - [= relevant global object =] - of `this` [[HTML]], and - that represents |publicKey|. -

      -
    14. -
    15. -

      - Set the [[\type]] internal slot - of |key| to "`public`" -

      -
    16. -
    17. -

      - Let |algorithm| be a new {{KeyAlgorithm}}. -

      -
    18. -
    19. -

      - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`Ed25519`". -

      -
    20. -
    21. -

      - Set the [[\algorithm]] - internal slot of |key| to |algorithm|. -

      -
    22. -
    -
    -
    If |format| is {{KeyFormat/"pkcs8"}}:
    -
    -
      -
    1. -

      - If |usages| contains a value which is not - "`sign`" - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -

      - Let |privateKeyInfo| be the result of running the - parse a privateKeyInfo - algorithm over |keyData|. -

      -
    4. -
    5. -

      - If an error occurs while parsing, - then [= exception/throw =] a - {{DataError}}. -

      -
    6. -
    7. -

      - If the `algorithm` object identifier field of the - `privateKeyAlgorithm` PrivateKeyAlgorithm field of - |privateKeyInfo| is not equal to the - `id-Ed25519` object identifier defined in [[RFC8410]], - then [= exception/throw =] a - {{DataError}}. -

      -
    8. -
    9. -

      - If the `parameters` field of the - `privateKeyAlgorithm` PrivateKeyAlgorithmIdentifier field - of |privateKeyInfo| is present, - then [= exception/throw =] a - {{DataError}}. -

      -
    10. -
    11. -

      - Let |curvePrivateKey| be the result of performing the parse an ASN.1 structure - algorithm, with |data| as the `privateKey` field - of |privateKeyInfo|, |structure| as the ASN.1 - `CurvePrivateKey` structure specified in Section 7 of [[RFC8410]], and |exactData| set to true. -

      -
    12. -
    13. -

      - If an error occurred while parsing, - then [= exception/throw =] a - {{DataError}}. -

      -
    14. -
    15. -

      - Let |key| be a new {{CryptoKey}} associated with the - [= relevant global object =] - of `this` [[HTML]], and - that represents the Ed25519 private key identified by |curvePrivateKey|. -

      -
    16. -
    17. -

      - Set the [[\type]] internal slot - of |key| to {{KeyType/"private"}} -

      -
    18. -
    19. -

      - Let |algorithm| be a new {{KeyAlgorithm}}. -

      -
    20. -
    21. -

      - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`Ed25519`". -

      -
    22. -
    23. -

      - Set the [[\algorithm]] - internal slot of |key| to |algorithm|. -

      -
    24. -
    -
    -
    If |format| is {{KeyFormat/"jwk"}}:
    -
    -
      -
    1. -
      -
      If |keyData| is a {{JsonWebKey}} dictionary:
      -

      Let |jwk| equal |keyData|.

      -
      Otherwise:
      -

      [= exception/Throw =] a {{DataError}}.

      -
      -
    2. -
    3. -

      - If the {{JsonWebKey/d}} field is present and |usages| contains - a value which is not - "`sign`", or, - if the {{JsonWebKey/d}} field is not present and |usages| contains - a value which is not - "`verify`" - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    4. -
    5. -

      - If the {{JsonWebKey/kty}} field of |jwk| is not - "`OKP`", - then [= exception/throw =] a - {{DataError}}. -

      -
    6. -
    7. -

      - If the {{JsonWebKey/crv}} field of |jwk| is not - "`Ed25519`", - then [= exception/throw =] a - {{DataError}}. -

      -
    8. -
    9. -

      - If the {{JsonWebKey/alg}} field of |jwk| is present and is - not "`Ed25519`" or "`EdDSA`", - then [= exception/throw =] a - {{DataError}}. -

      -
    10. -
    11. -

      - If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present and is - not "`sig`", - then [= exception/throw =] a - {{DataError}}. -

      -
    12. -
    13. -

      - If the {{JsonWebKey/key_ops}} field of |jwk| is present, and - is invalid according to the requirements of JSON Web - Key [[JWK]], or it does not contain all of the specified |usages| - values, - then [= exception/throw =] a - {{DataError}}. -

      -
    14. -
    15. -

      - If the {{JsonWebKey/ext}} field of |jwk| is present and - has the value false and |extractable| is true, - then [= exception/throw =] a - {{DataError}}. -

      -
    16. -
    17. -
      -
      If the {{JsonWebKey/d}} field is present:
      -
      -
        -
      1. -

        - If |jwk| does not meet the requirements of - the JWK private key format described in Section 2 - of [[RFC8037]], then [= exception/throw =] a {{DataError}}. -

        -
      2. -
      3. -

        - Let |key| be a new {{CryptoKey}} object that represents the - Ed25519 private key identified by interpreting - |jwk| according to Section 2 of [[RFC8037]]. -

        -
      4. -
      5. -

        - Set the [[\type]] - internal slot of |Key| to {{KeyType/"private"}}. -

        -
      6. -
      -
      -
      Otherwise:
      -
      -
        -
      1. -

        - If |jwk| does not meet the requirements of - the JWK public key format described in Section 2 - of [[RFC8037]], then [= exception/throw =] a {{DataError}}. -

        -
      2. -
      3. -

        - Let |key| be a new {{CryptoKey}} object that represents the - Ed25519 public key identified by interpreting - |jwk| according to Section 2 of [[RFC8037]]. -

        -
      4. -
      5. -

        - Set the [[\type]] - internal slot of |Key| to {{KeyType/"public"}}. -

        -
      6. -
      -
      -
      -
    18. -
    19. -

      - Let |algorithm| be a new instance of a {{KeyAlgorithm}} object. -

      -
    20. -
    21. -

      - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`Ed25519`". -

      -
    22. -
    23. -

      - Set the [[\algorithm]] - internal slot of |key| to |algorithm|. -

      -
    24. -
    -
    -
    If |format| is {{KeyFormat/"raw"}}:
    -
    -
      -
    1. -

      - If |usages| contains a value which is not - "`verify`" - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -

      - Let |data| be |keyData|. -

      -
    4. -
    5. -

      - If the length in bits of |data| is not 256 then [= exception/throw =] a {{DataError}}. -

      -
    6. -
    7. -

      - Let |algorithm| be a new {{KeyAlgorithm}} object. -

      -
    8. -
    9. -

      - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`Ed25519`". -

      -
    10. -
    11. -

      - Let |key| be a new {{CryptoKey}} associated with the - [= relevant global object =] - of `this` [[HTML]], and that represents |data|. -

      -
    12. -
    13. -

      - Set the [[\type]] internal slot - of |key| to "`public`" -

      -
    14. -
    15. -

      - Set the [[\algorithm]] - internal slot of |key| to |algorithm|. -

      -
    16. -
    -
    -
    Otherwise:
    -
    -

    - [= exception/throw =] a - {{NotSupportedError}}. -

    -
    -
    -
  4. -
  5. -

    - Return |key| -

    -
  6. -
-
+
+
Import Key
+
    +
  1. +

    Let |keyData| be the key data to be imported.

    +
  2. +
  3. +
    +
    If |format| is {{KeyFormat/"spki"}}:
    +
    +
      +
    1. +

      + If |usages| is not empty + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    2. +
    3. +

      + Let |spki| be the result of running the + parse a subjectPublicKeyInfo + algorithm over |keyData|. +

      +
    4. +
    5. +

      + If an error occurred while parsing, + then [= exception/throw =] a + {{DataError}}. +

      +
    6. +
    7. +

      + If the `algorithm` object identifier field of the + `algorithm` AlgorithmIdentifier field of |spki| is + not equal to the `id-X448` + object identifier defined in [[RFC8410]], + then [= exception/throw =] a + {{DataError}}. +

      +
    8. +
    9. +

      + If the `parameters` field of the `algorithm` + AlgorithmIdentifier field of |spki| is present, + then [= exception/throw =] a + {{DataError}}. +

      +
    10. +
    11. +

      + Let |publicKey| be the X448 public key identified by + the `subjectPublicKey` field of |spki|. +

      +
    12. +
    13. +

      + Let |key| be a new {{CryptoKey}} associated with the + [= relevant global object =] + of `this` [[HTML]], and + that represents |publicKey|. +

      +
    14. +
    15. +

      + Set the [[\type]] internal slot + of |key| to "`public`" +

      +
    16. +
    17. +

      + Let |algorithm| be a new {{KeyAlgorithm}}. +

      +
    18. +
    19. +

      + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`X448`". +

      +
    20. +
    21. +

      + Set the [[\algorithm]] + internal slot of |key| to |algorithm|. +

      +
    22. +
    +
    +
    If |format| is {{KeyFormat/"pkcs8"}}:
    +
    +
      +
    1. +

      + If |usages| contains an entry which is not + "`deriveKey`" or "`deriveBits`" + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    2. +
    3. +

      + Let |privateKeyInfo| be the result of running the + parse a privateKeyInfo + algorithm over |keyData|. +

      +
    4. +
    5. +

      + If an error occurs while parsing, + then [= exception/throw =] a + {{DataError}}. +

      +
    6. +
    7. +

      + If the `algorithm` object identifier field of the + `privateKeyAlgorithm` PrivateKeyAlgorithm field of + |privateKeyInfo| is not equal to the + `id-X448` object identifier defined in [[RFC8410]], + then [= exception/throw =] a + {{DataError}}. +

      +
    8. +
    9. +

      + If the `parameters` field of the + `privateKeyAlgorithm` PrivateKeyAlgorithmIdentifier field + of |privateKeyInfo| is present, + then [= exception/throw =] a + {{DataError}}. +

      +
    10. +
    11. +

      + Let |curvePrivateKey| be the result of performing the parse an ASN.1 structure + algorithm, with |data| as the `privateKey` field + of |privateKeyInfo|, |structure| as the ASN.1 + `CurvePrivateKey` structure specified in Section 7 of [[RFC8410]], and |exactData| set to true. +

      +
    12. +
    13. +

      + If an error occurred while parsing, + then [= exception/throw =] a + {{DataError}}. +

      +
    14. +
    15. +

      + Let |key| be a new {{CryptoKey}} associated with the + [= relevant global object =] + of `this` [[HTML]], and + that represents the X448 private key identified by |curvePrivateKey|. +

      +
    16. +
    17. +

      + Set the [[\type]] internal slot + of |key| to {{KeyType/"private"}} +

      +
    18. +
    19. +

      + Let |algorithm| be a new {{KeyAlgorithm}}. +

      +
    20. +
    21. +

      + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`X448`". +

      +
    22. +
    23. +

      + Set the [[\algorithm]] + internal slot of |key| to |algorithm|. +

      +
    24. +
    +
    +
    If |format| is {{KeyFormat/"jwk"}}:
    +
    +
      +
    1. +
      +
      If |keyData| is a {{JsonWebKey}} dictionary:
      +

      Let |jwk| equal |keyData|.

      +
      Otherwise:
      +

      [= exception/Throw =] a {{DataError}}.

      +
      +
    2. +
    3. +

      + If the {{JsonWebKey/d}} field is present and if |usages| + contains an entry which is not + "`deriveKey`" or "`deriveBits`" + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    4. +
    5. +

      + If the {{JsonWebKey/d}} field is not present and if |usages| is not + empty + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    6. +
    7. +

      + If the {{JsonWebKey/kty}} field of |jwk| is not + "`OKP`", + then [= exception/throw =] a + {{DataError}}. +

      +
    8. +
    9. +

      + If the {{JsonWebKey/crv}} field of |jwk| is not + "`X448`", + then [= exception/throw =] a + {{DataError}}. +

      +
    10. +
    11. +

      + If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present + and is not equal to "`enc`" then [= exception/throw =] a + {{DataError}}. +

      +
    12. +
    13. +

      + If the {{JsonWebKey/key_ops}} field of |jwk| is present, and + is invalid according to the requirements of JSON Web + Key [[JWK]], or it does not contain all of the specified |usages| + values, + then [= exception/throw =] a + {{DataError}}. +

      +
    14. +
    15. +

      + If the {{JsonWebKey/ext}} field of |jwk| is present and + has the value false and |extractable| is true, + then [= exception/throw =] a + {{DataError}}. +

      +
    16. +
    17. +
      +
      If the {{JsonWebKey/d}} field is present:
      +
      +
        +
      1. +

        + If |jwk| does not meet the requirements of + the JWK private key format described in Section 2 + of [[RFC8037]], then [= exception/throw =] a {{DataError}}. +

        +
      2. +
      3. +

        + Let |key| be a new {{CryptoKey}} object that represents the + X448 private key identified by interpreting + |jwk| according to Section 2 of [[RFC8037]]. +

        +
      4. +
      5. +

        + Set the [[\type]] + internal slot of |Key| to {{KeyType/"private"}}. +

        +
      6. +
      +
      +
      Otherwise:
      +
      +
        +
      1. +

        + If |jwk| does not meet the requirements of + the JWK public key format described in Section 2 + of [[RFC8037]], then [= exception/throw =] a {{DataError}}. +

        +
      2. +
      3. +

        + Let |key| be a new {{CryptoKey}} object that represents the + X448 public key identified by interpreting + |jwk| according to Section 2 of [[RFC8037]]. +

        +
      4. +
      5. +

        + Set the [[\type]] + internal slot of |Key| to {{KeyType/"public"}}. +

        +
      6. +
      +
      +
      +
    18. +
    19. +

      + Let |algorithm| be a new instance of a {{KeyAlgorithm}} object. +

      +
    20. +
    21. +

      + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`X448`". +

      +
    22. +
    23. +

      + Set the [[\algorithm]] + internal slot of |key| to |algorithm|. +

      +
    24. +
    +
    +
    If |format| is {{KeyFormat/"raw"}}:
    +
    +
      +
    1. +

      + If |usages| is not empty + then [= exception/throw =] a + {{SyntaxError}}. +

      +
    2. +
    3. +

      + Let |data| be |keyData|. +

      +
    4. +
    5. +

      + If the length in bits of |data| is not 448 then [= exception/throw =] a {{DataError}}. +

      +
    6. +
    7. +

      + Let |algorithm| be a new {{KeyAlgorithm}} object. +

      +
    8. +
    9. +

      + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`X448`". +

      +
    10. +
    11. +

      + Let |key| be a new {{CryptoKey}} associated with the + [= relevant global object =] + of `this` [[HTML]], and that represents |data|. +

      +
    12. +
    13. +

      + Set the [[\type]] internal slot + of |key| to "`public`" +

      +
    14. +
    15. +

      + Set the [[\algorithm]] + internal slot of |key| to |algorithm|. +

      +
    16. +
    +
    +
    Otherwise:
    +
    +

    + [= exception/throw =] a + {{NotSupportedError}}. +

    +
    +
    +
  4. +
  5. +

    + Return |key| +

    +
  6. +
+
-
Export Key
-
-
    -
  1. -

    - Let |key| be the {{CryptoKey}} to be - exported. -

    -
  2. -
  3. -

    - If the underlying cryptographic key material represented by the [[\handle]] internal slot of |key| - cannot be accessed, then [= exception/throw =] an {{OperationError}}. -

    -
  4. -
  5. -
    -
    If |format| is {{KeyFormat/"spki"}}:
    -
    -
      -
    1. -

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

      -
    2. -
    3. -

      - Let |data| be an instance of the `subjectPublicKeyInfo` - ASN.1 structure defined in [[RFC5280]] - with the following properties: -

      -
        -
      • -

        - Set the |algorithm| field to an - `AlgorithmIdentifier` ASN.1 type with the following - properties: -

        -
          -
        • -

          - Set the |algorithm| object identifier to the - `id-Ed25519` OID defined in [[RFC8410]]. -

          -
        • -
        -
      • -
      • -

        - Set the |subjectPublicKey| field to |keyData|. -

        -
      • -
      -
    4. -
    5. -

      - Let |result| be a new {{ArrayBuffer}} associated with the - [= relevant global object =] - of `this` [[HTML]], and containing - |data|. -

      -
    6. -
    -
    -
    If |format| is {{KeyFormat/"pkcs8"}}:
    -
    -
      -
    1. -

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

      -
    2. -
    3. -

      - Let |data| be an instance of the `privateKeyInfo` - ASN.1 structure defined in [[RFC5208]] - with the following properties: -

      -
        -
      • -

        - Set the |version| field to `0`. -

        -
      • -
      • -

        - Set the |privateKeyAlgorithm| field to a - `PrivateKeyAlgorithmIdentifier` ASN.1 type with the - following properties: -

        -
          -
        • -

          - Set the |algorithm| object identifier to the - `id-Ed25519` OID defined in [[RFC8410]]. -

          -
        • -
        -
      • -
      • -

        - Set the |privateKey| field to the result of DER-encoding - a `CurvePrivateKey` ASN.1 type, as defined in Section 7 of [[RFC8410]], that represents the - Ed25519 private key represented by the [[\handle]] internal slot of - |key| -

        -
      • -
      -
    4. -
    5. -

      - Let |result| be a new {{ArrayBuffer}} associated with the - [= relevant global object =] - of `this` [[HTML]], and containing - |data|. -

      -
    6. -
    -
    -
    If |format| is {{KeyFormat/"jwk"}}:
    -
    -
      -
    1. -

      - Let |jwk| be a new {{JsonWebKey}} - dictionary. -

      -
    2. -
    3. -

      - Set the `kty` attribute of |jwk| to - "`OKP`". -

      -
    4. -
    5. -

      - Set the `alg` attribute of |jwk| to - "`Ed25519`". -

      -
    6. -
    7. -

      - Set the `crv` attribute of |jwk| to - "`Ed25519`". -

      -
    8. -
    9. -

      - Set the {{JsonWebKey/x}} attribute of |jwk| according to the +

      +
      Export Key
      +
        +
      1. +

        + Let |key| be the {{CryptoKey}} to be + exported. +

        +
      2. +
      3. +

        + If the underlying cryptographic key material represented by the [[\handle]] internal slot of |key| + cannot be accessed, then [= exception/throw =] an {{OperationError}}. +

        +
      4. +
      5. +
        +
        If |format| is {{KeyFormat/"spki"}}:
        +
        +
          +
        1. +

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

          +
        2. +
        3. +

          + Let |data| be an instance of the `subjectPublicKeyInfo` + ASN.1 structure defined in [[RFC5280]] + with the following properties: +

          +
            +
          • +

            + Set the |algorithm| field to an + `AlgorithmIdentifier` ASN.1 type with the following + properties: +

            +
              +
            • +

              + Set the |algorithm| object identifier to the + `id-X448` OID defined in [[RFC8410]]. +

              +
            • +
            +
          • +
          • +

            + Set the |subjectPublicKey| field to |keyData|. +

            +
          • +
          +
        4. +
        5. +

          + Let |result| be a new {{ArrayBuffer}} associated with the + [= relevant global object =] + of `this` [[HTML]], and containing + |data|. +

          +
        6. +
        +
        +
        If |format| is {{KeyFormat/"pkcs8"}}:
        +
        +
          +
        1. +

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

          +
        2. +
        3. +

          + Let |data| be an instance of the `privateKeyInfo` + ASN.1 structure defined in [[RFC5208]] + with the following properties: +

          +
            +
          • +

            + Set the |version| field to `0`. +

            +
          • +
          • +

            + Set the |privateKeyAlgorithm| field to a + `PrivateKeyAlgorithmIdentifier` ASN.1 type with the + following properties: +

            +
              +
            • +

              + Set the |algorithm| object identifier to the + `id-X448` OID defined in [[RFC8410]]. +

              +
            • +
            +
          • +
          • +

            + Set the |privateKey| field to the result of DER-encoding + a `CurvePrivateKey` ASN.1 type, as defined in Section 7 of [[RFC8410]], that represents the + X448 private key represented by the [[\handle]] internal slot of + |key| +

            +
          • +
          +
        4. +
        5. +

          + Let |result| be a new {{ArrayBuffer}} associated with the + [= relevant global object =] + of `this` [[HTML]], and containing + |data|. +

          +
        6. +
        +
        +
        If |format| is {{KeyFormat/"jwk"}}:
        +
        +
          +
        1. +

          + Let |jwk| be a new {{JsonWebKey}} + dictionary. +

          +
        2. +
        3. +

          + Set the `kty` attribute of |jwk| to + "`OKP`". +

          +
        4. +
        5. +

          + Set the `crv` attribute of |jwk| to + "`X448`". +

          +
        6. +
        7. +

          + Set the {{JsonWebKey/x}} attribute of |jwk| according to the + definition in Section 2 of [[RFC8037]]. +

          +
        8. +
        9. +
          +
          + If the [[\type]] internal slot + of |key| is {{KeyType/"private"}} +
          +
          + Set the {{JsonWebKey/d}} attribute of |jwk| according to the definition in Section 2 of [[RFC8037]]. -

          -
        10. -
        11. -
          -
          - If the [[\type]] internal slot - of |key| is {{KeyType/"private"}} -
          -
          - Set the {{JsonWebKey/d}} attribute of |jwk| according to the - definition in Section 2 of [[RFC8037]]. -
          -
          -
        12. -
        13. -

          - Set the `key_ops` attribute of |jwk| to the {{CryptoKey/usages}} attribute of |key|. -

          -
        14. -
        15. -

          - Set the `ext` attribute of |jwk| to the [[\extractable]] internal slot - of |key|. -

          -
        16. -
        17. -

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

          -
        18. -
        -
        -
        - If |format| is {{KeyFormat/"raw"}}: -
        -
        -
          -
        1. -

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

          -
        2. -
        3. -

          - Let |data| be an octet string representing the Ed25519 - public key represented by the [[\handle]] internal slot of - |key|. -

          -
        4. -
        5. -

          - Let |result| be a new {{ArrayBuffer}} associated with the - [= relevant global object =] - of `this` [[HTML]], and containing - |data|. -

          -
        6. -
        -
        -
        Otherwise:
        -
        -

        - [= exception/throw =] a - {{NotSupportedError}}. -

        -
        -
        -
      6. -
      7. -

        - Return |result|. -

        -
      8. -
      -
    -
    +
+
+ +
  • +

    + Set the `key_ops` attribute of |jwk| to the {{CryptoKey/usages}} attribute of |key|. +

    +
  • +
  • +

    + Set the `ext` attribute of |jwk| to the [[\extractable]] internal slot + of |key|. +

    +
  • +
  • +

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

    +
  • + + +
    + If |format| is {{KeyFormat/"raw"}}: +
    +
    +
      +
    1. +

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

      +
    2. +
    3. +

      + Let |data| be an octet string representing the X448 + public key represented by the [[\handle]] internal slot of + |key|. +

      +
    4. +
    5. +

      + Let |result| be a new {{ArrayBuffer}} associated with the + [= relevant global object =] + of `this` [[HTML]], and containing + |data|. +

      +
    6. +
    +
    +
    Otherwise:
    +
    +

    + [= exception/throw =] a + {{NotSupportedError}}. +

    +
    + + +
  • +

    + Return |result|. +

    +
  • + +
    @@ -2698,15 +947,15 @@

    Description

    Registration

    - The recognized algorithm name + The recognized algorithm name for this algorithm is "`Ed448`".

    - - - + + + @@ -2750,895 +999,889 @@

    Ed448Params dictionary

    Operations

    -
    -
    Sign
    -
    - When signing, the following algorithm should be used: -
      -
    1. -

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

      -
    2. -
    3. -

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

      -
    4. -
    5. -

      - If |context| has a length greater than 255 bytes, - then [= exception/throw =] an {{OperationError}}. -

      -
    6. -
    7. -

      - Perform the Ed448 signing process, as specified in [[RFC8032]], - Section 5.2.6, with |message| as |M| - and |context| as |C|, - using the Ed448 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]]. -

      -
    8. -
    9. -

      - Return a new {{ArrayBuffer}} associated with the - [= relevant global object =] - of `this` [[HTML]], and containing the - bytes of the signature resulting from performing - the Ed448 signing process. -

      -
    10. -
    -
    -
    Verify
    -
    - When verifying, the following algorithm should be used: -
      -
    1. -

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

      -
    2. -
    3. -

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

      -
    4. -
    5. -

      - If |context| has a length greater than 255 bytes, - then [= exception/throw =] an {{OperationError}}. -

      -
    6. -
    7. -

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

      -

      - Not all implementations perform this check. -

      -
    8. -
    9. -

      - 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 Ed448, return `false`. -

      -

      - Not all implementations perform this check. -

      -
    10. -
    11. -

      - Perform the Ed448 verification steps, as specified in [[RFC8032]], - Section 5.2.7, using the cofactorless (unbatched) equation, - `[S]B = R + [k]A'`, on the |signature|, with |message| as |M| - and |context| as |C|, - using the Ed448 public key associated with |key|. -

      -
    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. -
    -
    -
    Generate Key
    -
    -
      -
    1. -

      - If |usages| contains a value which is not - one of "`sign`" or "`verify`", - then [= exception/throw =] a - {{SyntaxError}}. -

      -
    2. -
    3. -

      - Generate an Ed448 key pair, as defined in [[RFC8032]], section 5.1.5. -

      -
    4. -
    5. -

      - Let |algorithm| be a new {{KeyAlgorithm}} object. -

      -
    6. -
    7. -

      - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`Ed448`". -

      -
    8. -
    9. -

      - Let |publicKey| be a new {{CryptoKey}} associated with the - [= relevant global object =] - of `this` [[HTML]], and - representing the public key of the generated key pair. -

      -
    10. -
    11. -

      - Set the [[\type]] internal slot of - |publicKey| to "`public`" -

      -
    12. -
    13. -

      - Set the [[\algorithm]] internal - slot of |publicKey| to |algorithm|. -

      -
    14. -
    15. -

      - Set the [[\extractable]] internal - slot of |publicKey| to true. -

      -
    16. -
    17. -

      - Set the [[\usages]] internal slot of - |publicKey| to be the usage intersection - of |usages| and `[ "verify" ]`. -

      -
    18. -
    19. -

      - Let |privateKey| be a new {{CryptoKey}} associated with the - [= relevant global object =] - of `this` [[HTML]], and - representing the private key of the generated key pair. -

      -
    20. -
    21. -

      - Set the [[\type]] internal slot of - |privateKey| to {{KeyType/"private"}} -

      -
    22. -
    23. -

      - Set the [[\algorithm]] internal - slot of |privateKey| to |algorithm|. -

      -
    24. -
    25. -

      - Set the [[\extractable]] internal - slot of |privateKey| to |extractable|. -

      -
    26. -
    27. -

      - Set the [[\usages]] internal slot of - |privateKey| to be the usage intersection - of |usages| and `[ "sign" ]`. -

      -
    28. -
    29. -

      - Let |result| be a new {{CryptoKeyPair}} - dictionary. -

      -
    30. -
    31. -

      - Set the {{CryptoKeyPair/publicKey}} attribute - of |result| to be |publicKey|. -

      -
    32. -
    33. -

      - Set the {{CryptoKeyPair/privateKey}} attribute - of |result| to be |privateKey|. -

      -
    34. -
    35. -

      - Return the result of converting |result| to an ECMAScript Object, as - defined by [[WebIDL]]. -

      -
    36. -
    -
    - -
    Import Key
    -
    -
      -
    1. -

      Let |keyData| be the key data to be imported.

      -
    2. -
    3. -
      -
      If |format| is {{KeyFormat/"spki"}}:
      -
      -
        -
      1. -

        - If |usages| contains a value which is not - "`verify`" - then [= exception/throw =] a - {{SyntaxError}}. -

        -
      2. -
      3. -

        - Let |spki| be the result of running the - parse a subjectPublicKeyInfo - algorithm over |keyData|. -

        -
      4. -
      5. -

        - If an error occurred while parsing, - then [= exception/throw =] a - {{DataError}}. -

        -
      6. -
      7. -

        - If the `algorithm` object identifier field of the - `algorithm` AlgorithmIdentifier field of |spki| is - not equal to the `id-Ed448` - object identifier defined in [[RFC8410]], - then [= exception/throw =] a - {{DataError}}. -

        -
      8. -
      9. -

        - If the `parameters` field of the `algorithm` - AlgorithmIdentifier field of |spki| is present, - then [= exception/throw =] a - {{DataError}}. -

        -
      10. -
      11. -

        - Let |publicKey| be the Ed448 public key identified by - the `subjectPublicKey` field of |spki|. -

        -
      12. -
      13. -

        - Let |key| be a new {{CryptoKey}} associated with the - [= relevant global object =] - of `this` [[HTML]], and - that represents |publicKey|. -

        -
      14. -
      15. -

        - Set the [[\type]] internal slot - of |key| to "`public`" -

        -
      16. -
      17. -

        - Let |algorithm| be a new {{KeyAlgorithm}}. -

        -
      18. -
      19. -

        - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`Ed448`". -

        -
      20. -
      21. -

        - Set the [[\algorithm]] - internal slot of |key| to |algorithm|. -

        -
      22. -
      -
      -
      If |format| is {{KeyFormat/"pkcs8"}}:
      -
      -
        -
      1. -

        - If |usages| contains a value which is not - "`sign`" - then [= exception/throw =] a - {{SyntaxError}}. -

        -
      2. -
      3. -

        - Let |privateKeyInfo| be the result of running the - parse a privateKeyInfo - algorithm over |keyData|. -

        -
      4. -
      5. -

        - If an error occurs while parsing, - then [= exception/throw =] a - {{DataError}}. -

        -
      6. -
      7. -

        - If the `algorithm` object identifier field of the - `privateKeyAlgorithm` PrivateKeyAlgorithm field of - |privateKeyInfo| is not equal to the - `id-Ed448` object identifier defined in [[RFC8410]], - then [= exception/throw =] a - {{DataError}}. -

        -
      8. -
      9. -

        - If the `parameters` field of the - `privateKeyAlgorithm` PrivateKeyAlgorithmIdentifier field - of |privateKeyInfo| is present, - then [= exception/throw =] a - {{DataError}}. -

        -
      10. -
      11. -

        - Let |curvePrivateKey| be the result of performing the parse an ASN.1 structure - algorithm, with |data| as the `privateKey` field - of |privateKeyInfo|, |structure| as the ASN.1 - `CurvePrivateKey` structure specified in Section 7 of [[RFC8410]], and |exactData| set to true. -

        -
      12. -
      13. -

        - If an error occurred while parsing, - then [= exception/throw =] a - {{DataError}}. -

        -
      14. -
      15. -

        - Let |key| be a new {{CryptoKey}} associated with the - [= relevant global object =] - of `this` [[HTML]], and - that represents the Ed448 private key identified by |curvePrivateKey|. -

        -
      16. -
      17. -

        - Set the [[\type]] internal slot - of |key| to {{KeyType/"private"}} -

        -
      18. -
      19. -

        - Let |algorithm| be a new {{KeyAlgorithm}}. -

        -
      20. -
      21. -

        - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`Ed448`". -

        -
      22. -
      23. -

        - Set the [[\algorithm]] - internal slot of |key| to |algorithm|. -

        -
      24. -
      -
      -
      If |format| is {{KeyFormat/"jwk"}}:
      -
      -
        -
      1. -
        -
        If |keyData| is a {{JsonWebKey}} dictionary:
        -

        Let |jwk| equal |keyData|.

        -
        Otherwise:
        -

        [= exception/Throw =] a {{DataError}}.

        -
        -
      2. -
      3. -

        - If the {{JsonWebKey/d}} field is present and |usages| contains - a value which is not - "`sign`", or, - if the {{JsonWebKey/d}} field is not present and |usages| contains - a value which is not - "`verify`" - then [= exception/throw =] a - {{SyntaxError}}. -

        -
      4. -
      5. -

        - If the {{JsonWebKey/kty}} field of |jwk| is not - "`OKP`", - then [= exception/throw =] a - {{DataError}}. -

        -
      6. -
      7. -

        - If the {{JsonWebKey/crv}} field of |jwk| is not - "`Ed448`", - then [= exception/throw =] a - {{DataError}}. -

        -
      8. -
      9. -

        - If the {{JsonWebKey/alg}} field of |jwk| is present and is - not "`Ed448`" or "`EdDSA`", - then [= exception/throw =] a - {{DataError}}. -

        -
      10. -
      11. -

        - If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present and is - not "`sig`", - then [= exception/throw =] a - {{DataError}}. -

        -
      12. -
      13. -

        - If the {{JsonWebKey/key_ops}} field of |jwk| is present, and - is invalid according to the requirements of JSON Web - Key [[JWK]], or it does not contain all of the specified |usages| - values, - then [= exception/throw =] a - {{DataError}}. -

        -
      14. -
      15. -

        - If the {{JsonWebKey/ext}} field of |jwk| is present and - has the value false and |extractable| is true, - then [= exception/throw =] a - {{DataError}}. -

        -
      16. -
      17. -
        -
        If the {{JsonWebKey/d}} field is present:
        -
        -
          -
        1. -

          - If |jwk| does not meet the requirements of - the JWK private key format described in Section 2 - of [[RFC8037]], then [= exception/throw =] a {{DataError}}. -

          -
        2. -
        3. -

          - Let |key| be a new {{CryptoKey}} object that represents the - Ed448 private key identified by interpreting - |jwk| according to Section 2 of [[RFC8037]]. -

          -
        4. -
        5. -

          - Set the [[\type]] - internal slot of |Key| to {{KeyType/"private"}}. -

          -
        6. -
        -
        -
        Otherwise:
        -
        -
          -
        1. -

          - If |jwk| does not meet the requirements of - the JWK public key format described in Section 2 - of [[RFC8037]], then [= exception/throw =] a {{DataError}}. -

          -
        2. -
        3. -

          - Let |key| be a new {{CryptoKey}} object that represents the - Ed448 public key identified by interpreting - |jwk| according to Section 2 of [[RFC8037]]. -

          -
        4. -
        5. -

          - Set the [[\type]] - internal slot of |Key| to {{KeyType/"public"}}. -

          -
        6. -
        -
        -
        -
      18. -
      19. -

        - Let |algorithm| be a new instance of a {{KeyAlgorithm}} object. -

        -
      20. -
      21. -

        - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`Ed448`". -

        -
      22. -
      23. -

        - Set the [[\algorithm]] - internal slot of |key| to |algorithm|. -

        -
      24. -
      -
      -
      If |format| is {{KeyFormat/"raw"}}:
      -
      -
        -
      1. -

        - If |usages| contains a value which is not - "`verify`" - then [= exception/throw =] a - {{SyntaxError}}. -

        -
      2. -
      3. -

        - Let |data| be |keyData|. -

        -
      4. -
      5. -

        - If the length in bits of |data| is not 448 then [= exception/throw =] a {{DataError}}. -

        -
      6. -
      7. -

        - Let |algorithm| be a new {{KeyAlgorithm}} object. -

        -
      8. -
      9. -

        - Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`Ed448`". -

        -
      10. -
      11. -

        - Let |key| be a new {{CryptoKey}} associated with the - [= relevant global object =] - of `this` [[HTML]], and that represents |data|. -

        -
      12. -
      13. -

        - Set the [[\type]] internal slot - of |key| to "`public`" -

        -
      14. -
      15. -

        - Set the [[\algorithm]] - internal slot of |key| to |algorithm|. -

        -
      16. -
      -
      -
      Otherwise:
      -
      -

      - [= exception/throw =] a - {{NotSupportedError}}. -

      -
      -
      -
    4. -
    5. -

      - Return |key| -

      -
    6. -
    -
    - -
    Export Key
    -
    -
      -
    1. -

      - Let |key| be the {{CryptoKey}} to be - exported. -

      -
    2. -
    3. -

      - If the underlying cryptographic key material represented by the [[\handle]] internal slot of |key| - cannot be accessed, then [= exception/throw =] an {{OperationError}}. -

      -
    4. -
    5. -
      -
      If |format| is {{KeyFormat/"spki"}}:
      -
      -
        -
      1. -

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

        -
      2. -
      3. -

        - Let |data| be an instance of the `subjectPublicKeyInfo` - ASN.1 structure defined in [[RFC5280]] - with the following properties: -

        -
          -
        • -

          - Set the |algorithm| field to an - `AlgorithmIdentifier` ASN.1 type with the following - properties: -

          -
            -
          • -

            - Set the |algorithm| object identifier to the - `id-Ed448` OID defined in [[RFC8410]]. -

            -
          • -
          -
        • -
        • -

          - Set the |subjectPublicKey| field to |keyData|. -

          -
        • -
        -
      4. -
      5. -

        - Let |result| be a new {{ArrayBuffer}} associated with the - [= relevant global object =] - of `this` [[HTML]], and containing - |data|. -

        -
      6. -
      -
      -
      If |format| is {{KeyFormat/"pkcs8"}}:
      -
      -
        -
      1. -

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

        -
      2. -
      3. -

        - Let |data| be an instance of the `privateKeyInfo` - ASN.1 structure defined in [[RFC5208]] - with the following properties: -

        -
          -
        • -

          - Set the |version| field to `0`. -

          -
        • -
        • -

          - Set the |privateKeyAlgorithm| field to a - `PrivateKeyAlgorithmIdentifier` ASN.1 type with the - following properties: -

          -
            -
          • -

            - Set the |algorithm| object identifier to the - `id-Ed448` OID defined in [[RFC8410]]. -

            -
          • -
          -
        • -
        • -

          - Set the |privateKey| field to the result of DER-encoding - a `CurvePrivateKey` ASN.1 type, as defined in Section 7 of [[RFC8410]], that represents the - Ed448 private key represented by the [[\handle]] internal slot of - |key| -

          -
        • -
        -
      4. -
      5. -

        - Let |result| be a new {{ArrayBuffer}} associated with the - [= relevant global object =] - of `this` [[HTML]], and containing - |data|. -

        -
      6. -
      -
      -
      If |format| is {{KeyFormat/"jwk"}}:
      -
      -
        -
      1. -

        - Let |jwk| be a new {{JsonWebKey}} - dictionary. -

        -
      2. -
      3. -

        - Set the `kty` attribute of |jwk| to - "`OKP`". -

        -
      4. -
      5. -

        - Set the `alg` attribute of |jwk| to - "`Ed448`". -

        -
      6. -
      7. -

        - Set the `crv` attribute of |jwk| to - "`Ed448`". -

        -
      8. -
      9. -

        - Set the {{JsonWebKey/x}} attribute of |jwk| according to the +

        +
        Sign
        +
          +
        1. +

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

          +
        2. +
        3. +

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

          +
        4. +
        5. +

          + If |context| has a length greater than 255 bytes, + then [= exception/throw =] an {{OperationError}}. +

          +
        6. +
        7. +

          + Perform the Ed448 signing process, as specified in [[RFC8032]], + Section 5.2.6, with |message| as |M| + and |context| as |C|, + using the Ed448 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]]. +

          +
        8. +
        9. +

          + Return a new {{ArrayBuffer}} associated with the + [= relevant global object =] + of `this` [[HTML]], and containing the + bytes of the signature resulting from performing + the Ed448 signing process. +

          +
        10. +
        +
        +
        +
        Verify
        +
          +
        1. +

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

          +
        2. +
        3. +

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

          +
        4. +
        5. +

          + If |context| has a length greater than 255 bytes, + then [= exception/throw =] an {{OperationError}}. +

          +
        6. +
        7. +

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

          +

          + Not all implementations perform this check. +

          +
        8. +
        9. +

          + 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 Ed448, return `false`. +

          +

          + Not all implementations perform this check. +

          +
        10. +
        11. +

          + Perform the Ed448 verification steps, as specified in [[RFC8032]], + Section 5.2.7, using the cofactorless (unbatched) equation, + `[S]B = R + [k]A'`, on the |signature|, with |message| as |M| + and |context| as |C|, + using the Ed448 public key associated with |key|. +

          +
        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. +
        +
        +
        +
        Generate Key
        +
          +
        1. +

          + If |usages| contains a value which is not + one of "`sign`" or "`verify`", + then [= exception/throw =] a + {{SyntaxError}}. +

          +
        2. +
        3. +

          + Generate an Ed448 key pair, as defined in [[RFC8032]], section 5.1.5. +

          +
        4. +
        5. +

          + Let |algorithm| be a new {{KeyAlgorithm}} object. +

          +
        6. +
        7. +

          + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`Ed448`". +

          +
        8. +
        9. +

          + Let |publicKey| be a new {{CryptoKey}} associated with the + [= relevant global object =] + of `this` [[HTML]], and + representing the public key of the generated key pair. +

          +
        10. +
        11. +

          + Set the [[\type]] internal slot of + |publicKey| to "`public`" +

          +
        12. +
        13. +

          + Set the [[\algorithm]] internal + slot of |publicKey| to |algorithm|. +

          +
        14. +
        15. +

          + Set the [[\extractable]] internal + slot of |publicKey| to true. +

          +
        16. +
        17. +

          + Set the [[\usages]] internal slot of + |publicKey| to be the usage intersection + of |usages| and `[ "verify" ]`. +

          +
        18. +
        19. +

          + Let |privateKey| be a new {{CryptoKey}} associated with the + [= relevant global object =] + of `this` [[HTML]], and + representing the private key of the generated key pair. +

          +
        20. +
        21. +

          + Set the [[\type]] internal slot of + |privateKey| to {{KeyType/"private"}} +

          +
        22. +
        23. +

          + Set the [[\algorithm]] internal + slot of |privateKey| to |algorithm|. +

          +
        24. +
        25. +

          + Set the [[\extractable]] internal + slot of |privateKey| to |extractable|. +

          +
        26. +
        27. +

          + Set the [[\usages]] internal slot of + |privateKey| to be the usage intersection + of |usages| and `[ "sign" ]`. +

          +
        28. +
        29. +

          + Let |result| be a new {{CryptoKeyPair}} + dictionary. +

          +
        30. +
        31. +

          + Set the {{CryptoKeyPair/publicKey}} attribute + of |result| to be |publicKey|. +

          +
        32. +
        33. +

          + Set the {{CryptoKeyPair/privateKey}} attribute + of |result| to be |privateKey|. +

          +
        34. +
        35. +

          + Return the result of converting |result| to an ECMAScript Object, as + defined by [[WebIDL]]. +

          +
        36. +
        +
        +
        +
        Import Key
        +
          +
        1. +

          Let |keyData| be the key data to be imported.

          +
        2. +
        3. +
          +
          If |format| is {{KeyFormat/"spki"}}:
          +
          +
            +
          1. +

            + If |usages| contains a value which is not + "`verify`" + then [= exception/throw =] a + {{SyntaxError}}. +

            +
          2. +
          3. +

            + Let |spki| be the result of running the + parse a subjectPublicKeyInfo + algorithm over |keyData|. +

            +
          4. +
          5. +

            + If an error occurred while parsing, + then [= exception/throw =] a + {{DataError}}. +

            +
          6. +
          7. +

            + If the `algorithm` object identifier field of the + `algorithm` AlgorithmIdentifier field of |spki| is + not equal to the `id-Ed448` + object identifier defined in [[RFC8410]], + then [= exception/throw =] a + {{DataError}}. +

            +
          8. +
          9. +

            + If the `parameters` field of the `algorithm` + AlgorithmIdentifier field of |spki| is present, + then [= exception/throw =] a + {{DataError}}. +

            +
          10. +
          11. +

            + Let |publicKey| be the Ed448 public key identified by + the `subjectPublicKey` field of |spki|. +

            +
          12. +
          13. +

            + Let |key| be a new {{CryptoKey}} associated with the + [= relevant global object =] + of `this` [[HTML]], and + that represents |publicKey|. +

            +
          14. +
          15. +

            + Set the [[\type]] internal slot + of |key| to "`public`" +

            +
          16. +
          17. +

            + Let |algorithm| be a new {{KeyAlgorithm}}. +

            +
          18. +
          19. +

            + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`Ed448`". +

            +
          20. +
          21. +

            + Set the [[\algorithm]] + internal slot of |key| to |algorithm|. +

            +
          22. +
          +
          +
          If |format| is {{KeyFormat/"pkcs8"}}:
          +
          +
            +
          1. +

            + If |usages| contains a value which is not + "`sign`" + then [= exception/throw =] a + {{SyntaxError}}. +

            +
          2. +
          3. +

            + Let |privateKeyInfo| be the result of running the + parse a privateKeyInfo + algorithm over |keyData|. +

            +
          4. +
          5. +

            + If an error occurs while parsing, + then [= exception/throw =] a + {{DataError}}. +

            +
          6. +
          7. +

            + If the `algorithm` object identifier field of the + `privateKeyAlgorithm` PrivateKeyAlgorithm field of + |privateKeyInfo| is not equal to the + `id-Ed448` object identifier defined in [[RFC8410]], + then [= exception/throw =] a + {{DataError}}. +

            +
          8. +
          9. +

            + If the `parameters` field of the + `privateKeyAlgorithm` PrivateKeyAlgorithmIdentifier field + of |privateKeyInfo| is present, + then [= exception/throw =] a + {{DataError}}. +

            +
          10. +
          11. +

            + Let |curvePrivateKey| be the result of performing the parse an ASN.1 structure + algorithm, with |data| as the `privateKey` field + of |privateKeyInfo|, |structure| as the ASN.1 + `CurvePrivateKey` structure specified in Section 7 of [[RFC8410]], and |exactData| set to true. +

            +
          12. +
          13. +

            + If an error occurred while parsing, + then [= exception/throw =] a + {{DataError}}. +

            +
          14. +
          15. +

            + Let |key| be a new {{CryptoKey}} associated with the + [= relevant global object =] + of `this` [[HTML]], and + that represents the Ed448 private key identified by |curvePrivateKey|. +

            +
          16. +
          17. +

            + Set the [[\type]] internal slot + of |key| to {{KeyType/"private"}} +

            +
          18. +
          19. +

            + Let |algorithm| be a new {{KeyAlgorithm}}. +

            +
          20. +
          21. +

            + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`Ed448`". +

            +
          22. +
          23. +

            + Set the [[\algorithm]] + internal slot of |key| to |algorithm|. +

            +
          24. +
          +
          +
          If |format| is {{KeyFormat/"jwk"}}:
          +
          +
            +
          1. +
            +
            If |keyData| is a {{JsonWebKey}} dictionary:
            +

            Let |jwk| equal |keyData|.

            +
            Otherwise:
            +

            [= exception/Throw =] a {{DataError}}.

            +
            +
          2. +
          3. +

            + If the {{JsonWebKey/d}} field is present and |usages| contains + a value which is not + "`sign`", or, + if the {{JsonWebKey/d}} field is not present and |usages| contains + a value which is not + "`verify`" + then [= exception/throw =] a + {{SyntaxError}}. +

            +
          4. +
          5. +

            + If the {{JsonWebKey/kty}} field of |jwk| is not + "`OKP`", + then [= exception/throw =] a + {{DataError}}. +

            +
          6. +
          7. +

            + If the {{JsonWebKey/crv}} field of |jwk| is not + "`Ed448`", + then [= exception/throw =] a + {{DataError}}. +

            +
          8. +
          9. +

            + If the {{JsonWebKey/alg}} field of |jwk| is present and is + not "`Ed448`" or "`EdDSA`", + then [= exception/throw =] a + {{DataError}}. +

            +
          10. +
          11. +

            + If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present and is + not "`sig`", + then [= exception/throw =] a + {{DataError}}. +

            +
          12. +
          13. +

            + If the {{JsonWebKey/key_ops}} field of |jwk| is present, and + is invalid according to the requirements of JSON Web + Key [[JWK]], or it does not contain all of the specified |usages| + values, + then [= exception/throw =] a + {{DataError}}. +

            +
          14. +
          15. +

            + If the {{JsonWebKey/ext}} field of |jwk| is present and + has the value false and |extractable| is true, + then [= exception/throw =] a + {{DataError}}. +

            +
          16. +
          17. +
            +
            If the {{JsonWebKey/d}} field is present:
            +
            +
              +
            1. +

              + If |jwk| does not meet the requirements of + the JWK private key format described in Section 2 + of [[RFC8037]], then [= exception/throw =] a {{DataError}}. +

              +
            2. +
            3. +

              + Let |key| be a new {{CryptoKey}} object that represents the + Ed448 private key identified by interpreting + |jwk| according to Section 2 of [[RFC8037]]. +

              +
            4. +
            5. +

              + Set the [[\type]] + internal slot of |Key| to {{KeyType/"private"}}. +

              +
            6. +
            +
            +
            Otherwise:
            +
            +
              +
            1. +

              + If |jwk| does not meet the requirements of + the JWK public key format described in Section 2 + of [[RFC8037]], then [= exception/throw =] a {{DataError}}. +

              +
            2. +
            3. +

              + Let |key| be a new {{CryptoKey}} object that represents the + Ed448 public key identified by interpreting + |jwk| according to Section 2 of [[RFC8037]]. +

              +
            4. +
            5. +

              + Set the [[\type]] + internal slot of |Key| to {{KeyType/"public"}}. +

              +
            6. +
            +
            +
            +
          18. +
          19. +

            + Let |algorithm| be a new instance of a {{KeyAlgorithm}} object. +

            +
          20. +
          21. +

            + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`Ed448`". +

            +
          22. +
          23. +

            + Set the [[\algorithm]] + internal slot of |key| to |algorithm|. +

            +
          24. +
          +
          +
          If |format| is {{KeyFormat/"raw"}}:
          +
          +
            +
          1. +

            + If |usages| contains a value which is not + "`verify`" + then [= exception/throw =] a + {{SyntaxError}}. +

            +
          2. +
          3. +

            + Let |data| be |keyData|. +

            +
          4. +
          5. +

            + If the length in bits of |data| is not 448 then [= exception/throw =] a {{DataError}}. +

            +
          6. +
          7. +

            + Let |algorithm| be a new {{KeyAlgorithm}} object. +

            +
          8. +
          9. +

            + Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`Ed448`". +

            +
          10. +
          11. +

            + Let |key| be a new {{CryptoKey}} associated with the + [= relevant global object =] + of `this` [[HTML]], and that represents |data|. +

            +
          12. +
          13. +

            + Set the [[\type]] internal slot + of |key| to "`public`" +

            +
          14. +
          15. +

            + Set the [[\algorithm]] + internal slot of |key| to |algorithm|. +

            +
          16. +
          +
          +
          Otherwise:
          +
          +

          + [= exception/throw =] a + {{NotSupportedError}}. +

          +
          +
          +
        4. +
        5. +

          + Return |key| +

          +
        6. +
        +
        +
        +
        Export Key
        +
          +
        1. +

          + Let |key| be the {{CryptoKey}} to be + exported. +

          +
        2. +
        3. +

          + If the underlying cryptographic key material represented by the [[\handle]] internal slot of |key| + cannot be accessed, then [= exception/throw =] an {{OperationError}}. +

          +
        4. +
        5. +
          +
          If |format| is {{KeyFormat/"spki"}}:
          +
          +
            +
          1. +

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

            +
          2. +
          3. +

            + Let |data| be an instance of the `subjectPublicKeyInfo` + ASN.1 structure defined in [[RFC5280]] + with the following properties: +

            +
              +
            • +

              + Set the |algorithm| field to an + `AlgorithmIdentifier` ASN.1 type with the following + properties: +

              +
                +
              • +

                + Set the |algorithm| object identifier to the + `id-Ed448` OID defined in [[RFC8410]]. +

                +
              • +
              +
            • +
            • +

              + Set the |subjectPublicKey| field to |keyData|. +

              +
            • +
            +
          4. +
          5. +

            + Let |result| be a new {{ArrayBuffer}} associated with the + [= relevant global object =] + of `this` [[HTML]], and containing + |data|. +

            +
          6. +
          +
          +
          If |format| is {{KeyFormat/"pkcs8"}}:
          +
          +
            +
          1. +

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

            +
          2. +
          3. +

            + Let |data| be an instance of the `privateKeyInfo` + ASN.1 structure defined in [[RFC5208]] + with the following properties: +

            +
              +
            • +

              + Set the |version| field to `0`. +

              +
            • +
            • +

              + Set the |privateKeyAlgorithm| field to a + `PrivateKeyAlgorithmIdentifier` ASN.1 type with the + following properties: +

              +
                +
              • +

                + Set the |algorithm| object identifier to the + `id-Ed448` OID defined in [[RFC8410]]. +

                +
              • +
              +
            • +
            • +

              + Set the |privateKey| field to the result of DER-encoding + a `CurvePrivateKey` ASN.1 type, as defined in Section 7 of [[RFC8410]], that represents the + Ed448 private key represented by the [[\handle]] internal slot of + |key| +

              +
            • +
            +
          4. +
          5. +

            + Let |result| be a new {{ArrayBuffer}} associated with the + [= relevant global object =] + of `this` [[HTML]], and containing + |data|. +

            +
          6. +
          +
          +
          If |format| is {{KeyFormat/"jwk"}}:
          +
          +
            +
          1. +

            + Let |jwk| be a new {{JsonWebKey}} + dictionary. +

            +
          2. +
          3. +

            + Set the `kty` attribute of |jwk| to + "`OKP`". +

            +
          4. +
          5. +

            + Set the `alg` attribute of |jwk| to + "`Ed448`". +

            +
          6. +
          7. +

            + Set the `crv` attribute of |jwk| to + "`Ed448`". +

            +
          8. +
          9. +

            + Set the {{JsonWebKey/x}} attribute of |jwk| according to the + definition in Section 2 of [[RFC8037]]. +

            +
          10. +
          11. +
            +
            + If the [[\type]] internal slot + of |key| is {{KeyType/"private"}} +
            +
            + Set the {{JsonWebKey/d}} attribute of |jwk| according to the definition in Section 2 of [[RFC8037]]. -

            -
          12. -
          13. -
            -
            - If the [[\type]] internal slot - of |key| is {{KeyType/"private"}} -
            -
            - Set the {{JsonWebKey/d}} attribute of |jwk| according to the - definition in Section 2 of [[RFC8037]]. -
            -
            -
          14. -
          15. -

            - Set the `key_ops` attribute of |jwk| to the {{CryptoKey/usages}} attribute of |key|. -

            -
          16. -
          17. -

            - Set the `ext` attribute of |jwk| to the [[\extractable]] internal slot - of |key|. -

            -
          18. -
          19. -

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

            -
          20. -
          -
          -
          - If |format| is {{KeyFormat/"raw"}}: -
          -
          -
            -
          1. -

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

            -
          2. -
          3. -

            - Let |data| be an octet string - representing the Ed448 public key represented by the [[\handle]] - internal slot of |key|. -

            -
          4. -
          5. -

            - Let |result| be a new {{ArrayBuffer}} associated with the - [= relevant global object =] - of `this` [[HTML]], and containing - |data|. -

            -
          6. -
          -
          -
          Otherwise:
          -
          -

          - [= exception/throw =] a - {{NotSupportedError}}. -

          -
          -
          -
        6. -
        7. -

          - Return |result|. -

          -
        8. -
        -
      -
      +
    +
    + +
  • +

    + Set the `key_ops` attribute of |jwk| to the {{CryptoKey/usages}} attribute of |key|. +

    +
  • +
  • +

    + Set the `ext` attribute of |jwk| to the [[\extractable]] internal slot + of |key|. +

    +
  • +
  • +

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

    +
  • + + +
    + If |format| is {{KeyFormat/"raw"}}: +
    +
    +
      +
    1. +

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

      +
    2. +
    3. +

      + Let |data| be an octet string + representing the Ed448 public key represented by the [[\handle]] + internal slot of |key|. +

      +
    4. +
    5. +

      + Let |result| be a new {{ArrayBuffer}} associated with the + [= relevant global object =] + of `this` [[HTML]], and containing + |data|. +

      +
    6. +
    +
    +
    Otherwise:
    +
    +

    + [= exception/throw =] a + {{NotSupportedError}}. +

    +
    + + +
  • +

    + Return |result|. +

    +
  • + +

    Usage Example

    - This example generates two X25519 key pairs, one for Alice and one for Bob, performs + This example generates two X448 key pairs, one for Alice and one for Bob, performs a key agreement between them, derives a 256-bit AES-GCM key from the result using HKDF with SHA-256, and encrypts and decrypts some data with it.

    -
    +    
           // Generate a key pair for Alice.
    -      const alice_x25519_key = await crypto.subtle.generateKey('X25519', false /* extractable */, ['deriveKey']);
    -      const alice_private_key = alice_x25519_key.privateKey;
    +      const alice_x448_key = await crypto.subtle.generateKey('X448', false /* extractable */, ['deriveKey']);
    +      const alice_private_key = alice_x448_key.privateKey;
     
           // Normally, the public key would be sent by Bob to Alice in advance over some authenticated channel.
           // In this example, we'll generate another key pair and use its public key instead.
    -      const bob_x25519_key = await crypto.subtle.generateKey('X25519', false /* extractable */, ['deriveKey']);
    -      const bob_public_key = bob_x25519_key.publicKey;
    +      const bob_x448_key = await crypto.subtle.generateKey('X448', false /* extractable */, ['deriveKey']);
    +      const bob_public_key = bob_x448_key.publicKey;
     
           // Perform the key agreement.
    -      const alice_x25519_params = { name: 'X25519', public: bob_public_key };
    -      const alice_shared_key = await crypto.subtle.deriveKey(alice_x25519_params, alice_private_key, 'HKDF', false /* extractable */, ['deriveKey']);
    +      const alice_x448_params = { name: 'X448', public: bob_public_key };
    +      const alice_shared_key = await crypto.subtle.deriveKey(alice_x448_params, alice_private_key, 'HKDF', false /* extractable */, ['deriveKey']);
     
           // Derive a symmetric key from the result.
           const salt = crypto.getRandomValues(new Uint8Array(32));
    -      const info = new TextEncoder().encode('X25519 key agreement for an AES-GCM-256 key');
    +      const info = new TextEncoder().encode('X448 key agreement for an AES-GCM-256 key');
           const hkdf_params = { name: 'HKDF', hash: 'SHA-256', salt, info };
           const gcm_params = { name: 'AES-GCM', length: 256 };
           const alice_symmetric_key = await crypto.subtle.deriveKey(hkdf_params, alice_shared_key, gcm_params, false /* extractable */, ['encrypt', 'decrypt']);
    @@ -3650,10 +1893,10 @@ 

    Usage Example

    // On Bob's side, Alice's public key and Bob's private key are used, instead. // To get the same result, Alice and Bob must agree on using the same salt and info. - const alice_public_key = alice_x25519_key.publicKey; - const bob_private_key = bob_x25519_key.privateKey; - const bob_x25519_params = { name: 'X25519', public: alice_public_key }; - const bob_shared_key = await crypto.subtle.deriveKey(bob_x25519_params, bob_private_key, 'HKDF', false /* extractable */, ['deriveKey']); + const alice_public_key = alice_x448_key.publicKey; + const bob_private_key = bob_x448_key.privateKey; + const bob_x448_params = { name: 'X448', public: alice_public_key }; + const bob_shared_key = await crypto.subtle.deriveKey(bob_x448_params, bob_private_key, 'HKDF', false /* extractable */, ['deriveKey']); const bob_symmetric_key = await crypto.subtle.deriveKey(hkdf_params, bob_shared_key, gcm_params, false /* extractable */, ['encrypt', 'decrypt']); // On Bob's side, the data can be decrypted. @@ -3680,19 +1923,6 @@

    Algorithm mappings

    - - - - - - - @@ -3749,16 +1966,6 @@

    Mapping between Algorithm and SubjectPublicKeyInfo

    - - - - - - @@ -3769,16 +1976,6 @@

    Mapping between Algorithm and SubjectPublicKeyInfo

    [[RFC8410]] - - - - - - @@ -3808,16 +2005,6 @@

    Mapping between Algorithm and PKCS#8 PrivateKeyInfo

    - - - - - - @@ -3828,16 +2015,6 @@

    Mapping between Algorithm and PKCS#8 PrivateKeyInfo

    [[RFC8410]] - - - - - -
    OperationParametersResultOperationParametersResult
    -{ kty: "OKP",
    -  crv: "X25519" }
    -
    -
    -
    -{ name: "X25519" }
    -
    -
    -
     { kty: "OKP",
       crv: "X448" }
     
    @@ -3700,19 +1930,6 @@

    Algorithm mappings

     { name: "X448" }
    -
    -
    -
    -{ kty: "OKP",
    -  crv: "Ed25519",
    -  alg: "Ed25519" }
    -
    -
    -
    -{ name: "Ed25519" }
     
    id-X25519 (1.3.101.110)BIT STRING - "`X25519`" - - [[RFC8410]] -
    id-X448 (1.3.101.111) BIT STRING
    id-Ed25519 (1.3.101.112)BIT STRING - "`Ed25519`" - - [[RFC8410]] -
    id-Ed448 (1.3.101.113) BIT STRING
    id-X25519 (1.3.101.110)CurvePrivateKey - "`X25519`" - - [[RFC8410]] -
    id-X448 (1.3.101.111) CurvePrivateKey
    id-Ed25519 (1.3.101.112)CurvePrivateKey - "`Ed25519`" - - [[RFC8410]] -
    id-Ed448 (1.3.101.113) CurvePrivateKey