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]].
+ Note: This introduction does not reflect the fact that Curve25519 has already been + added to [[[webcrypto | Web Cryptography API]]]. +
- 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.
- The "`X25519`" algorithm identifier is used to perform - key agreement using the X25519 algorithm specified in - [[RFC7748]]. -
-- The recognized algorithm name - for this algorithm is "`X25519`". -
-| Operation | -Parameters | -Result | -
|---|---|---|
| deriveBits | -{{EcdhKeyDeriveParams}} | -octet string | -
| generateKey | -None | -{{CryptoKeyPair}} | -
| importKey | -None | -{{CryptoKey}} | -
| exportKey | -None | -object | -
- If the [[\type]] internal slot of - |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. -
-- Let |publicKey| be the - {{EcdhKeyDeriveParams/public}} member of - |normalizedAlgorithm|. -
-- If the [[\type]] internal slot of - |publicKey| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. -
-- 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}}. -
-- 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|. -
-- 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. -
-- If |usages| contains an entry which is not - "`deriveKey`" or "`deriveBits`" - then [= exception/throw =] a - {{SyntaxError}}. -
-- 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. -
-- Let |algorithm| be a new {{KeyAlgorithm}} object. -
-- Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`X25519`". -
-- 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. -
-- Set the [[\type]] internal slot of - |publicKey| to "`public`" -
-- Set the [[\algorithm]] internal - slot of |publicKey| to |algorithm|. -
-- Set the [[\extractable]] internal - slot of |publicKey| to true. -
-- Set the [[\usages]] internal slot of - |publicKey| to be the empty list. -
-- 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. -
-- Set the [[\type]] internal slot of - |privateKey| to {{KeyType/"private"}} -
-- Set the [[\algorithm]] internal - slot of |privateKey| to |algorithm|. -
-- Set the [[\extractable]] internal - slot of |privateKey| to |extractable|. -
-- Set the [[\usages]] internal slot of - |privateKey| to be the - usage intersection of - |usages| and `[ "deriveKey", "deriveBits" ]`. -
-- Let |result| be a new {{CryptoKeyPair}} - dictionary. -
-- Set the {{CryptoKeyPair/publicKey}} attribute - of |result| to be |publicKey|. -
-- Set the {{CryptoKeyPair/privateKey}} attribute - of |result| to be |privateKey|. -
-- Return the result of converting |result| to an ECMAScript Object, as - defined by [[WebIDL]]. -
-Let |keyData| be the key data to be imported.
-- If |usages| is not empty - then [= exception/throw =] a - {{SyntaxError}}. -
-- Let |spki| be the result of running the - parse a subjectPublicKeyInfo - algorithm over |keyData|. -
-- If an error occurred while parsing, - then [= exception/throw =] a - {{DataError}}. -
-- 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}}. -
-- If the `parameters` field of the `algorithm` - AlgorithmIdentifier field of |spki| is present, - then [= exception/throw =] a - {{DataError}}. -
-- Let |publicKey| be the X25519 public key identified by - the `subjectPublicKey` field of |spki|. -
-- Let |key| be a new {{CryptoKey}} associated with the - [= relevant global object =] - of `this` [[HTML]], and - that represents |publicKey|. -
-- Set the [[\type]] internal slot - of |key| to "`public`" -
-- Let |algorithm| be a new {{KeyAlgorithm}}. -
-- Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`X25519`". -
-- Set the [[\algorithm]] - internal slot of |key| to |algorithm|. -
-- If |usages| contains an entry which is not - "`deriveKey`" or "`deriveBits`" - then [= exception/throw =] a - {{SyntaxError}}. -
-- Let |privateKeyInfo| be the result of running the - parse a privateKeyInfo - algorithm over |keyData|. -
-- If an error occurs while parsing, - then [= exception/throw =] a - {{DataError}}. -
-- 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}}. -
-- If the `parameters` field of the - `privateKeyAlgorithm` PrivateKeyAlgorithmIdentifier field - of |privateKeyInfo| is present, - then [= exception/throw =] a - {{DataError}}. -
-- 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. -
-- If an error occurred while parsing, - then [= exception/throw =] a - {{DataError}}. -
-- 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|. -
-- Set the [[\type]] internal slot - of |key| to {{KeyType/"private"}} -
-- Let |algorithm| be a new {{KeyAlgorithm}}. -
-- Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`X25519`". -
-- Set the [[\algorithm]] - internal slot of |key| to |algorithm|. -
-Let |jwk| equal |keyData|.
[= exception/Throw =] a {{DataError}}.
- If the {{JsonWebKey/d}} field is present and if |usages| - contains an entry which is not - "`deriveKey`" or "`deriveBits`" - then [= exception/throw =] a - {{SyntaxError}}. -
-- If the {{JsonWebKey/d}} field is not present and if |usages| is not - empty - then [= exception/throw =] a - {{SyntaxError}}. -
-- If the {{JsonWebKey/kty}} field of |jwk| is not - "`OKP`", - then [= exception/throw =] a - {{DataError}}. -
-- If the {{JsonWebKey/crv}} field of |jwk| is not - "`X25519`", - then [= exception/throw =] a - {{DataError}}. -
-- 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}}. -
-- 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}}. -
-- If the {{JsonWebKey/ext}} field of |jwk| is present and - has the value false and |extractable| is true, - then [= exception/throw =] a - {{DataError}}. -
-- If |jwk| does not meet the requirements of - the JWK private key format described in Section 2 - of [[RFC8037]], then [= exception/throw =] a {{DataError}}. -
-- Let |key| be a new {{CryptoKey}} object that represents the - X25519 private key identified by interpreting - |jwk| according to Section 2 of [[RFC8037]]. -
-- Set the [[\type]] - internal slot of |Key| to {{KeyType/"private"}}. -
-- If |jwk| does not meet the requirements of - the JWK public key format described in Section 2 - of [[RFC8037]], then [= exception/throw =] a {{DataError}}. -
-- Let |key| be a new {{CryptoKey}} object that represents the - X25519 public key identified by interpreting - |jwk| according to Section 2 of [[RFC8037]]. -
-- Set the [[\type]] - internal slot of |Key| to {{KeyType/"public"}}. -
-- Let |algorithm| be a new instance of a {{KeyAlgorithm}} object. -
-- Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`X25519`". -
-- Set the [[\algorithm]] - internal slot of |key| to |algorithm|. -
-- If |usages| is not empty - then [= exception/throw =] a - {{SyntaxError}}. -
-- Let |data| be |keyData|. -
-- If the length in bits of |data| is not 256 then [= exception/throw =] a {{DataError}}. -
-- Let |algorithm| be a new {{KeyAlgorithm}} object. -
-- Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`X25519`". -
-- Let |key| be a new {{CryptoKey}} associated with the - [= relevant global object =] - of `this` [[HTML]], and that represents |data|. -
-- Set the [[\type]] internal slot - of |key| to "`public`" -
-- Set the [[\algorithm]] - internal slot of |key| to |algorithm|. -
-- [= exception/throw =] a - {{NotSupportedError}}. -
-- Return |key| -
-- Let |key| be the {{CryptoKey}} to be - exported. -
-- If the underlying cryptographic key material represented by the [[\handle]] internal slot of |key| - cannot be accessed, then [= exception/throw =] an {{OperationError}}. -
-- If the [[\type]] internal slot - of |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. -
-- 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|. -
-- Let |result| be a new {{ArrayBuffer}} associated with the - [= relevant global object =] - of `this` [[HTML]], and containing - |data|. -
-- If the [[\type]] internal slot - of |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. -
-- 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| -
-- Let |result| be a new {{ArrayBuffer}} associated with the - [= relevant global object =] - of `this` [[HTML]], and containing - |data|. -
-- Let |jwk| be a new {{JsonWebKey}} - dictionary. -
-- Set the `kty` attribute of |jwk| to - "`OKP`". -
-- Set the `crv` attribute of |jwk| to - "`X25519`". -
-- Set the {{JsonWebKey/x}} attribute of |jwk| according to the - definition in Section 2 of [[RFC8037]]. -
-- 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 the [[\type]] internal slot - of |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. -
-- Let |data| be an octet string representing the X25519 - public key represented by the [[\handle]] internal slot of - |key|. -
-- Let |result| be a new {{ArrayBuffer}} associated with the - [= relevant global object =] - of `this` [[HTML]], and containing - |data|. -
-- [= exception/throw =] a - {{NotSupportedError}}. -
-- Return |result|. -
-- The recognized algorithm name + The recognized algorithm name for this algorithm is "`X448`".
| Operation | -Parameters | -Result | +Operation | +Parameters | +Result | |||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| deriveBits | {{EcdhKeyDeriveParams}} | -octet string | +octet string | |||||||||||||||||||||||||||||||||||||||||||||||||||
| generateKey | @@ -982,1706 +123,814 @@
| Operation | -Parameters | -Result | -
|---|---|---|
| sign | -None | -{{ArrayBuffer}} | -
| verify | -None | -boolean | -
| generateKey | -None | -{{CryptoKeyPair}} | -
| importKey | -None | -{{CryptoKey}} | -
| exportKey | -None | -object | -
- If the [[\type]] internal slot of - |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. -
-- 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]]. -
-- 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. -
-- If the [[\type]] internal slot of - |key| is not {{KeyType/"public"}}, then [= exception/throw =] an {{InvalidAccessError}}. -
-- 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. -
-- 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. -
-- 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|. -
-- Let |result| be a boolean with the value `true` if the signature is valid - and the value `false` otherwise. -
-- Return |result|. -
-- If |usages| contains a value which is not - one of "`sign`" or "`verify`", - then [= exception/throw =] a - {{SyntaxError}}. -
-- Generate an Ed25519 key pair, as defined in [[RFC8032]], section 5.1.5. -
-- Let |algorithm| be a new {{KeyAlgorithm}} object. -
-- Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`Ed25519`". -
-- 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. -
-- Set the [[\type]] internal slot of - |publicKey| to "`public`" -
-- Set the [[\algorithm]] internal - slot of |publicKey| to |algorithm|. -
-- Set the [[\extractable]] internal - slot of |publicKey| to true. -
-- Set the [[\usages]] internal slot of - |publicKey| to be the usage intersection - of |usages| and `[ "verify" ]`. -
-- 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. -
-- Set the [[\type]] internal slot of - |privateKey| to {{KeyType/"private"}} -
-- Set the [[\algorithm]] internal - slot of |privateKey| to |algorithm|. -
-- Set the [[\extractable]] internal - slot of |privateKey| to |extractable|. -
-- Set the [[\usages]] internal slot of - |privateKey| to be the usage intersection - of |usages| and `[ "sign" ]`. -
-- Let |result| be a new {{CryptoKeyPair}} - dictionary. -
-- Set the {{CryptoKeyPair/publicKey}} attribute - of |result| to be |publicKey|. -
-- Set the {{CryptoKeyPair/privateKey}} attribute - of |result| to be |privateKey|. -
-- Return the result of converting |result| to an ECMAScript Object, as - defined by [[WebIDL]]. -
-+ If the [[\type]] internal slot of + |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. +
++ Let |publicKey| be the + {{EcdhKeyDeriveParams/public}} member of + |normalizedAlgorithm|. +
++ If the [[\type]] internal slot of + |publicKey| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. +
++ 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}}. +
++ 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|. +
++ 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. +
++ If |usages| contains an entry which is not + "`deriveKey`" or "`deriveBits`" + then [= exception/throw =] a + {{SyntaxError}}. +
++ 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. +
++ Let |algorithm| be a new {{KeyAlgorithm}} object. +
++ Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`X448`". +
++ 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. +
++ Set the [[\type]] internal slot of + |publicKey| to "`public`" +
++ Set the [[\algorithm]] internal + slot of |publicKey| to |algorithm|. +
++ Set the [[\extractable]] internal + slot of |publicKey| to true. +
++ Set the [[\usages]] internal slot of + |publicKey| to be the empty list. +
++ 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. +
++ Set the [[\type]] internal slot of + |privateKey| to {{KeyType/"private"}} +
++ Set the [[\algorithm]] internal + slot of |privateKey| to |algorithm|. +
++ Set the [[\extractable]] internal + slot of |privateKey| to |extractable|. +
++ Set the [[\usages]] internal slot of + |privateKey| to be the + usage intersection of + |usages| and `[ "deriveKey", "deriveBits" ]`. +
++ Let |result| be a new {{CryptoKeyPair}} + dictionary. +
++ Set the {{CryptoKeyPair/publicKey}} attribute + of |result| to be |publicKey|. +
++ Set the {{CryptoKeyPair/privateKey}} attribute + of |result| to be |privateKey|. +
++ Return the result of converting |result| to an ECMAScript Object, as + defined by [[WebIDL]]. +
+Let |keyData| be the key data to be imported.
-- If |usages| contains a value which is not - "`verify`" - then [= exception/throw =] a - {{SyntaxError}}. -
-- Let |spki| be the result of running the - parse a subjectPublicKeyInfo - algorithm over |keyData|. -
-- If an error occurred while parsing, - then [= exception/throw =] a - {{DataError}}. -
-- 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}}. -
-- If the `parameters` field of the `algorithm` - AlgorithmIdentifier field of |spki| is present, - then [= exception/throw =] a - {{DataError}}. -
-- Let |publicKey| be the Ed25519 public key identified by - the `subjectPublicKey` field of |spki|. -
-- Let |key| be a new {{CryptoKey}} associated with the - [= relevant global object =] - of `this` [[HTML]], and - that represents |publicKey|. -
-- Set the [[\type]] internal slot - of |key| to "`public`" -
-- Let |algorithm| be a new {{KeyAlgorithm}}. -
-- Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`Ed25519`". -
-- Set the [[\algorithm]] - internal slot of |key| to |algorithm|. -
-- If |usages| contains a value which is not - "`sign`" - then [= exception/throw =] a - {{SyntaxError}}. -
-- Let |privateKeyInfo| be the result of running the - parse a privateKeyInfo - algorithm over |keyData|. -
-- If an error occurs while parsing, - then [= exception/throw =] a - {{DataError}}. -
-- 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}}. -
-- If the `parameters` field of the - `privateKeyAlgorithm` PrivateKeyAlgorithmIdentifier field - of |privateKeyInfo| is present, - then [= exception/throw =] a - {{DataError}}. -
-- 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. -
-- If an error occurred while parsing, - then [= exception/throw =] a - {{DataError}}. -
-- 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|. -
-- Set the [[\type]] internal slot - of |key| to {{KeyType/"private"}} -
-- Let |algorithm| be a new {{KeyAlgorithm}}. -
-- Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`Ed25519`". -
-- Set the [[\algorithm]] - internal slot of |key| to |algorithm|. -
-Let |jwk| equal |keyData|.
[= exception/Throw =] a {{DataError}}.
- 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}}. -
-- If the {{JsonWebKey/kty}} field of |jwk| is not - "`OKP`", - then [= exception/throw =] a - {{DataError}}. -
-- If the {{JsonWebKey/crv}} field of |jwk| is not - "`Ed25519`", - then [= exception/throw =] a - {{DataError}}. -
-- If the {{JsonWebKey/alg}} field of |jwk| is present and is - not "`Ed25519`" or "`EdDSA`", - then [= exception/throw =] a - {{DataError}}. -
-- If |usages| is non-empty and the {{JsonWebKey/use}} field of |jwk| is present and is - not "`sig`", - then [= exception/throw =] a - {{DataError}}. -
-- 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}}. -
-- If the {{JsonWebKey/ext}} field of |jwk| is present and - has the value false and |extractable| is true, - then [= exception/throw =] a - {{DataError}}. -
-- If |jwk| does not meet the requirements of - the JWK private key format described in Section 2 - of [[RFC8037]], then [= exception/throw =] a {{DataError}}. -
-- Let |key| be a new {{CryptoKey}} object that represents the - Ed25519 private key identified by interpreting - |jwk| according to Section 2 of [[RFC8037]]. -
-- Set the [[\type]] - internal slot of |Key| to {{KeyType/"private"}}. -
-- If |jwk| does not meet the requirements of - the JWK public key format described in Section 2 - of [[RFC8037]], then [= exception/throw =] a {{DataError}}. -
-- Let |key| be a new {{CryptoKey}} object that represents the - Ed25519 public key identified by interpreting - |jwk| according to Section 2 of [[RFC8037]]. -
-- Set the [[\type]] - internal slot of |Key| to {{KeyType/"public"}}. -
-- Let |algorithm| be a new instance of a {{KeyAlgorithm}} object. -
-- Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`Ed25519`". -
-- Set the [[\algorithm]] - internal slot of |key| to |algorithm|. -
-- If |usages| contains a value which is not - "`verify`" - then [= exception/throw =] a - {{SyntaxError}}. -
-- Let |data| be |keyData|. -
-- If the length in bits of |data| is not 256 then [= exception/throw =] a {{DataError}}. -
-- Let |algorithm| be a new {{KeyAlgorithm}} object. -
-- Set the {{KeyAlgorithm/name}} attribute of - |algorithm| to "`Ed25519`". -
-- Let |key| be a new {{CryptoKey}} associated with the - [= relevant global object =] - of `this` [[HTML]], and that represents |data|. -
-- Set the [[\type]] internal slot - of |key| to "`public`" -
-- Set the [[\algorithm]] - internal slot of |key| to |algorithm|. -
-- [= exception/throw =] a - {{NotSupportedError}}. -
-- Return |key| -
-Let |keyData| be the key data to be imported.
++ If |usages| is not empty + then [= exception/throw =] a + {{SyntaxError}}. +
++ Let |spki| be the result of running the + parse a subjectPublicKeyInfo + algorithm over |keyData|. +
++ If an error occurred while parsing, + then [= exception/throw =] a + {{DataError}}. +
++ 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}}. +
++ If the `parameters` field of the `algorithm` + AlgorithmIdentifier field of |spki| is present, + then [= exception/throw =] a + {{DataError}}. +
++ Let |publicKey| be the X448 public key identified by + the `subjectPublicKey` field of |spki|. +
++ Let |key| be a new {{CryptoKey}} associated with the + [= relevant global object =] + of `this` [[HTML]], and + that represents |publicKey|. +
++ Set the [[\type]] internal slot + of |key| to "`public`" +
++ Let |algorithm| be a new {{KeyAlgorithm}}. +
++ Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`X448`". +
++ Set the [[\algorithm]] + internal slot of |key| to |algorithm|. +
++ If |usages| contains an entry which is not + "`deriveKey`" or "`deriveBits`" + then [= exception/throw =] a + {{SyntaxError}}. +
++ Let |privateKeyInfo| be the result of running the + parse a privateKeyInfo + algorithm over |keyData|. +
++ If an error occurs while parsing, + then [= exception/throw =] a + {{DataError}}. +
++ 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}}. +
++ If the `parameters` field of the + `privateKeyAlgorithm` PrivateKeyAlgorithmIdentifier field + of |privateKeyInfo| is present, + then [= exception/throw =] a + {{DataError}}. +
++ 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. +
++ If an error occurred while parsing, + then [= exception/throw =] a + {{DataError}}. +
++ 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|. +
++ Set the [[\type]] internal slot + of |key| to {{KeyType/"private"}} +
++ Let |algorithm| be a new {{KeyAlgorithm}}. +
++ Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`X448`". +
++ Set the [[\algorithm]] + internal slot of |key| to |algorithm|. +
+Let |jwk| equal |keyData|.
[= exception/Throw =] a {{DataError}}.
+ If the {{JsonWebKey/d}} field is present and if |usages| + contains an entry which is not + "`deriveKey`" or "`deriveBits`" + then [= exception/throw =] a + {{SyntaxError}}. +
++ If the {{JsonWebKey/d}} field is not present and if |usages| is not + empty + then [= exception/throw =] a + {{SyntaxError}}. +
++ If the {{JsonWebKey/kty}} field of |jwk| is not + "`OKP`", + then [= exception/throw =] a + {{DataError}}. +
++ If the {{JsonWebKey/crv}} field of |jwk| is not + "`X448`", + then [= exception/throw =] a + {{DataError}}. +
++ 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}}. +
++ 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}}. +
++ If the {{JsonWebKey/ext}} field of |jwk| is present and + has the value false and |extractable| is true, + then [= exception/throw =] a + {{DataError}}. +
++ If |jwk| does not meet the requirements of + the JWK private key format described in Section 2 + of [[RFC8037]], then [= exception/throw =] a {{DataError}}. +
++ Let |key| be a new {{CryptoKey}} object that represents the + X448 private key identified by interpreting + |jwk| according to Section 2 of [[RFC8037]]. +
++ Set the [[\type]] + internal slot of |Key| to {{KeyType/"private"}}. +
++ If |jwk| does not meet the requirements of + the JWK public key format described in Section 2 + of [[RFC8037]], then [= exception/throw =] a {{DataError}}. +
++ Let |key| be a new {{CryptoKey}} object that represents the + X448 public key identified by interpreting + |jwk| according to Section 2 of [[RFC8037]]. +
++ Set the [[\type]] + internal slot of |Key| to {{KeyType/"public"}}. +
++ Let |algorithm| be a new instance of a {{KeyAlgorithm}} object. +
++ Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`X448`". +
++ Set the [[\algorithm]] + internal slot of |key| to |algorithm|. +
++ If |usages| is not empty + then [= exception/throw =] a + {{SyntaxError}}. +
++ Let |data| be |keyData|. +
++ If the length in bits of |data| is not 448 then [= exception/throw =] a {{DataError}}. +
++ Let |algorithm| be a new {{KeyAlgorithm}} object. +
++ Set the {{KeyAlgorithm/name}} attribute of + |algorithm| to "`X448`". +
++ Let |key| be a new {{CryptoKey}} associated with the + [= relevant global object =] + of `this` [[HTML]], and that represents |data|. +
++ Set the [[\type]] internal slot + of |key| to "`public`" +
++ Set the [[\algorithm]] + internal slot of |key| to |algorithm|. +
++ [= exception/throw =] a + {{NotSupportedError}}. +
++ Return |key| +
+- Let |key| be the {{CryptoKey}} to be - exported. -
-- If the underlying cryptographic key material represented by the [[\handle]] internal slot of |key| - cannot be accessed, then [= exception/throw =] an {{OperationError}}. -
-- If the [[\type]] internal slot - of |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. -
-- 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|. -
-- Let |result| be a new {{ArrayBuffer}} associated with the - [= relevant global object =] - of `this` [[HTML]], and containing - |data|. -
-- If the [[\type]] internal slot - of |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}. -
-- 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| -
-- Let |result| be a new {{ArrayBuffer}} associated with the - [= relevant global object =] - of `this` [[HTML]], and containing - |data|. -
-- Let |jwk| be a new {{JsonWebKey}} - dictionary. -
-- Set the `kty` attribute of |jwk| to - "`OKP`". -
-- Set the `alg` attribute of |jwk| to - "`Ed25519`". -
-- Set the `crv` attribute of |jwk| to - "`Ed25519`". -
-
- Set the {{JsonWebKey/x}} attribute of |jwk| according to the
+
+ Let |key| be the {{CryptoKey}} to be
+ exported.
+
+ If the underlying cryptographic key material represented by the [[\handle]] internal slot of |key|
+ cannot be accessed, then [= exception/throw =] an {{OperationError}}.
+
+ If the [[\type]] internal slot
+ of |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}.
+
+ 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|.
+
+ Let |result| be a new {{ArrayBuffer}} associated with the
+ [= relevant global object =]
+ of `this` [[HTML]], and containing
+ |data|.
+
+ If the [[\type]] internal slot
+ of |key| is not {{KeyType/"private"}}, then [= exception/throw =] an {{InvalidAccessError}}.
+
+ 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|
+
+ Let |result| be a new {{ArrayBuffer}} associated with the
+ [= relevant global object =]
+ of `this` [[HTML]], and containing
+ |data|.
+
+ Let |jwk| be a new {{JsonWebKey}}
+ dictionary.
+
+ Set the `kty` attribute of |jwk| to
+ "`OKP`".
+
+ Set the `crv` attribute of |jwk| to
+ "`X448`".
+
+ Set the {{JsonWebKey/x}} attribute of |jwk| according to the
+ definition in Section 2 of [[RFC8037]].
+ Export Key
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- 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 the [[\type]] internal slot - of |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. -
-- Let |data| be an octet string representing the Ed25519 - public key represented by the [[\handle]] internal slot of - |key|. -
-- Let |result| be a new {{ArrayBuffer}} associated with the - [= relevant global object =] - of `this` [[HTML]], and containing - |data|. -
-- [= exception/throw =] a - {{NotSupportedError}}. -
-- Return |result|. -
-+ 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 the [[\type]] internal slot + of |key| is not "`public`", then [= exception/throw =] an {{InvalidAccessError}}. +
++ Let |data| be an octet string representing the X448 + public key represented by the [[\handle]] internal slot of + |key|. +
++ Let |result| be a new {{ArrayBuffer}} associated with the + [= relevant global object =] + of `this` [[HTML]], and containing + |data|. +
++ [= exception/throw =] a + {{NotSupportedError}}. +
++ Return |result|. +
+- The recognized algorithm name + The recognized algorithm name for this algorithm is "`Ed448`".
| Operation | -Parameters | -Result | +Operation | +Parameters | +Result |
|---|---|---|---|---|---|
-{ 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" }
|
@@ -3749,16 +1966,6 @@ ||
| id-X25519 (1.3.101.110) | -BIT STRING | -- "`X25519`" - | -- [[RFC8410]] - | -||
| id-X448 (1.3.101.111) | BIT STRING | @@ -3769,16 +1976,6 @@||||
| id-Ed25519 (1.3.101.112) | -BIT STRING | -- "`Ed25519`" - | -- [[RFC8410]] - | -||
| id-Ed448 (1.3.101.113) | BIT STRING | @@ -3808,16 +2005,6 @@||||
| id-X25519 (1.3.101.110) | -CurvePrivateKey | -- "`X25519`" - | -- [[RFC8410]] - | -||
| id-X448 (1.3.101.111) | CurvePrivateKey | @@ -3828,16 +2015,6 @@||||
| id-Ed25519 (1.3.101.112) | -CurvePrivateKey | -- "`Ed25519`" - | -- [[RFC8410]] - | -||
| id-Ed448 (1.3.101.113) | CurvePrivateKey |