From 1bd19938479bb488122ee69e46d0d48d8274049a Mon Sep 17 00:00:00 2001 From: Manu Sporny Date: Sun, 2 Feb 2025 18:31:00 -0500 Subject: [PATCH] Add static snapshot for Proposed Recommendation. --- transitions/2025/PR/index.html | 4275 ++++++++++++++++++++++++++++++++ 1 file changed, 4275 insertions(+) create mode 100644 transitions/2025/PR/index.html diff --git a/transitions/2025/PR/index.html b/transitions/2025/PR/index.html new file mode 100644 index 0000000..4f6e5fb --- /dev/null +++ b/transitions/2025/PR/index.html @@ -0,0 +1,4275 @@ + + + + + + + +Data Integrity EdDSA Cryptosuites v1.0 + + + + + + + + + + + + + + + + +
+

+

Data Integrity EdDSA Cryptosuites v1.0

Achieving Data Integrity using EdDSA with Edwards curves

+

W3C Proposed Recommendation

+
+ More details about this document +
+
This version:
+ https://www.w3.org/TR/2025/PR-vc-di-eddsa-20250306/ +
+
Latest published version:
+ https://www.w3.org/TR/vc-di-eddsa/ +
+
Latest editor's draft:
https://w3c.github.io/vc-di-eddsa/
+
History:
+ https://www.w3.org/standards/history/vc-di-eddsa/ +
+ Commit history +
+ +
Implementation report:
+ https://w3c.github.io/vc-di-eddsa-test-suite/ +
+ + + +
Editors:
+ Manu Sporny (Digital Bazaar) +
+ Greg Bernstein (Invited Expert) +
+ Ted Thibodeau Jr (OpenLink Software) (v2.0) +
+ Dmitri Zagidulin (MIT Digital Credentials Consortium) +
+ Sebastian Crane (Invited Expert) +
+ +
Authors:
+ Dave Longley (Digital Bazaar) +
+ Manu Sporny (Digital Bazaar) +
+ Greg Bernstein (Invited Expert) +
+
Feedback:
+ GitHub w3c/vc-di-eddsa + (pull requests, + new issue, + open issues) +
+ +
Related Specifications
+ Verifiable Credentials Data Model v2.0 +
+ Verifiable Credential Data Integrity v1.0 +
+ Controller Documents v1.0 +
+ Data Integrity ECDSA Cryptosuites v1.0 +
+ Data Integrity BBS Cryptosuites v1.0 +
+
+
+ + + +
+
+

Abstract

+

+This specification describes Data Integrity cryptographic suites for use when +creating or verifying a digital signature using the the Ed25519 instantiation +of the Edwards-Curve Digital Signature Algorithm (EdDSA). +

+
+ +

Status of This Document

This section describes the status of this + document at the time of its publication. A list of current W3C + publications and the latest revision of this technical report can be found + in the W3C technical reports index at + https://www.w3.org/TR/.

+

+ This document was published by the Verifiable Credentials Working Group as + a Proposed Recommendation using the + Recommendation track. +

Publication as a Proposed Recommendation does not + imply endorsement by W3C and its Members.

+ This is a draft document and may be updated, replaced or obsoleted by other + documents at any time. It is inappropriate to cite this document as other + than work in progress. + +

+ The W3C Membership and other interested parties are invited to review + the document and send comments through 03 April 2025. + Advisory Committee Representatives should consult their + WBS questionnaires. Note that substantive technical comments were expected during the + Candidate Recommendation review period that ended + 19 January 2024. +

+ + This document was produced by a group + operating under the + W3C Patent + Policy. + + + W3C maintains a + public list of any patent disclosures + made in connection with the deliverables of + the group; that page also includes + instructions for disclosing a patent. An individual who has actual + knowledge of a patent which the individual believes contains + Essential Claim(s) + must disclose the information in accordance with + section 6 of the W3C Patent Policy. + +

+ This document is governed by the + 03 November 2023 W3C Process Document. +

+ +

1. Introduction

+ +

+This specification defines a cryptographic suite for the purpose of creating, +verifying proofs for Ed25519 EdDSA signatures in conformance with the +Data Integrity [VC-DATA-INTEGRITY] specification. The approach is +accepted by the U.S. National Institute of Standards in the latest [FIPS-186-5] +publication and meets U.S. Federal Information Processing requirements when +using cryptography to secure digital information. +

+

+The suites described in this specification use the RDF Dataset Canonicalization +Algorithm [RDF-CANON] or the JSON Canonicalization Scheme [RFC8785] to +transform an input document into its canonical form. The canonical +representation is then hashed and signed with a detached signature algorithm. +

+ +

1.1 Terminology

+ + +

+Terminology used throughout this document is defined in the +Terminology section of the +Verifiable Credential Data Integrity 1.0 specification. +

+ +
+ +

1.2 Conformance

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

+ The key words MAY, MUST, MUST NOT, and SHOULD in this document + are to be interpreted as described in + BCP 14 + [RFC2119] [RFC8174] + when, and only when, they appear in all capitals, as shown here. +

+

+A conforming proof is any concrete expression of the data model +that complies with the normative statements in this specification. Specifically, +all relevant normative statements in Sections +2. Data Model and 3. Algorithms +of this document MUST be enforced. +

+ +

+A conforming processor is any algorithm realized +as software and/or hardware that generates or consumes a +conforming proof. Conforming processors MUST produce errors when +non-conforming documents are consumed. +

+

+This document contains examples of JSON and JSON-LD data. Some of these examples +are invalid JSON, as they include features such as inline comments (//) +explaining certain portions and ellipses (...) indicating the omission of +information that is irrelevant to the example. These parts would have to be +removed in order to treat the examples as valid JSON or JSON-LD. +

+
+ +
+ +

2. Data Model

+ + +

+The following sections outline the data model that is used by this specification +to express verification methods, such as cryptographic public keys, and +data integrity proofs, such as digital signatures. +

+ +

2.1 Verification Methods

+ + +

+This cryptographic suite is used to verify Data Integrity Proofs +[VC-DATA-INTEGRITY] produced using Edwards Curve cryptographic key material. +The encoding formats for those key types are provided in this section. Lossless +cryptographic key transformation processes that result in equivalent +cryptographic key material MAY be used for the processing of digital +signatures. +

+ +

2.1.1 Multikey

+ + +

+The Multikey format, defined in +Controlled Identifiers (CIDs) v1.0, is used to express public keys for the cryptographic +suites defined in this specification. +

+ +

+The publicKeyMultibase value of the verification method MUST start with the +base-58-btc prefix (z), as defined in the +Multibase section of +Controlled Identifiers (CIDs) v1.0. A Multibase-encoded Ed25519 256-bit public key value +follows, as defined in the +Multikey section of +Controlled Identifiers (CIDs) v1.0. Any other encoding MUST NOT be allowed. +

+ +

+Developers are advised to not accidentally publish a representation of a private +key. Implementations of this specification will raise errors if they encounter a +Multikey prefix value other than 0xed01 in a publicKeyMultibase value. +

+ +
+
+ Example 1: An Ed25519 public key encoded as a Multikey +
{
+  "id": "https://example.com/issuer/123#key-0",
+  "type": "Multikey",
+  "controller": "https://example.com/issuer/123",
+  "publicKeyMultibase": "z6Mkf5rGMoatrSj1f4CyvuHBeXJELe9RPdzo2PKGNCKVtZxP"
+}
+
+ +
+
+ Example 2: An Ed25519 public key encoded as a + Multikey in a controller document +
{
+  "@context": [
+    "https://www.w3.org/ns/did/v1",
+    "https://w3id.org/security/multikey/v1"
+  ],
+  "id": "did:example:123",
+  "verificationMethod": [{
+    "id": "did:example:123#key-0",
+    "type": "Multikey",
+    "controller": "did:example:123",
+    "publicKeyMultibase": "z6Mkf5rGMoatrSj1f4CyvuHBeXJELe9RPdzo2PKGNCKVtZxP"
+  }],
+  "authentication": [
+    "did:example:123#key-0"
+  ],
+  "assertionMethod": [
+    "did:example:123#key-0"
+  ],
+  "capabilityDelegation": [
+    "did:example:123#key-0"
+  ],
+  "capabilityInvocation": [
+    "did:example:123#key-0"
+  ]
+}
+
+ +

+The secretKeyMultibase value of the verification method MUST start with the +base-58-btc prefix (z), as defined in the +Multibase section of +Controlled Identifiers (CIDs) v1.0. A Multibase-encoded Ed25519 256-bit secret key value +follows, as defined in the +Multikey section of +Controlled Identifiers (CIDs) v1.0. Any other encoding MUST NOT be allowed. +

+ +

+Developers are advised to prevent accidental publication of a representation of +a secret key, and to not export the secretKeyMultibase property by default, +when serializing key pairs to Multikey. +

+ +
+ +
+ +

2.2 Proof Representations

+ + +

+This section details the proof representation formats that are defined by +this specification. +

+ +

2.2.1 DataIntegrityProof

+ + +

+A proof contains the attributes specified in the +Proofs section +of [VC-DATA-INTEGRITY] with the following restrictions. +

+

+The type property MUST be DataIntegrityProof. +

+

+The cryptosuite property of the proof MUST be eddsa-rdfc-2022 or eddsa-jcs-2022. +

+

+The proofValue property of the proof MUST be a detached EdDSA signature +produced according to [RFC8032], encoded using the base-58-btc header and +alphabet as described in the +Multibase section of +Controlled Identifiers (CIDs) v1.0. +

+ +
+
+ Example 3: An Ed25519 digital signature expressed as a + DataIntegrityProof +
{
+  "@context": [
+    {"myWebsite": "https://vocabulary.example/myWebsite"},
+    "https://www.w3.org/ns/credentials/v2"
+  ],
+  "myWebsite": "https://hello.world.example/",
+  "proof": {
+    "type": "DataIntegrityProof",
+    "cryptosuite": "eddsa-rdfc-2022",
+    "created": "2023-02-24T23:36:38Z",
+    "verificationMethod": "https://vc.example/issuers/5678#z6MkrJVnaZkeFzdQyMZu1
+      cgjg7k1pZZ6pvBQ7XJPt4swbTQ2",
+    "proofPurpose": "assertionMethod",
+    "proofValue": "z5C5b1uzYJN6pDR3aWgAqUMoSB1JY29epA74qyjaie9qh4okm9DZP6y77eTNq
+      5NfYyMwNu9bpQQWUHKH5zAmEtszK"
+  }
+}
+
+ +
+ +
+
+ +

3. Algorithms

+ + +

+The following section describes multiple Data Integrity cryptographic suites +that use the Edwards-Curve Digital Signature Algorithm. +

+ +

3.1 Instantiate Cryptosuite

+ + +

+This algorithm is used to configure a cryptographic suite to be used by the +Add Proof and +Verify Proof +functions in Verifiable Credential Data Integrity 1.0. The algorithm takes an options object +(map options) as input and returns a cryptosuite instance (struct cryptosuite). +

+ +
    +
  1. +Initialize cryptosuite to an empty struct. +
  2. +
  3. +If options.type does not equal DataIntegrityProof, return cryptosuite. +
  4. +
  5. +If options.cryptosuite is eddsa-rdfc-2022: +
      +
    1. +Set cryptosuite.createProof to the algorithm in Section +3.2.1 Create Proof (eddsa-rdfc-2022). +
    2. +
    3. +Set cryptosuite.verifyProof to the algorithm in Section +3.2.2 Verify Proof (eddsa-rdfc-2022). +
    4. +
    +
  6. +
  7. +If options.cryptosuite is eddsa-jcs-2022: +
      +
    1. +Set cryptosuite.createProof to the algorithm in Section +3.3.1 Create Proof (eddsa-jcs-2022). +
    2. +
    3. +Set cryptosuite.verifyProof to the algorithm in Section +3.3.2 Verify Proof (eddsa-jcs-2022). +
    4. +
    +
  8. +
  9. +Return cryptosuite. +
  10. +
+ +
+ +

3.2 eddsa-rdfc-2022

+ + +

+The eddsa-rdfc-2022 cryptographic suite takes an input document, canonicalizes +the document using the RDF Dataset Canonicalization algorithm [RDF-CANON], and then +cryptographically hashes and signs the output +resulting in the production of a data integrity proof. The algorithms in this +section also include the verification of such a data integrity proof. +

+ +

+When the RDF Dataset Canonicalization Algorithm [RDF-CANON] is used, +implementations will detect +dataset poisoning by default, and abort processing upon such detection. +

+ +

3.2.1 Create Proof (eddsa-rdfc-2022)

+ + +

+The following algorithm specifies how to create a data integrity proof given +an unsecured data document. Required inputs are an +unsecured data document (map unsecuredDocument), and a set of proof +options (map options). A data integrity proof (map), or an error, +is produced as output. +

+ +
    +
  1. +Let proof be a clone of the proof options, options. +
  2. +
  3. +Let proofConfig be the result of running the algorithm in +Section 3.2.5 Proof Configuration (eddsa-rdfc-2022) with +options passed as a parameter. +
  4. +
  5. +Let transformedData be the result of running the algorithm in Section 3.2.3 Transformation (eddsa-rdfc-2022) with unsecuredDocument, +proofConfig, and options passed as parameters. +
  6. +
  7. +Let hashData be the result of running the algorithm in Section +3.2.4 Hashing (eddsa-rdfc-2022) with transformedData and proofConfig +passed as a parameters. +
  8. +
  9. +Let proofBytes be the result of running the algorithm in Section +3.2.6 Proof Serialization (eddsa-rdfc-2022) with hashData and +options passed as parameters. +
  10. +
  11. +Let proof.proofValue be a +base58-btc-encoded Multibase value of the proofBytes. +
  12. +
  13. +Return proof as the data integrity proof. +
  14. +
+ +
+ +

3.2.2 Verify Proof (eddsa-rdfc-2022)

+ + +

+The following algorithm specifies how to verify a data integrity proof given +an secured data document. Required inputs are an +secured data document (map securedDocument). This algorithm returns +a verification result, which is a struct whose +items are: +

+
+
verified
+
true or false
+
verifiedDocument
+
+if verified is false, Null; +otherwise, an unsecured data document +
+
+ +
    +
  1. +Let unsecuredDocument be a copy of securedDocument with +the proof value removed. +
  2. +
  3. +Let proofOptions be the result of a copy of securedDocument.proof with proofValue +removed. +
  4. +
  5. +Let proofBytes be the +Multibase decoded base58-btc +value in securedDocument.proof.proofValue. +
  6. +
  7. +Let transformedData be the result of running the algorithm in Section 3.2.3 Transformation (eddsa-rdfc-2022) with unsecuredDocument and +proofOptions passed as parameters. +
  8. +
  9. +Let proofConfig be the result of running the algorithm in Section 3.2.5 Proof Configuration (eddsa-rdfc-2022) with unsecuredDocument and +proofOptions passed as parameters. +
  10. +
  11. +Let hashData be the result of running the algorithm in Section +3.2.4 Hashing (eddsa-rdfc-2022) with transformedData and proofConfig +passed as a parameters. +
  12. +
  13. +Let verified be the result of running the algorithm in Section +3.2.7 Proof Verification (eddsa-rdfc-2022) algorithm on hashData, +proofBytes, and proofConfig. +
  14. +
  15. +Return a verification result with items: +
    +
    verified
    +
    verified
    +
    verifiedDocument
    +
    +if verified is true, unsecuredDocument; +otherwise, Null
    +
    +
  16. +
+ +
+ +

3.2.3 Transformation (eddsa-rdfc-2022)

+ + +

+The following algorithm specifies how to transform an unsecured input document +into a transformed document that is ready to be provided as input to the +hashing algorithm in Section 3.2.4 Hashing (eddsa-rdfc-2022). +

+ +

+Required inputs to this algorithm are an + +unsecured data document (unsecuredDocument) and +transformation options (options). The +transformation options MUST contain a type identifier for the + +cryptographic suite (type) and a cryptosuite +identifier (cryptosuite). A transformed data document is +produced as output. Whenever this algorithm encodes strings, it MUST use UTF-8 +encoding. +

+ +
    +
  1. +If options.type is not set to the string +DataIntegrityProof and options.cryptosuite is not +set to the string eddsa-rdfc-2022, +an error MUST be raised that SHOULD convey an error type of +PROOF_TRANSFORMATION_ERROR. +
  2. +
  3. +Let canonicalDocument be the result of converting unsecuredDocument + +to RDF statements, applying the RDF Dataset Canonicalization +Algorithm [RDF-CANON] to the result, and then serializing the result to a +serialized canonical form [RDF-CANON]. +
  4. +
  5. +Return canonicalDocument as the transformed data document. +
  6. +
+
+ +

3.2.4 Hashing (eddsa-rdfc-2022)

+ + +

+The following algorithm specifies how to cryptographically hash a +transformed data document and proof configuration +into cryptographic hash data that is ready to be provided as input to the +algorithms in Section 3.2.6 Proof Serialization (eddsa-rdfc-2022) or +Section 3.2.7 Proof Verification (eddsa-rdfc-2022). +

+ +

+The required inputs to this algorithm are a transformed data document +(transformedDocument) and canonical proof configuration +(canonicalProofConfig). A single hash data value represented as +series of bytes is produced as output. +

+ +
    +
  1. +Let proofConfigHash be the result of applying the +SHA-256 (SHA-2 with 256-bit output) cryptographic hashing algorithm [RFC6234] +to the canonicalProofConfig. proofConfigHash will be +exactly 32 bytes in size. +
  2. +
  3. +Let transformedDocumentHash be the result of applying the +SHA-256 (SHA-2 with 256-bit output) cryptographic hashing algorithm [RFC6234] +to the transformedDocument. transformedDocumentHash will +be exactly 32 bytes in size. +
  4. +
  5. +Let hashData be the result of concatenating proofConfigHash +(the first hash produced above) followed by transformedDocumentHash +(the second hash produced above). +
  6. +
  7. +Return hashData as the hash data. +
  8. +
+ +
+ +

3.2.5 Proof Configuration (eddsa-rdfc-2022)

+ + +

+The following algorithm specifies how to generate a +proof configuration from a set of proof options +that is used as input to the proof hashing algorithm. +

+ +

+The required inputs to this algorithm are the document +(unsecuredDocument) and the proof options +(options). The proof options MUST contain a type identifier +for the + +cryptographic suite (type) and MUST contain a cryptosuite +identifier (cryptosuite). A proof configuration +object is produced as output. +

+
    +
  1. +Let proofConfig be a clone of the options object. +
  2. +
  3. +If proofConfig.type is not set to DataIntegrityProof and/or +proofConfig.cryptosuite is not set to eddsa-rdfc-2022, an +error MUST be raised and SHOULD convey an error type of +PROOF_GENERATION_ERROR. +
  4. +
  5. +If proofConfig.created is present and set to a value that is not a +valid [XMLSCHEMA11-2] datetime, an error MUST be +raised and SHOULD convey an error type of +PROOF_GENERATION_ERROR. +
  6. +
  7. +Set proofConfig.@context to +unsecuredDocument.@context. +
  8. +
  9. +Let canonicalProofConfig be the result of applying the +RDF Dataset Canonicalization Algorithm +[RDF-CANON] to the proofConfig. +
  10. +
  11. +Return canonicalProofConfig. +
  12. +
+ +
+ +

3.2.6 Proof Serialization (eddsa-rdfc-2022)

+ + +

+The following algorithm specifies how to serialize a digital signature from +a set of cryptographic hash data. This +algorithm is designed to be used in conjunction with the algorithms defined +in the Data Integrity [VC-DATA-INTEGRITY] specification, + +Section 4: Algorithms. Required inputs are +cryptographic hash data (hashData) and +proof options (options). The +proof options MUST contain a type identifier for the + +cryptographic suite (type) and MAY contain a cryptosuite +identifier (cryptosuite). A single digital proof value +represented as series of bytes is produced as output. +

+ +
    +
  1. +Let privateKeyBytes be the result of retrieving the +private key bytes associated with the +options.verificationMethod value as described in the +Data Integrity [VC-DATA-INTEGRITY] specification, + +Section 4.1: Processing Model. +
  2. +
  3. +Let proofBytes be the result of applying the Edwards-Curve Digital +Signature Algorithm (EdDSA) [RFC8032], using the Ed25519 variant +(Pure EdDSA), with hashData as the data to be signed using +the private key specified by privateKeyBytes. +proofBytes will be exactly 64 bytes in size. +
  4. +
  5. +Return proofBytes as the digital proof. +
  6. +
+ +
+ +

3.2.7 Proof Verification (eddsa-rdfc-2022)

+ + +

+The following algorithm specifies how to verify a digital signature from +a set of cryptographic hash data. This +algorithm is designed to be used in conjunction with the algorithms defined +in the Data Integrity [VC-DATA-INTEGRITY] specification, + +Section 4: Algorithms. Required inputs are +cryptographic hash data (hashData), +a digital signature (proofBytes) and +proof options (options). A verification result +represented as a boolean value is produced as output. +

+ +
    +
  1. +Let publicKeyBytes be the result of retrieving the +public key bytes associated with the +options.verificationMethod value as described in the +Controlled Identifiers (CIDs) v1.0 specification, + +Section 3.3: Retrieve Verification Method. +
  2. +
  3. +Let verificationResult be the result of applying the verification +algorithm for the Edwards-Curve Digital Signature Algorithm (EdDSA) +[RFC8032], using the Ed25519 variant (Pure EdDSA), +with hashData as the data to be verified against the +proofBytes using the public key specified by +publicKeyBytes. +
  4. +
  5. +Return verificationResult as the verification result. +
  6. +
+ +
+
+ +

3.3 eddsa-jcs-2022

+ + +

+The eddsa-jcs-2022 cryptographic suite takes an input document, canonicalizes +the document using the JSON Canonicalization Scheme [RFC8785], and then +cryptographically hashes and signs the output resulting in the production of a +data integrity proof. +

+ + + +

3.3.1 Create Proof (eddsa-jcs-2022)

+ + +

+The following algorithm specifies how to create a data integrity proof given +an unsecured data document. Required inputs are an +unsecured data document (map unsecuredDocument), and a set of proof +options (map options). A data integrity proof (map), or an error, +is produced as output. +

+ +
    +
  1. +Let proof be a clone of the proof options, options. +
  2. +
  3. +If unsecuredDocument.@context is present, +set proof.@context to +unsecuredDocument.@context. +
  4. +
  5. +Let proofConfig be the result of running the algorithm in +Section 3.3.5 Proof Configuration (eddsa-jcs-2022) with +proof passed as the proof options parameter. +
  6. +
  7. +Let transformedData be the result of running the algorithm in Section +3.3.3 Transformation (eddsa-jcs-2022) with unsecuredDocument +and options passed as parameters. +
  8. +
  9. +Let hashData be the result of running the algorithm in Section +3.3.4 Hashing (eddsa-jcs-2022) with transformedData and proofConfig +passed as a parameters. +
  10. +
  11. +Let proofBytes be the result of running the algorithm in Section +3.3.6 Proof Serialization (eddsa-jcs-2022) with hashData and +options passed as parameters. +
  12. +
  13. +Let proof.proofValue be a +base58-btc-encoded Multibase value of the proofBytes. +
  14. +
  15. +Return proof as the data integrity proof. +
  16. +
+
+ +

3.3.2 Verify Proof (eddsa-jcs-2022)

+ + +

+The following algorithm specifies how to verify a data integrity proof given +an secured data document. Required inputs are an +secured data document (map securedDocument). This algorithm returns +a verification result, which is a struct whose items are: +

+
+
verified
+
true or false
+
verifiedDocument
+
+if verified is true, an unsecured data document; +otherwise Null +
+
+ +
    +
  1. +Let unsecuredDocument be a copy of securedDocument with the proof value +removed. +
  2. +
  3. +Let proofOptions be the result of a copy of securedDocument.proof with +proofValue removed. +
  4. +
  5. +Let proofBytes be the +Multibase decoded base58-btc +value in securedDocument.proof.proofValue. +
  6. +
  7. +If proofOptions.@context exists: +
      +
    1. +Check that the securedDocument.@context starts with all values +contained in the proofOptions.@context in the same order. +Otherwise, set verified to false and skip to the last step. +
    2. +
    3. +Set unsecuredDocument.@context equal to +proofOptions.@context. +
    4. +
    +
  8. +
  9. +Let transformedData be the result of running the algorithm in Section +3.3.3 Transformation (eddsa-jcs-2022) with unsecuredDocument and +proofOptions passed as parameters. +
  10. +
  11. +Let proofConfig be the result of running the algorithm in Section +3.3.5 Proof Configuration (eddsa-jcs-2022) with proofOptions passed +as the parameter. +
  12. +
  13. +Let hashData be the result of running the algorithm in Section +3.3.4 Hashing (eddsa-jcs-2022) with transformedData and proofConfig passed as +a parameters. +
  14. +
  15. +Let verified be the result of running the algorithm in Section +3.3.7 Proof Verification (eddsa-jcs-2022) on hashData, proofBytes, +and proofConfig. +
  16. +
  17. +Return a verification result with items: +
    +
    verified
    +
    verified
    +
    verifiedDocument
    +
    +if verified is true, unsecuredDocument; +otherwise, Null
    +
    +
  18. +
+
+

3.3.3 Transformation (eddsa-jcs-2022)

+ + +

+The following algorithm specifies how to transform an unsecured input document +into a transformed document that is ready to be provided as input to the +hashing algorithm in Section 3.3.4 Hashing (eddsa-jcs-2022). +

+ +

+Required inputs to this algorithm are an + +unsecured data document (unsecuredDocument) and +transformation options (options). The +transformation options MUST contain a type identifier for the + +cryptographic suite (type) and a cryptosuite +identifier (cryptosuite). A transformed data document is +produced as output. Whenever this algorithm encodes strings, it MUST use UTF-8 +encoding. +

+ +
    +
  1. +If options.type is not set to the string +DataIntegrityProof and options.cryptosuite is not +set to the string eddsa-jcs-2022, +an error MUST be raised that SHOULD convey an error type of +PROOF_VERIFICATION_ERROR. +
  2. +
  3. +Let canonicalDocument be the result of applying the +JSON Canonicalization Scheme [RFC8785] to a JSON serialization of the +unsecuredDocument. +
  4. +
  5. +Return canonicalDocument as the transformed data document. +
  6. +
+
+

3.3.4 Hashing (eddsa-jcs-2022)

+ + +

+The following algorithm specifies how to cryptographically hash a +transformed data document and proof configuration +into cryptographic hash data that is ready to be provided as input to the +algorithms in Section 3.3.6 Proof Serialization (eddsa-jcs-2022) or +Section 3.3.7 Proof Verification (eddsa-jcs-2022). +

+ +

+The required inputs to this algorithm are a transformed data document +(transformedDocument) and canonical proof configuration +(canonicalProofConfig). A single hash data value represented as +series of bytes is produced as output. +

+ +
    +
  1. +Let transformedDocumentHash be the result of applying the +SHA-256 (SHA-2 with 256-bit output) cryptographic hashing algorithm [RFC6234] +to the transformedDocument. transformedDocumentHash will +be exactly 32 bytes in size. +
  2. +
  3. +Let proofConfigHash be the result of applying the +SHA-256 (SHA-2 with 256-bit output) cryptographic hashing algorithm [RFC6234] +to the canonicalProofConfig. proofConfigHash will be +exactly 32 bytes in size. +
  4. +
  5. +Let hashData be the result of joining proofConfigHash (the +first hash) with transformedDocumentHash (the second hash). +
  6. +
  7. +Return hashData as the hash data. +
  8. +
+ +
+

3.3.5 Proof Configuration (eddsa-jcs-2022)

+ + +

+The following algorithm specifies how to generate a +proof configuration from a set of proof options +that is used as input to the proof hashing algorithm. +

+ +

+The required inputs to this algorithm are proof options +(options). The proof options MUST contain a type identifier +for the + +cryptographic suite (type) and MUST contain a cryptosuite +identifier (cryptosuite). A proof configuration +object is produced as output. +

+ +
    +
  1. +Let proofConfig be a clone of the options object. +
  2. +
  3. +If proofConfig.type is not set to DataIntegrityProof or +proofConfig.cryptosuite is not set to eddsa-jcs-2022, +an error MUST be raised that SHOULD convey an error type of +PROOF_GENERATION_ERROR. +
  4. +
  5. +If proofConfig.created is set to a value that is not a +valid [XMLSCHEMA11-2] datetime, an error MUST be +raised and SHOULD convey an error type of +PROOF_GENERATION_ERROR. +
  6. +
  7. +Let canonicalProofConfig be the result of applying the +JSON Canonicalization Scheme [RFC8785] to the proofConfig. +
  8. +
  9. +Return canonicalProofConfig. +
  10. +
+ +
+

3.3.6 Proof Serialization (eddsa-jcs-2022)

+ + +

+The following algorithm specifies how to serialize a digital signature from +a set of cryptographic hash data. This +algorithm is designed to be used in conjunction with the algorithms defined +in the Data Integrity [VC-DATA-INTEGRITY] specification, + +Section 4: Algorithms. Required inputs are +cryptographic hash data (hashData) and +proof options (options). The +proof options MUST contain a type identifier for the + +cryptographic suite (type) and MAY contain a cryptosuite +identifier (cryptosuite). A single digital proof value +represented as series of bytes is produced as output. +

+ +
    +
  1. +Let privateKeyBytes be the result of retrieving the +private key bytes associated with the +options.verificationMethod value as described in the +Data Integrity [VC-DATA-INTEGRITY] specification, + +Section 4: Retrieving Cryptographic Material. +
  2. +
  3. +Let proofBytes be the result of applying the Edwards-Curve Digital +Signature Algorithm (EdDSA) [RFC8032], using the Ed25519 variant +(Pure EdDSA), with hashData as the data to be signed using +the private key specified by privateKeyBytes. +proofBytes will be exactly 64 bytes in size. +
  4. +
  5. +Return proofBytes as the digital proof. +
  6. +
+ +
+

3.3.7 Proof Verification (eddsa-jcs-2022)

+ + +

+The following algorithm specifies how to verify a digital signature from +a set of cryptographic hash data. This +algorithm is designed to be used in conjunction with the algorithms defined +in the Data Integrity [VC-DATA-INTEGRITY] specification, + +Section 4: Algorithms. Required inputs are +cryptographic hash data (hashData), +a digital signature (proofBytes) and +proof options (options). A verification result +represented as a boolean value is produced as output. +

+ +
    +
  1. +Let publicKeyBytes be the result of retrieving the +public key bytes associated with the +options.verificationMethod value as described in the +Data Integrity [VC-DATA-INTEGRITY] specification, + +Section 4: Retrieving Cryptographic Material. +
  2. +
  3. +Let verificationResult be the result of applying the verification +algorithm for the Edwards-Curve Digital Signature Algorithm (EdDSA) +[RFC8032], using the Ed25519 variant (Pure EdDSA), +with hashData as the data to be verified against the +proofBytes using the public key specified by +publicKeyBytes. +
  4. +
  5. +Return verificationResult as the verification result. +
  6. +
+ +
+
+ +
+ +

4. Security Considerations

+ + +

+Before reading this section, readers are urged to familiarize themselves +with general security advice provided in the + +Security Considerations section of the Data Integrity specification. +

+ +

+The following section describes security considerations that developers +implementing this specification should be aware of in order to create secure +software. +

+ +

4.1 Security Properties of Ed25519 Implementations

This section is non-normative.

+ +

+Ed25519 signatures (EdDSA algorithm with edwards25519 curve) have +been widely adopted, due both to the compact size of the keys and +signatures and to the speed at +which signatures can be produced and verified. Many libraries exist that can +create and verify Ed25519 signatures. Since the publication of [RFC8032], +security properties of Ed25519 signatures have been rigorously proven (see +[Provable_Ed25519] and [Taming_EdDSAs]). However, it has been observed that a +significant number of libraries do not achieve these security levels, due to +missing input validity checks during the signature verification process. In +this section, we summarize the security levels achievable with Ed25519 +signatures, and indicate how one can determine whether a library will support those +levels. +

+

4.1.1 Signature Security Properties

+ +

+Digital signatures might exhibit a number of desirable cryptographic +properties [Taming_EdDSAs] among these are: +

+

+EUF-CMA (existential unforgeability under +chosen message attacks) is usually the minimal security property required +of a signature scheme. It guarantees that any efficient adversary who has the +public key + + + + + + + p + k + + + + + + of the signer and received an arbitrary number of signatures on +messages of its choice (in an adaptive manner): + + + + + + + { + + m + i + + , + + σ + i + + + } + + i + = + 1 + + N + + + + + + +, +cannot output a valid signature + + + + + + + + σ + + + + + + + + +for a new message + + + + + + + + m + + + + { + + m + i + + + } + + i + = + 1 + + N + + + + + + + +(except with negligible probability). If the attacker outputs a valid +signature on a new message: + + + + + + + ( + + m + + + , + + σ + + + ) + + + + + +, +it is called an existential +forgery. +

+

+SUF-CMA (strong unforgeability under chosen +message attacks) is a stronger notion than EUF-CMA. It guarantees +that for any efficient adversary who has the public key + + + + + + + p + k + + + + + + +of the signer and +received an arbitrary number of signatures on messages of its choice: + + + + + + + { + + m + i + + , + + σ + i + + + } + + i + = + 1 + + N + + + + + + +, +it cannot output a new valid signature pair + + + + + + + ( + + m + + + , + + σ + + + ) + + + + + +, +such that + + + + + + + ( + + m + + + , + + σ + + + ) + + { + + m + i + + , + + σ + i + + + } + + i + = + 1 + + N + + + + + + + +(except with negligible probability). Strong unforgeability implies that an +adversary not only cannot sign new messages, but also cannot find a new signature +on an old message. See [Provable_Ed25519] for a real world attack that would +have been circumvented with SUF-CMA security over EUF-CMA security. +

+

+Binding signature (BS) We say that a signature +scheme is binding if no efficient signer can output a tuple + + + + + + + [ + p + k + , + m + , + + m + + + , + σ + ] + + + + + +, +where both + + + + + + + ( + m + , + σ + ) + + + + + + +and + + + + + + + ( + + m + + + , + σ + ) + + + + + + +are valid message signature pairs under the public key + + + + + + + p + k + + + + + + +and + + + + + + + m + + + m + + + + + + + + +(except with negligible probability). A binding signature makes it impossible +for the signer to claim later that it has signed a different message; the +signature binds the signer to the message. +

+

+Strongly Binding signature (SBS) Certain +applications may require a signature to not only be binding to the message but +also be binding to the public key. We say that a signature scheme is +strongly-binding if any efficient signer cannot output a tuple + + + + + + + [ + p + k + , + m + , + p + + k + + + , + + m + + + , + σ + ] + + + + + +, +where + + + + + + + ( + m + , + σ + ) + + + + + + +is a valid signature for the public key + + + + + + + p + k + + + + + + +and + + + + + + + ( + + m + + + , + σ + ) + + + + + + +is a valid signature for the public key + + + + + + + p + + k + + + + + + + + +and either + + + + + + + + m + + + + m + + + + + + +or + + + + + + + p + k + + p + + k + + + + + + + +, +or both (except with negligible probability). See [Provable_Ed25519] for real +world attacks that would have been circumvented with the SBS property. +

+

Note that the BS and SBS properties are forms of +non-repudiation. +

+
+

4.1.2 Achieving Ed25519 Security Properties

+ +

+As pointed out in [Taming_EdDSAs], flaws in Ed25519 libraries +primarily occur on the signature verification side, where edge cases +are sometimes not properly checked. An Ed25519 signature library that is in conformance +with [RFC8032] or [FIPS-186-5], i.e., one that performs all + specified validation checks, will have the SUF-CMA +property in addition to EUF-CMA. +

+

+Reference [Taming_EdDSAs] achieves the BS and +SBS properties along with SUF-CMA in their +"signature verification algorithm 2" where an additional check is +performed against the public key A to make sure that it is not one of +eight "small order points". These additional checks incur minimal processing overhead. +

+

+Reference [Taming_EdDSAs] included a set of twelve test vectors +to test various Ed25519 libraries available at the time of publication. They +found that a significant portion missed edge cases and hence did not achieve +SUF-CMA (just EUF-CMA), and only two libraries out of sixteen +achieved all the security properties. Since the time of publication, more +Ed25519 libraries have been created, and some of the libraries have been updated +to include all verification checks. Implementers are recommended to test the +Ed25519 library they are using against the test vectors of [Taming_EdDSAs]. +

+
+
+ +
+ +

5. Privacy Considerations

+ + +

+Before reading this section, readers are urged to familiarize themselves +with general privacy advice provided in the + +Privacy Considerations section of the Data Integrity specification. +

+ +

+The following section describes privacy considerations that developers +implementing this specification should be aware of in order to avoid violating +privacy assumptions. +

+ +

5.1 Selective and Unlinkable Disclosure

+ + +

+The cryptographic suites described in this specification do not support +selective disclosure or unlinkable disclosure. If +selective disclosure is a desired feature, readers might find the +Data Integrity ECDSA Cryptosuites v1.0 specification useful. If unlinkable disclosure is of +interest, the Data Integrity BBS Cryptosuites v1.0 specification provides an unlinkable digital +signature mechanism. +

+ +
+
+ +

A. The Ed25519Signature2020 Suite

+ + +

+Ed25519Signature2020 is an earlier version of a cryptographic suite +for use of the EdDSA algorithm and Curve25519. While it has +been used in production systems, new implementations should instead use +eddsa-rdfc-2022. Ed25519Signature2020 has +been kept in this specification to provide a stable reference. +

+ +

A.1 Data Model

+ +

A.1.1 Verification Methods

+ +
A.1.1.1 Ed25519VerificationKey2020
+ + +

+The key format described in this section is provided to document a legacy +mechanism that has been deployed to production. The key format described in +section 2.1.1 Multikey supercedes the one described in this section. New +applications are strongly urged to use the newer key format. +

+ +

+The type of the verification method MUST be +Ed25519VerificationKey2020. +

+ +

+The controller of the verification method MUST be a URL. +

+ +

+The publicKeyMultibase value of the verification method MUST start with the +base-58-btc prefix (z), as defined in the +Multibase section of +[VC-DATA-INTEGRITY]. A Multibase-encoded Multikey value follows, which MUST +consist of a binary value that starts with the two-byte prefix 0xed01, which +is the Multikey header for an Ed25519 public key, followed by the 32-byte +public key data, all of which is then encoded using base-58-btc. Any other +encoding MUST NOT be allowed. +

+ +

+Developers are advised to not accidentally publish a representation of a private +key. Implementations of this specification will raise errors in the event of a +Multikey header value other than 0xed01 being used in a +publicKeyMultibase value. +

+ +
+
+ Example 4: An Ed25519 public key encoded as an + Ed25519VerificationKey2020 +
{
+  "id": "https://example.com/issuer/123#key-0",
+  "type": "Ed25519VerificationKey2020",
+  "controller": "https://example.com/issuer/123",
+  "publicKeyMultibase": "z6Mkf5rGMoatrSj1f4CyvuHBeXJELe9RPdzo2PKGNCKVtZxP"
+}
+
+ +
+
+ Example 5: An Ed25519 public key encoded as an + Ed25519VerificationKey2020 in a controller document. +
{
+  "@context": [
+    "https://www.w3.org/ns/did/v1",
+    "https://w3id.org/security/suites/ed25519-2020/v1"
+  ],
+  "id": "did:example:123",
+  "verificationMethod": [{
+    "id": "did:example:123#key-0",
+    "type": "Ed25519VerificationKey2020",
+    "controller": "did:example:123",
+    "publicKeyMultibase": "z6Mkf5rGMoatrSj1f4CyvuHBeXJELe9RPdzo2PKGNCKVtZxP"
+  }],
+  "authentication": [
+    "did:example:123#key-0"
+  ],
+  "assertionMethod": [
+    "did:example:123#key-0"
+  ],
+  "capabilityDelegation": [
+    "did:example:123#key-0"
+  ],
+  "capabilityInvocation": [
+    "did:example:123#key-0"
+  ]
+}
+
+
+ +
+

A.1.2 Proof representations

+ +
A.1.2.1 Ed25519Signature2020
+ + +

+The proof format described in this section is provided to document a legacy +mechanism that has been deployed to production. The DataIntegrityProof formats +described in section 2.2.1 DataIntegrityProof supercede the one described in +this section. New applications are strongly urged to use the newer proof format. +

+ +

+The verificationMethod property of the proof MUST be a URL. +Dereferencing the verificationMethod MUST result in an object +containing a type property with the value set to +Ed25519VerificationKey2020. +

+ +

+The type property of the proof MUST be Ed25519Signature2020. +

+

+The created property of the proof MUST be an [XMLSCHEMA11-2] +formatted date string. +

+

+The proofPurpose property of the proof MUST be a string, and MUST +match the verification relationship expressed by the verification method +controller. +

+

+The proofValue property of the proof MUST be a detached EdDSA +produced according to [RFC8032], encoded using +the base-58-btc header and alphabet as described in the + +Multibase section of [CONTROLLER-DOCUMENT]. +

+ +
+
+ Example 6: An Ed25519 digital signature expressed as a + Ed25519Signature2020 +
{
+  "@context": [
+    {"myWebsite": "https://vocabulary.example/myWebsite"},
+    "https://w3id.org/security/suites/ed25519-2020/v1"
+  ],
+  "myWebsite": "https://hello.world.example/",
+  "proof": {
+    "type": "Ed25519Signature2020",
+    "created": "2020-11-05T19:23:24Z",
+    "verificationMethod": "https://di.example/issuer#z6MkjLrk3gKS2nnkeWcmcxiZPGskmesDpuwRBorgHxUXfxnG",
+    "proofPurpose": "assertionMethod",
+    "proofValue": "z4oey5q2M3XKaxup3tmzN4DRFTLVqpLMweBrSxMY2xHX5XTYVQeVbY8nQAVHMrXFkXJpmEcqdoDwLWxaqA3Q1geV6"
+  }
+}
+
+ +
+ +
+
+ +

A.2 Algorithms

+ +

A.2.1 Ed25519Signature2020

+ + +

+The Ed25519Signature2020 cryptographic suite takes an input document, +canonicalizes the document using the RDF Dataset Canonicalization algorithm [RDF-CANON], +and then cryptographically hashes and signs the output +resulting in the production of a data integrity proof. The algorithms in this +section also include the verification of such a data integrity proof. +

+ +
A.2.1.1 Add Proof (Ed25519Signature2020)
+ + +

+To generate a proof, the algorithm in + +Section 4.1: Add Proof in the Data Integrity +[VC-DATA-INTEGRITY] specification MUST be executed. +For that algorithm, the cryptographic suite specific + +transformation algorithm is defined in Section +A.2.1.3 Transformation (Ed25519Signature2020), the + +hashing algorithm is defined in Section +A.2.1.4 Hashing (Ed25519Signature2020), and the + +proof serialization algorithm is defined in Section +A.2.1.6 Proof Serialization (Ed25519Signature2020). +

+
+ +
A.2.1.2 Verify Proof (Ed25519Signature2020)
+ + +

+To verify a proof, the algorithm in + +Section 4.2: Verify Proof in the Data Integrity +[VC-DATA-INTEGRITY] specification MUST be executed. +For that algorithm, the cryptographic suite specific + +transformation algorithm is defined in Section +A.2.1.3 Transformation (Ed25519Signature2020), the + +hashing algorithm is defined in Section A.2.1.4 Hashing (Ed25519Signature2020), +and the + +proof verification algorithm is defined in Section +A.2.1.7 Proof Verification (Ed25519Signature2020). +

+
+ +
A.2.1.3 Transformation (Ed25519Signature2020)
+ + +

+The following algorithm specifies how to transform an unsecured input document +into a transformed document that is ready to be provided as input to the +hashing algorithm in Section A.2.1.4 Hashing (Ed25519Signature2020). +

+ +

+Required inputs to this algorithm are an + +unsecured data document (unsecuredDocument) and +transformation options (options). The +transformation options MUST contain a type identifier for the + +cryptographic suite (type) and a cryptosuite +identifier (cryptosuite). A transformed data document is +produced as output. Whenever this algorithm encodes strings, it MUST use UTF-8 +encoding. +

+ +
    +
  1. +If options.type is not set to the string +Ed25519Signature2020, +an error MUST be raised that SHOULD convey an error type of +PROOF_TRANSFORMATION_ERROR. +
  2. +
  3. +Let canonicalDocument be the result of converting unsecuredDocument to +JSON-LD expanded form +and then +to RDF statements, applying the +Universal RDF Dataset Canonicalization Algorithm, and then serializing the result to a +serialized canonical form. +
  4. +
  5. +Return canonicalDocument as the transformed data document. +
  6. +
+ +
+ +
A.2.1.4 Hashing (Ed25519Signature2020)
+ + +

+The following algorithm specifies how to cryptographically hash a +transformed data document and proof configuration +into cryptographic hash data that is ready to be provided as input to the +algorithms in Section A.2.1.6 Proof Serialization (Ed25519Signature2020) or +Section A.2.1.7 Proof Verification (Ed25519Signature2020). +

+ +

+The required inputs to this algorithm are a +transformed data document (transformedDocument) and +proof configuration (proofConfig). The +proof configuration MUST contain a type identifier for the + +cryptographic suite (type) and MAY contain a cryptosuite +identifier (cryptosuite). A single hash data value +represented as series of bytes is produced as output. +

+ +
    +
  1. +Let transformedDocumentHash be the result of applying the +SHA-256 (SHA-2 with 256-bit output) cryptographic hashing algorithm [RFC6234] +to the transformedDocument. transformedDocumentHash will +be exactly 32 bytes in size. +
  2. +
  3. +Let proofConfigHash be the result of applying the +SHA-256 (SHA-2 with 256-bit output) cryptographic hashing algorithm [RFC6234] +to the canonicalProofConfig. proofConfigHash will be +exactly 32 bytes in size. +
  4. + +
  5. +Let hashData be the result of joining proofConfigHash (the +first hash) with transformedDocumentHash (the second hash). +
  6. +
  7. +Return hashData as the hash data. +
  8. +
+ +
+ +
A.2.1.5 Proof Configuration (Ed25519Signature2020)
+ + +

+The following algorithm specifies how to generate a +proof configuration from a set of proof options +that is used as input to the proof hashing algorithm. +

+ +

+The required inputs to this algorithm are proof options +(options). The proof options MUST contain a type identifier +for the + +cryptographic suite (type) and MAY contain a cryptosuite +identifier (cryptosuite). A proof configuration +object is produced as output. +

+ +
    +
  1. +Let proofConfig be a clone of the options object. +
  2. +
  3. +If proofConfig.type is not set to Ed25519Signature2020, +an error MUST be raised and SHOULD convey an error type of +PROOF_GENERATION_ERROR. +
  4. +
  5. +If proofConfig.created is present and set to a value that is not a +valid [XMLSCHEMA11-2] datetime, an error MUST be +raised and SHOULD convey an error type of +PROOF_GENERATION_ERROR. +
  6. +
  7. +Set proofConfig.@context to +unsecuredDocument.@context +
  8. +
  9. +Let canonicalProofConfig be the result of applying the +RDF Dataset Canonicalization algorithm [RDF-CANON] to the proofConfig. +
  10. +
  11. +Return canonicalProofConfig. +
  12. +
+ +
+ +
A.2.1.6 Proof Serialization (Ed25519Signature2020)
+ + +

+The following algorithm specifies how to serialize a digital signature from +a set of cryptographic hash data. This +algorithm is designed to be used in conjunction with the algorithms defined +in the Data Integrity [VC-DATA-INTEGRITY] specification, + +Section 4: Algorithms. Required inputs are +cryptographic hash data (hashData) and +proof options (options). The +proof options MUST contain a type identifier for the + +cryptographic suite (type) and MAY contain a cryptosuite +identifier (cryptosuite). A single digital proof value +represented as series of bytes is produced as output. +

+ +
    +
  1. +Let privateKeyBytes be the result of retrieving the +private key bytes associated with the +options.verificationMethod value as described in the +Data Integrity [VC-DATA-INTEGRITY] specification, + +Section 4: Retrieving Cryptographic Material. +
  2. +
  3. +Let proofBytes be the result of applying the Edwards-Curve Digital +Signature Algorithm (EdDSA) [RFC8032], using the Ed25519 variant +(Pure EdDSA), with hashData as the data to be signed using +the private key specified by privateKeyBytes. +proofBytes will be exactly 64 bytes in size. +
  4. +
  5. +Return proofBytes as the digital proof. +
  6. +
+ +
+ +
A.2.1.7 Proof Verification (Ed25519Signature2020)
+ + +

+The following algorithm specifies how to verify a digital signature from +a set of cryptographic hash data. This +algorithm is designed to be used in conjunction with the algorithms defined +in the Data Integrity [VC-DATA-INTEGRITY] specification, + +Section 4: Algorithms. Required inputs are +cryptographic hash data (hashData), +a digital signature (proofBytes) and +proof options (options). A verification result +represented as a boolean value is produced as output. +

+ +
    +
  1. +Let publicKeyBytes be the result of retrieving the +public key bytes associated with the +options.verificationMethod value as described in the +Data Integrity [VC-DATA-INTEGRITY] specification, + +Section 4: Retrieving Cryptographic Material. +
  2. +
  3. +Let verificationResult be the result of applying the verification +algorithm for the Edwards-Curve Digital Signature Algorithm (EdDSA) +[RFC8032], using the Ed25519 variant (Pure EdDSA), +with hashData as the data to be verified against the +proofBytes using the public key specified by +publicKeyBytes. +
  4. +
  5. +Return verificationResult as the verification result. +
  6. +
+ +
+
+
+
+ + +

B. Test Vectors

This section is non-normative.

+ +

B.1 Representation: eddsa-rdfc-2022

+ +

+The signer needs to generate a private/public key pair with the private key used +for signing and the public key made available for verification. The +representation of the public key and the representation of the private key +are shown below. +

+
+
+ Example 7: Private and Public keys for Signature +
{
+    publicKeyMultibase: "z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2",
+    secretKeyMultibase: "z3u2en7t5LR2WtQH5PfFqMqwVHBeXouLzo6haApm8XHqvjxq"
+}
+
+ +

+Signing begins with a credential without an attached proof, which is converted +to canonical form, and then hashed, as shown in the following three examples. +

+ +
+
+ Example 8: Credential without Proof +
{
+    "@context": [
+        "https://www.w3.org/ns/credentials/v2",
+        "https://www.w3.org/ns/credentials/examples/v2"
+    ],
+    "id": "urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33",
+    "type": ["VerifiableCredential", "AlumniCredential"],
+    "name": "Alumni Credential",
+    "description": "A minimum viable example of an Alumni Credential.",
+    "issuer": "https://vc.example/issuers/5678",
+    "validFrom": "2023-01-01T00:00:00Z",
+    "credentialSubject": {
+        "id": "did:example:abcdefgh",
+        "alumniOf": "The School of Examples"
+    }
+}
+
+ +
+
+ Example 9: Canonical Credential without Proof +
<did:example:abcdefgh> <https://www.w3.org/ns/credentials/examples#alumniOf> "The School of Examples" .
+<urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://www.w3.org/2018/credentials#VerifiableCredential> .
+<urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://www.w3.org/ns/credentials/examples#AlumniCredential> .
+<urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33> <https://schema.org/description> "A minimum viable example of an Alumni Credential." .
+<urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33> <https://schema.org/name> "Alumni Credential" .
+<urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33> <https://www.w3.org/2018/credentials#credentialSubject> <did:example:abcdefgh> .
+<urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33> <https://www.w3.org/2018/credentials#issuer> <https://vc.example/issuers/5678> .
+<urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33> <https://www.w3.org/2018/credentials#validFrom> "2023-01-01T00:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> .
+
+ + +
+
+ Example 10: Hash of Canonical Credential without Proof (hex) +
517744132ae165a5349155bef0bb0cf2258fff99dfe1dbd914b938d775a36017
+
+ +

+The next step is to take the proof options document, convert it to canonical form, +and obtain its hash, as shown in the next three examples. +

+ +
+
+ Example 11: Proof Options Document +
{
+  "type": "DataIntegrityProof",
+  "cryptosuite": "eddsa-rdfc-2022",
+  "created": "2023-02-24T23:36:38Z",
+  "verificationMethod": "did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2#z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2",
+  "proofPurpose": "assertionMethod",
+  "@context": [
+    "https://www.w3.org/ns/credentials/v2",
+    "https://www.w3.org/ns/credentials/examples/v2"
+  ]
+}
+
+ +
+
+ Example 12: Canonical Proof Options Document +
_:c14n0 <http://purl.org/dc/terms/created> "2023-02-24T23:36:38Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> .
+_:c14n0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://w3id.org/security#DataIntegrityProof> .
+_:c14n0 <https://w3id.org/security#cryptosuite> "eddsa-rdfc-2022"^^<https://w3id.org/security#cryptosuiteString> .
+_:c14n0 <https://w3id.org/security#proofPurpose> <https://w3id.org/security#assertionMethod> .
+_:c14n0 <https://w3id.org/security#verificationMethod> <did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2#z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2> .
+
+ +
+
+ Example 13: Hash of Canonical Proof Options Document (hex) +
bea7b7acfbad0126b135104024a5f1733e705108f42d59668b05c0c50004c6b0
+
+ +

+Finally, we concatenate the hash of the proof options followed by the hash of the credential without proof, use the private key with the combined hash to +compute the Ed25519 signature, and then base58-btc encode the signature. +

+ +
+
+ Example 14: Combine hashes of Proof Options and Credential (hex) +
bea7b7acfbad0126b135104024a5f1733e705108f42d59668b05c0c50004c6b0517744132ae165a5349155bef0bb0cf2258fff99dfe1dbd914b938d775a36017
+
+ +
+
+ Example 15: Signature of Combined Hashes (hex) +
4d8e53c2d5b3f2a7891753eb16ca993325bdb0d3cfc5be1093d0a18426f5ef8578cadc0fd4b5f4dd0d1ce0aefd15ab120b7a894d0eb094ffda4e6553cd1ed50d
+
+ +
+
+ Example 16: Signature of Combined Hashes base58-btc +
z2YwC8z3ap7yx1nZYCg4L3j3ApHsF8kgPdSb5xoS1VR7vPG3F561B52hYnQF9iseabecm3ijx4K1FBTQsCZahKZme
+
+ +

Assemble the signed credential with the following two steps:

+
    +
  1. +Add the proofValue field with the previously computed base58-btc +value to the proof options document. +
  2. +
  3. +Set the proof field of the credential to the augmented proof +option document. +
  4. +
+ +
+
+ Example 17: Signed Credential +
{
+  "@context": [
+    "https://www.w3.org/ns/credentials/v2",
+    "https://www.w3.org/ns/credentials/examples/v2"
+  ],
+  "id": "urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33",
+  "type": [
+    "VerifiableCredential",
+    "AlumniCredential"
+  ],
+  "name": "Alumni Credential",
+  "description": "A minimum viable example of an Alumni Credential.",
+  "issuer": "https://vc.example/issuers/5678",
+  "validFrom": "2023-01-01T00:00:00Z",
+  "credentialSubject": {
+    "id": "did:example:abcdefgh",
+    "alumniOf": "The School of Examples"
+  },
+  "proof": {
+    "type": "DataIntegrityProof",
+    "cryptosuite": "eddsa-rdfc-2022",
+    "created": "2023-02-24T23:36:38Z",
+    "verificationMethod": "did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2#z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2",
+    "proofPurpose": "assertionMethod",
+    "proofValue": "z2YwC8z3ap7yx1nZYCg4L3j3ApHsF8kgPdSb5xoS1VR7vPG3F561B52hYnQF9iseabecm3ijx4K1FBTQsCZahKZme"
+  }
+}
+
+
+

B.2 Enhanced Example for Representation: eddsa-rdfc-2022

+ +

+Here we again go through the steps of creating a credential signed with +eddsa-rdfc-2022, but with a more complicated input document. The +representation of the public key and the representation of the private key +are shown below. +

+
+
+ Example 18: Private and Public keys for Signature +
{
+    publicKeyMultibase: "z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2",
+    secretKeyMultibase: "z3u2en7t5LR2WtQH5PfFqMqwVHBeXouLzo6haApm8XHqvjxq"
+}
+
+ +

+Signing begins with a credential without an attached proof, which is converted +to canonical form, and then hashed, as shown in the following three examples. +

+ +
+
+ Example 19: Employment Authorization Credential without Proof +
{
+    "@context": [
+      "https://www.w3.org/ns/credentials/v2",
+      "https://w3id.org/citizenship/v4rc1"
+    ],
+    "type": [
+      "VerifiableCredential",
+      "EmploymentAuthorizationDocumentCredential"
+    ],
+    "issuer": {
+      "id": "did:key:zDnaegE6RR3atJtHKwTRTWHsJ3kNHqFwv7n9YjTgmU7TyfU76",
+      "image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIW2NgUPr/HwADaAIhG61j/AAAAABJRU5ErkJggg=="
+    },
+    "credentialSubject": {
+      "type": [
+        "Person",
+        "EmployablePerson"
+      ],
+      "givenName": "JOHN",
+      "additionalName": "JACOB",
+      "familyName": "SMITH",
+      "image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIW2Ng+M/wHwAEAQH/7yMK/gAAAABJRU5ErkJggg==",
+      "gender": "Male",
+      "residentSince": "2015-01-01",
+      "birthCountry": "Bahamas",
+      "birthDate": "1999-07-17",
+      "employmentAuthorizationDocument": {
+        "type": "EmploymentAuthorizationDocument",
+        "identifier": "83627465",
+        "lprCategory": "C09",
+        "lprNumber": "999-999-999"
+      }
+    },
+    "name": "Employment Authorization Document",
+    "description": "Example Employment Authorization Document.",
+    "validFrom": "2019-12-03T00:00:00Z",
+    "validUntil": "2029-12-03T00:00:00Z"
+  }
+
+ +
+
+ Example 20: Canonical Employment Authorization Credential without Proof +
<did:key:zDnaegE6RR3atJtHKwTRTWHsJ3kNHqFwv7n9YjTgmU7TyfU76> <https://schema.org/image> <data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIW2NgUPr/HwADaAIhG61j/AAAAABJRU5ErkJggg==> .
+_:c14n0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://w3id.org/citizenship#EmploymentAuthorizationDocumentCredential> .
+_:c14n0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://www.w3.org/2018/credentials#VerifiableCredential> .
+_:c14n0 <https://schema.org/description> "Example Employment Authorization Document." .
+_:c14n0 <https://schema.org/name> "Employment Authorization Document" .
+_:c14n0 <https://www.w3.org/2018/credentials#credentialSubject> _:c14n1 .
+_:c14n0 <https://www.w3.org/2018/credentials#issuer> <did:key:zDnaegE6RR3atJtHKwTRTWHsJ3kNHqFwv7n9YjTgmU7TyfU76> .
+_:c14n0 <https://www.w3.org/2018/credentials#validFrom> "2019-12-03T00:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> .
+_:c14n0 <https://www.w3.org/2018/credentials#validUntil> "2029-12-03T00:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> .
+_:c14n1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://schema.org/Person> .
+_:c14n1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://w3id.org/citizenship#EmployablePerson> .
+_:c14n1 <https://schema.org/additionalName> "JACOB" .
+_:c14n1 <https://schema.org/birthDate> "1999-07-17"^^<http://www.w3.org/2001/XMLSchema#dateTime> .
+_:c14n1 <https://schema.org/familyName> "SMITH" .
+_:c14n1 <https://schema.org/gender> "Male" .
+_:c14n1 <https://schema.org/givenName> "JOHN" .
+_:c14n1 <https://schema.org/image> <data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIW2Ng+M/wHwAEAQH/7yMK/gAAAABJRU5ErkJggg==> .
+_:c14n1 <https://w3id.org/citizenship#birthCountry> "Bahamas" .
+_:c14n1 <https://w3id.org/citizenship#employmentAuthorizationDocument> _:c14n2 .
+_:c14n1 <https://w3id.org/citizenship#residentSince> "2015-01-01"^^<http://www.w3.org/2001/XMLSchema#dateTime> .
+_:c14n2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://w3id.org/citizenship#EmploymentAuthorizationDocument> .
+_:c14n2 <https://schema.org/identifier> "83627465" .
+_:c14n2 <https://w3id.org/citizenship#lprCategory> "C09" .
+_:c14n2 <https://w3id.org/citizenship#lprNumber> "999-999-999" .
+
+ + +
+
+ Example 21: Hash of Canonical Employment Authorization Credential without Proof (hex) +
03f59e5b04ab575b1172cb684f22eede72f0e9033e0b5c67d0e2506768d6ce11
+
+ +

+The next step is to take the proof options document, convert it to canonical +form, and obtain its hash, as shown in the next three examples. +

+ +
+
+ Example 22: Proof Options Document +
{
+  "type": "DataIntegrityProof",
+  "cryptosuite": "eddsa-rdfc-2022",
+  "created": "2023-02-24T23:36:38Z",
+  "verificationMethod": "did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2#z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2",
+  "proofPurpose": "assertionMethod",
+  "@context": [
+    "https://www.w3.org/ns/credentials/v2",
+    "https://w3id.org/citizenship/v4rc1"
+  ]
+}
+
+ +
+
+ Example 23: Canonical Proof Options Document +
_:c14n0 <http://purl.org/dc/terms/created> "2023-02-24T23:36:38Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> .
+_:c14n0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://w3id.org/security#DataIntegrityProof> .
+_:c14n0 <https://w3id.org/security#cryptosuite> "eddsa-rdfc-2022"^^<https://w3id.org/security#cryptosuiteString> .
+_:c14n0 <https://w3id.org/security#proofPurpose> <https://w3id.org/security#assertionMethod> .
+_:c14n0 <https://w3id.org/security#verificationMethod> <did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2#z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2> .
+
+ +
+
+ Example 24: Hash of Canonical Proof Options Document (hex) +
bea7b7acfbad0126b135104024a5f1733e705108f42d59668b05c0c50004c6b0
+
+ +

+Finally, we concatenate the hash of the proof options followed by the hash of +the credential without proof, use the private key with the combined hash to +compute the Ed25519 signature, and then base58-btc encode the signature. +

+ +
+
+ Example 25: Combine hashes of Proof Options and Credential (hex) +
bea7b7acfbad0126b135104024a5f1733e705108f42d59668b05c0c50004c6b003f59e5b04ab575b1172cb684f22eede72f0e9033e0b5c67d0e2506768d6ce11
+
+ +
+
+ Example 26: Signature of Combined Hashes (hex) +
20b1a944960b75ca69ba070af4820de6e6acae1afe827d8c566c0f7b932d1bd3abde3222b3095088051439a8b4e7a5356c7ba6d246774f875ebb6ddee1577003
+
+ +
+
+ Example 27: Signature of Combined Hashes base58-btc +
zeuuS9pi2ZR8Q41bFFJKS9weSWkwa7pRcxHTHzxjDEHtVSZp3D9Rm3JdzT82EQpmXMb9wvfFJLuDPeSXZaRX1q1c
+
+ +

Assemble the signed credential with the following two steps:

+
    +
  1. +Add the proofValue field with the previously computed base58-btc +value to the proof options document. +
  2. +
  3. +Set the proof field of the credential to the augmented proof +option document. +
  4. +
+ +
+
+ Example 28: Signed Employment Authorization Credential +
{
+  "@context": [
+    "https://www.w3.org/ns/credentials/v2",
+    "https://w3id.org/citizenship/v4rc1"
+  ],
+  "type": [
+    "VerifiableCredential",
+    "EmploymentAuthorizationDocumentCredential"
+  ],
+  "issuer": {
+    "id": "did:key:zDnaegE6RR3atJtHKwTRTWHsJ3kNHqFwv7n9YjTgmU7TyfU76",
+    "image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIW2NgUPr/HwADaAIhG61j/AAAAABJRU5ErkJggg=="
+  },
+  "credentialSubject": {
+    "type": [
+      "Person",
+      "EmployablePerson"
+    ],
+    "givenName": "JOHN",
+    "additionalName": "JACOB",
+    "familyName": "SMITH",
+    "image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIW2Ng+M/wHwAEAQH/7yMK/gAAAABJRU5ErkJggg==",
+    "gender": "Male",
+    "residentSince": "2015-01-01",
+    "birthCountry": "Bahamas",
+    "birthDate": "1999-07-17",
+    "employmentAuthorizationDocument": {
+      "type": "EmploymentAuthorizationDocument",
+      "identifier": "83627465",
+      "lprCategory": "C09",
+      "lprNumber": "999-999-999"
+    }
+  },
+  "name": "Employment Authorization Document",
+  "description": "Example Employment Authorization Document.",
+  "validFrom": "2019-12-03T00:00:00Z",
+  "validUntil": "2029-12-03T00:00:00Z",
+  "proof": {
+    "type": "DataIntegrityProof",
+    "cryptosuite": "eddsa-rdfc-2022",
+    "created": "2023-02-24T23:36:38Z",
+    "verificationMethod": "did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2#z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2",
+    "proofPurpose": "assertionMethod",
+    "proofValue": "zeuuS9pi2ZR8Q41bFFJKS9weSWkwa7pRcxHTHzxjDEHtVSZp3D9Rm3JdzT82EQpmXMb9wvfFJLuDPeSXZaRX1q1c"
+  }
+}
+
+
+

B.3 Representation: eddsa-jcs-2022

+ +

+The signer needs to generate a private/public key pair with the private key used +for signing and the public key made available for verification. The +representation of the public key, and the representation of the private key +are shown below. +

+
+
+ Example 29: Private and Public keys for Signature +
{
+  publicKeyMultibase: "z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2",
+  secretKeyMultibase: "z3u2en7t5LR2WtQH5PfFqMqwVHBeXouLzo6haApm8XHqvjxq"
+}
+
+ +

+Signing begins with a credential without an attached proof, which is converted +to canonical form, and then hashed, as shown in the following three examples. +

+ +
+
+ Example 30: Credential without Proof +
{
+    "@context": [
+        "https://www.w3.org/ns/credentials/v2",
+        "https://www.w3.org/ns/credentials/examples/v2"
+    ],
+    "id": "urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33",
+    "type": ["VerifiableCredential", "AlumniCredential"],
+    "name": "Alumni Credential",
+    "description": "A minimum viable example of an Alumni Credential.",
+    "issuer": "https://vc.example/issuers/5678",
+    "validFrom": "2023-01-01T00:00:00Z",
+    "credentialSubject": {
+        "id": "did:example:abcdefgh",
+        "alumniOf": "The School of Examples"
+    }
+}
+
+ +
+
+ Example 31: Canonical Credential without Proof +
{"@context":["https://www.w3.org/ns/credentials/v2","https://www.w3.org/ns/credentials/examples/v2"],"credentialSubject":{"alumniOf":"The School of Examples","id":"did:example:abcdefgh"},"description":"A minimum viable example of an Alumni Credential.","id":"urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33","issuer":"https://vc.example/issuers/5678","name":"Alumni Credential","type":["VerifiableCredential","AlumniCredential"],"validFrom":"2023-01-01T00:00:00Z"}
+
+ + +
+
+ Example 32: Hash of Canonical Credential without Proof (hex) +
59b7cb6251b8991add1ce0bc83107e3db9dbbab5bd2c28f687db1a03abc92f19
+
+ +

+The next step is to take the proof options document, convert it to canonical form, +and obtain its hash, as shown in the next three examples. +

+ +
+
+ Example 33: Proof Options Document +
{
+  "type": "DataIntegrityProof",
+  "cryptosuite": "eddsa-jcs-2022",
+  "created": "2023-02-24T23:36:38Z",
+  "verificationMethod": "did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2#z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2",
+  "proofPurpose": "assertionMethod",
+  "@context": [
+    "https://www.w3.org/ns/credentials/v2",
+    "https://www.w3.org/ns/credentials/examples/v2"
+  ]
+}
+
+ +
+
+ Example 34: Canonical Proof Options Document +
{"@context":["https://www.w3.org/ns/credentials/v2","https://www.w3.org/ns/credentials/examples/v2"],"created":"2023-02-24T23:36:38Z","cryptosuite":"eddsa-jcs-2022","proofPurpose":"assertionMethod","type":"DataIntegrityProof","verificationMethod":"did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2#z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2"}
+
+ +
+
+ Example 35: Hash of Canonical Proof Options Document (hex) +
66ab154f5c2890a140cb8388a22a160454f80575f6eae09e5a097cabe539a1db
+
+ +

+Finally, we concatenate the hash of the proof options followed by the hash of the credential without proof, use the private key with the combined hash to +compute the Ed25519 signature, and then base58-btc encode the signature. +

+ +
+
+ Example 36: Combine hashes of Proof Options and Credential (hex) +
66ab154f5c2890a140cb8388a22a160454f80575f6eae09e5a097cabe539a1db59b7cb6251b8991add1ce0bc83107e3db9dbbab5bd2c28f687db1a03abc92f19
+
+ +
+
+ Example 37: Signature of Combined Hashes (hex) +
407cd12654b33d718ecbb99179a1506daaa849450bf3fc523cce3e1c96f8b80351da3f253d725c6f00b07c9e5448d50b3ef78012b9ab54255116d069c6dd2808
+
+ +
+
+ Example 38: Signature of Combined Hashes base58-btc +
z2HnFSSPPBzR36zdDgK8PbEHeXbR56YF24jwMpt3R1eHXQzJDMWS93FCzpvJpwTWd3GAVFuUfjoJdcnTMuVor51aX
+
+ +

+Assemble the signed credential with the following two steps: +

+
    +
  1. +Add the proofValue field with the previously computed base58-btc +value to the proof options document. +
  2. +
  3. +Set the proof field of the credential to the augmented proof +option document. +
  4. +
+ +
+
+ Example 39: Signed Credential +
{
+  "@context": [
+    "https://www.w3.org/ns/credentials/v2",
+    "https://www.w3.org/ns/credentials/examples/v2"
+  ],
+  "id": "urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33",
+  "type": [
+    "VerifiableCredential",
+    "AlumniCredential"
+  ],
+  "name": "Alumni Credential",
+  "description": "A minimum viable example of an Alumni Credential.",
+  "issuer": "https://vc.example/issuers/5678",
+  "validFrom": "2023-01-01T00:00:00Z",
+  "credentialSubject": {
+    "id": "did:example:abcdefgh",
+    "alumniOf": "The School of Examples"
+  },
+  "proof": {
+    "type": "DataIntegrityProof",
+    "cryptosuite": "eddsa-jcs-2022",
+    "created": "2023-02-24T23:36:38Z",
+    "verificationMethod": "did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2#z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2",
+    "proofPurpose": "assertionMethod",
+    "@context": [
+      "https://www.w3.org/ns/credentials/v2",
+      "https://www.w3.org/ns/credentials/examples/v2"
+    ],
+    "proofValue": "z2HnFSSPPBzR36zdDgK8PbEHeXbR56YF24jwMpt3R1eHXQzJDMWS93FCzpvJpwTWd3GAVFuUfjoJdcnTMuVor51aX"
+  }
+}
+
+
+

B.4 Representation: Ed25519Signature2020

+ +

+The signer needs to generate a private/public key pair with the private key used +for signing and the public key made available for verification. The +representation of the public key, and the representation of the private key, +are shown below. +

+
+
+ Example 40: Private and Public keys for Signature +
{
+    publicKeyMultibase: "z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2",
+    secretKeyMultibase: "z3u2en7t5LR2WtQH5PfFqMqwVHBeXouLzo6haApm8XHqvjxq"
+}
+
+ +

+Signing begins with a credential without an attached proof, which is converted +to canonical form, and then hashed, as shown in the following three examples. +

+ +
+
+ Example 41: Credential without Proof +
{
+    "@context": [
+        "https://www.w3.org/ns/credentials/v2",
+        "https://www.w3.org/ns/credentials/examples/v2"
+    ],
+    "id": "urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33",
+    "type": ["VerifiableCredential", "AlumniCredential"],
+    "name": "Alumni Credential",
+    "description": "A minimum viable example of an Alumni Credential.",
+    "issuer": "https://vc.example/issuers/5678",
+    "validFrom": "2023-01-01T00:00:00Z",
+    "credentialSubject": {
+        "id": "did:example:abcdefgh",
+        "alumniOf": "The School of Examples"
+    }
+}
+
+ +
+
+ Example 42: Canonical Credential without Proof +
<did:example:abcdefgh> <https://www.w3.org/ns/credentials/examples#alumniOf> "The School of Examples" .
+<urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://www.w3.org/2018/credentials#VerifiableCredential> .
+<urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://www.w3.org/ns/credentials/examples#AlumniCredential> .
+<urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33> <https://schema.org/description> "A minimum viable example of an Alumni Credential." .
+<urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33> <https://schema.org/name> "Alumni Credential" .
+<urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33> <https://www.w3.org/2018/credentials#credentialSubject> <did:example:abcdefgh> .
+<urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33> <https://www.w3.org/2018/credentials#issuer> <https://vc.example/issuers/5678> .
+<urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33> <https://www.w3.org/2018/credentials#validFrom> "2023-01-01T00:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> .
+
+ + +
+
+ Example 43: Hash of Canonical Credential without Proof (hex) +
517744132ae165a5349155bef0bb0cf2258fff99dfe1dbd914b938d775a36017
+
+ +

+The next step is to take the proof options document, convert it to canonical form, +and obtain its hash, as shown in the next three examples. +

+ +
+
+ Example 44: Proof Options Document +
{
+  "type": "Ed25519Signature2020",
+  "created": "2023-02-24T23:36:38Z",
+  "verificationMethod": "did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2#z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2",
+  "proofPurpose": "assertionMethod",
+  "@context": [
+    "https://www.w3.org/ns/credentials/v2",
+    "https://www.w3.org/ns/credentials/examples/v2",
+    "https://w3id.org/security/suites/ed25519-2020/v1"
+  ]
+}
+
+ +
+
+ Example 45: Canonical Proof Options Document +
_:c14n0 <http://purl.org/dc/terms/created> "2023-02-24T23:36:38Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> .
+_:c14n0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://w3id.org/security#Ed25519Signature2020> .
+_:c14n0 <https://w3id.org/security#proofPurpose> <https://w3id.org/security#assertionMethod> .
+_:c14n0 <https://w3id.org/security#verificationMethod> <did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2#z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2> .
+
+ +
+
+ Example 46: Hash of Canonical Proof Options Document (hex) +
04e14bcf5727cba0c0aa04a04d22a56fef915d5f8f7756bb92ae67cb1d0c4847
+
+ +

+Finally, we concatenate the hash of the proof options followed by the hash of the credential without proof, use the private key with the combined hash to +compute the Ed25519 signature, and then base58-btc encode the signature. +

+ +
+
+ Example 47: Combine hashes of Proof Options and Credential (hex) +
04e14bcf5727cba0c0aa04a04d22a56fef915d5f8f7756bb92ae67cb1d0c4847517744132ae165a5349155bef0bb0cf2258fff99dfe1dbd914b938d775a36017
+
+ +
+
+ Example 48: Signature of Combined Hashes (hex) +
cd8d023e8a9b462d563bbbd24c4499d8172738eb3f5235d74f65971e9be36dd7f23a1e201791e9a6747e45b8fa877a984f51f591567365c4d8222ecad39be60c
+
+ +
+
+ Example 49: Signature of Combined Hashes base58-btc +
z57Mm1vboMtZiCyJ4aReZsv8co4Re64Y8GEjL1ZARzMbXZgkARFLqFs1P345NpPGG2hgCrS4nNdvJhpwnrNyG3kEF
+
+ +

Assemble the signed credential with the following two steps:

+
    +
  1. +Add the proofValue field with the previously computed base58-btc +value to the proof options document. +
  2. +
  3. +Set the proof field of the credential to the augmented proof +option document. +
  4. +
+ +
+
+ Example 50: Signed Credential +
{
+  "@context": [
+    "https://www.w3.org/ns/credentials/v2",
+    "https://www.w3.org/ns/credentials/examples/v2",
+    "https://w3id.org/security/suites/ed25519-2020/v1"
+  ],
+  "id": "urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33",
+  "type": [
+    "VerifiableCredential",
+    "AlumniCredential"
+  ],
+  "name": "Alumni Credential",
+  "description": "A minimum viable example of an Alumni Credential.",
+  "issuer": "https://vc.example/issuers/5678",
+  "validFrom": "2023-01-01T00:00:00Z",
+  "credentialSubject": {
+    "id": "did:example:abcdefgh",
+    "alumniOf": "The School of Examples"
+  },
+  "proof": {
+    "type": "Ed25519Signature2020",
+    "created": "2023-02-24T23:36:38Z",
+    "verificationMethod": "did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2#z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2",
+    "proofPurpose": "assertionMethod",
+    "proofValue": "z57Mm1vboMtZiCyJ4aReZsv8co4Re64Y8GEjL1ZARzMbXZgkARFLqFs1P345NpPGG2hgCrS4nNdvJhpwnrNyG3kEF"
+  }
+}
+
+
+

B.5 Proof Sets and Chains

+ +

+Proof sets and chains are defined in the [VC-DATA-INTEGRITY]. We +provide test vectors showing the creation of proof sets and chains with the +eddsa-rdfc-2022 cryptosuite. Multiple signers can be involved in the generation +of proof sets and chains so multiple public/private key pairs are needed. These +are shown below. +

+
+
+ Example 51: Public and Private Key Pairs +
{
+  "keyPair1": {
+    "publicKeyMultibase": "z6MktgKTsu1QhX6QPbyqG6geXdw6FQCZBPq7uQpieWbiQiG7",
+    "privateKeyMultibase": "z3u2W4YnTstS1nSSBAgZcYSJF43JuZ9uLV6bF38B1Bf8NugW"
+  },
+  "keyPair2": {
+    "publicKeyMultibase": "z6MkhWqdDBPojHA7cprTGTt5yHv5yUi1B8cnXn8ReLumkw6E",
+    "privateKeyMultibase": "z3u2cfp4Q17kMGhNCh348a3yw3cUBiWK6RXRzyJE54sixMFn"
+  },
+  "keyPair3": {
+    "publicKeyMultibase": "z6MkmEq87wkHCYnWnNZkigeDMGTN7oUw1upkhzd77KuXERS1",
+    "privateKeyMultibase": "z3u2Zr3tcDLBDQKGxVa9SRDFNLqNqPWsa8p9rWPvCEH6bADB"
+  },
+  "keyPair4": {
+    "publicKeyMultibase": "z6Mkm1S51iPHJvDEkJ9MRtxJmT8Pqo6wHipAFwBAjN83vntT",
+    "privateKeyMultibase": "z3u2ZTWiFwM17veUR7sXniY66Gf14SqMdpMLy7SW9x4EDdmw"
+  }
+}
+
+

+The original unsigned credential is shown below: +

+
+
+ Example 52: Unsigned Credential +
{
+    "@context": [
+        "https://www.w3.org/ns/credentials/v2",
+        "https://www.w3.org/ns/credentials/examples/v2"
+    ],
+    "id": "urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33",
+    "type": ["VerifiableCredential", "AlumniCredential"],
+    "name": "Alumni Credential",
+    "description": "A minimum viable example of an Alumni Credential.",
+    "issuer": "https://vc.example/issuers/5678",
+    "validFrom": "2023-01-01T00:00:00Z",
+    "credentialSubject": {
+        "id": "did:example:abcdefgh",
+        "alumniOf": "The School of Examples"
+    }
+}
+
+

B.5.1 Proof Set

+ +

+To demonstrate creating a proof set, we start with a document containing a +single proof and add another proof to it. The starting document is shown below and +contains a proof signed with keyPair1. +

+
+
+ Example 53: Starting Document for Proof Set +
{
+  "@context": [
+    "https://www.w3.org/ns/credentials/v2",
+    "https://www.w3.org/ns/credentials/examples/v2"
+  ],
+  "id": "urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33",
+  "type": [
+    "VerifiableCredential",
+    "AlumniCredential"
+  ],
+  "name": "Alumni Credential",
+  "description": "A minimum viable example of an Alumni Credential.",
+  "issuer": "https://vc.example/issuers/5678",
+  "validFrom": "2023-01-01T00:00:00Z",
+  "credentialSubject": {
+    "id": "did:example:abcdefgh",
+    "alumniOf": "The School of Examples"
+  },
+  "proof": {
+    "type": "DataIntegrityProof",
+    "id": "urn:uuid:26329423-bec9-4b2e-88cb-a7c7d9dc4544",
+    "cryptosuite": "eddsa-rdfc-2022",
+    "created": "2023-02-24T23:36:38Z",
+    "verificationMethod": "did:key:z6MktgKTsu1QhX6QPbyqG6geXdw6FQCZBPq7uQpieWbiQiG7#z6MktgKTsu1QhX6QPbyqG6geXdw6FQCZBPq7uQpieWbiQiG7",
+    "proofPurpose": "assertionMethod",
+    "proofValue": "z66vWyqwAghu52WbpRkCwFRTu6Msn92ArtjpJ3gGMSVoU5RADwBfszoDt1QWY8owqLPz4nTj7hAwV7xFti1p93zdr"
+  }
+}
+
+

+The options input to +Section 4.4: Add Proof Set/Chain in [VC-DATA-INTEGRITY] +is shown below. Note that it does not include a previousProof attribute since +we are constructing a proof set and not a chain. In addition, we will be using +keyPair2 for signing. +

+
+
+ Example 54: Proof Options for Set +
{
+  "type": "DataIntegrityProof",
+  "id": "urn:uuid:8cc9022b-6b14-4cf3-8571-74972c5feb54",
+  "cryptosuite": "eddsa-rdfc-2022",
+  "created": "2023-02-24T23:36:38Z",
+  "verificationMethod": "did:key:z6MkhWqdDBPojHA7cprTGTt5yHv5yUi1B8cnXn8ReLumkw6E#z6MkhWqdDBPojHA7cprTGTt5yHv5yUi1B8cnXn8ReLumkw6E",
+  "proofPurpose": "assertionMethod"
+}
+
+

+Per the algorithm of +Section 4.4: Add Proof Set/Chain in [VC-DATA-INTEGRITY], +we create an array variable, allProofs, and add the proof from the +starting document to it. Since there is no previousProof attribute, no +modification of unsignedDocument is needed prior to computing the signed proof +in step 6 of +Section 4.4: Add Proof Set/Chain in +[VC-DATA-INTEGRITY]. The signed proof configuration is shown below. +

+
+
+ Example 55: Signed Proof Options +
{
+  "type": "DataIntegrityProof",
+  "id": "urn:uuid:8cc9022b-6b14-4cf3-8571-74972c5feb54",
+  "cryptosuite": "eddsa-rdfc-2022",
+  "created": "2023-02-24T23:36:38Z",
+  "verificationMethod": "did:key:z6MkhWqdDBPojHA7cprTGTt5yHv5yUi1B8cnXn8ReLumkw6E#z6MkhWqdDBPojHA7cprTGTt5yHv5yUi1B8cnXn8ReLumkw6E",
+  "proofPurpose": "assertionMethod",
+  "proofValue": "z2scr94SNNrGpP2bE7ajvKWeUHm7HJ2edDkxpARvFAQ8V3USzwEzibqrXKaLHBrWostswsfvg82twQR88BgtnsrXY"
+}
+
+

+The signed proof options above gets appended to the allProofs +variable, which then gets set as the proof attribute of the unsigned document +to produce the final signed document as shown below. +

+
+
+ Example 56: Signed Proof Set +
{
+  "@context": [
+    "https://www.w3.org/ns/credentials/v2",
+    "https://www.w3.org/ns/credentials/examples/v2"
+  ],
+  "id": "urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33",
+  "type": [
+    "VerifiableCredential",
+    "AlumniCredential"
+  ],
+  "name": "Alumni Credential",
+  "description": "A minimum viable example of an Alumni Credential.",
+  "issuer": "https://vc.example/issuers/5678",
+  "validFrom": "2023-01-01T00:00:00Z",
+  "credentialSubject": {
+    "id": "did:example:abcdefgh",
+    "alumniOf": "The School of Examples"
+  },
+  "proof": [
+    {
+      "type": "DataIntegrityProof",
+      "id": "urn:uuid:26329423-bec9-4b2e-88cb-a7c7d9dc4544",
+      "cryptosuite": "eddsa-rdfc-2022",
+      "created": "2023-02-24T23:36:38Z",
+      "verificationMethod": "did:key:z6MktgKTsu1QhX6QPbyqG6geXdw6FQCZBPq7uQpieWbiQiG7#z6MktgKTsu1QhX6QPbyqG6geXdw6FQCZBPq7uQpieWbiQiG7",
+      "proofPurpose": "assertionMethod",
+      "proofValue": "z66vWyqwAghu52WbpRkCwFRTu6Msn92ArtjpJ3gGMSVoU5RADwBfszoDt1QWY8owqLPz4nTj7hAwV7xFti1p93zdr"
+    },
+    {
+      "type": "DataIntegrityProof",
+      "id": "urn:uuid:8cc9022b-6b14-4cf3-8571-74972c5feb54",
+      "cryptosuite": "eddsa-rdfc-2022",
+      "created": "2023-02-24T23:36:38Z",
+      "verificationMethod": "did:key:z6MkhWqdDBPojHA7cprTGTt5yHv5yUi1B8cnXn8ReLumkw6E#z6MkhWqdDBPojHA7cprTGTt5yHv5yUi1B8cnXn8ReLumkw6E",
+      "proofPurpose": "assertionMethod",
+      "proofValue": "z2scr94SNNrGpP2bE7ajvKWeUHm7HJ2edDkxpARvFAQ8V3USzwEzibqrXKaLHBrWostswsfvg82twQR88BgtnsrXY"
+    }
+  ]
+}
+
+
+ +

B.5.2 Proof Chain with Multiple Dependencies

+ +

+This collection of test vectors demonstrates the construction a proof chain. We +start with a document containing a proof set, i.e., our previous example, and +then add a new proof to the credential that has a dependency on the existing +proofs. This example also demonstrates the case where the previousProofs +attribute is an array. This example uses keyPair3 and the starting document is +given below. +

+
+
+ Example 57: Starting Document for Proof Chain +
{
+  "@context": [
+    "https://www.w3.org/ns/credentials/v2",
+    "https://www.w3.org/ns/credentials/examples/v2"
+  ],
+  "id": "urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33",
+  "type": [
+    "VerifiableCredential",
+    "AlumniCredential"
+  ],
+  "name": "Alumni Credential",
+  "description": "A minimum viable example of an Alumni Credential.",
+  "issuer": "https://vc.example/issuers/5678",
+  "validFrom": "2023-01-01T00:00:00Z",
+  "credentialSubject": {
+    "id": "did:example:abcdefgh",
+    "alumniOf": "The School of Examples"
+  },
+  "proof": [
+    {
+      "type": "DataIntegrityProof",
+      "id": "urn:uuid:26329423-bec9-4b2e-88cb-a7c7d9dc4544",
+      "cryptosuite": "eddsa-rdfc-2022",
+      "created": "2023-02-24T23:36:38Z",
+      "verificationMethod": "did:key:z6MktgKTsu1QhX6QPbyqG6geXdw6FQCZBPq7uQpieWbiQiG7#z6MktgKTsu1QhX6QPbyqG6geXdw6FQCZBPq7uQpieWbiQiG7",
+      "proofPurpose": "assertionMethod",
+      "proofValue": "z66vWyqwAghu52WbpRkCwFRTu6Msn92ArtjpJ3gGMSVoU5RADwBfszoDt1QWY8owqLPz4nTj7hAwV7xFti1p93zdr"
+    },
+    {
+      "type": "DataIntegrityProof",
+      "id": "urn:uuid:8cc9022b-6b14-4cf3-8571-74972c5feb54",
+      "cryptosuite": "eddsa-rdfc-2022",
+      "created": "2023-02-24T23:36:38Z",
+      "verificationMethod": "did:key:z6MkhWqdDBPojHA7cprTGTt5yHv5yUi1B8cnXn8ReLumkw6E#z6MkhWqdDBPojHA7cprTGTt5yHv5yUi1B8cnXn8ReLumkw6E",
+      "proofPurpose": "assertionMethod",
+      "proofValue": "z2scr94SNNrGpP2bE7ajvKWeUHm7HJ2edDkxpARvFAQ8V3USzwEzibqrXKaLHBrWostswsfvg82twQR88BgtnsrXY"
+    }
+  ]
+}
+
+

+The options input to +Section 4.4: Add Proof Set/Chain in [VC-DATA-INTEGRITY] +is shown below. Note that it includes a previousProof attribute since we are +constructing a proof chain. +

+
+
+ Example 58: Options for Proof Chain +
{
+  "type": "DataIntegrityProof",
+  "id": "urn:uuid:d94f792a-c546-4d06-b38a-da070ab56c23",
+  "cryptosuite": "eddsa-rdfc-2022",
+  "created": "2023-02-26T22:06:38Z",
+  "verificationMethod": "did:key:z6MkmEq87wkHCYnWnNZkigeDMGTN7oUw1upkhzd77KuXERS1#z6MkmEq87wkHCYnWnNZkigeDMGTN7oUw1upkhzd77KuXERS1",
+  "proofPurpose": "assertionMethod",
+  "previousProof": [
+    "urn:uuid:26329423-bec9-4b2e-88cb-a7c7d9dc4544",
+    "urn:uuid:8cc9022b-6b14-4cf3-8571-74972c5feb54"
+  ]
+}
+
+

+Per the algorithm of +Section 4.4: Add Proof Set/Chain in [VC-DATA-INTEGRITY], +we create an array variable, allProofs, and add the proofs from the +starting document to it. Since the options contains the previousProof +attribute, we compute the matchingProofs variable per step 4 +of Section 4.4: Add Proof +Set/Chain, and we set the +unsecuredDocument.proof equal to the matchingProofs. This +produces the document shown below. +

+
+
+ Example 59: Temporary Unsecured Document for Binding Previous Proofs +
{
+  "@context": [
+    "https://www.w3.org/ns/credentials/v2",
+    "https://www.w3.org/ns/credentials/examples/v2"
+  ],
+  "id": "urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33",
+  "type": [
+    "VerifiableCredential",
+    "AlumniCredential"
+  ],
+  "name": "Alumni Credential",
+  "description": "A minimum viable example of an Alumni Credential.",
+  "issuer": "https://vc.example/issuers/5678",
+  "validFrom": "2023-01-01T00:00:00Z",
+  "credentialSubject": {
+    "id": "did:example:abcdefgh",
+    "alumniOf": "The School of Examples"
+  },
+  "proof": [
+    {
+      "type": "DataIntegrityProof",
+      "id": "urn:uuid:26329423-bec9-4b2e-88cb-a7c7d9dc4544",
+      "cryptosuite": "eddsa-rdfc-2022",
+      "created": "2023-02-24T23:36:38Z",
+      "verificationMethod": "did:key:z6MktgKTsu1QhX6QPbyqG6geXdw6FQCZBPq7uQpieWbiQiG7#z6MktgKTsu1QhX6QPbyqG6geXdw6FQCZBPq7uQpieWbiQiG7",
+      "proofPurpose": "assertionMethod",
+      "proofValue": "z66vWyqwAghu52WbpRkCwFRTu6Msn92ArtjpJ3gGMSVoU5RADwBfszoDt1QWY8owqLPz4nTj7hAwV7xFti1p93zdr"
+    },
+    {
+      "type": "DataIntegrityProof",
+      "id": "urn:uuid:8cc9022b-6b14-4cf3-8571-74972c5feb54",
+      "cryptosuite": "eddsa-rdfc-2022",
+      "created": "2023-02-24T23:36:38Z",
+      "verificationMethod": "did:key:z6MkhWqdDBPojHA7cprTGTt5yHv5yUi1B8cnXn8ReLumkw6E#z6MkhWqdDBPojHA7cprTGTt5yHv5yUi1B8cnXn8ReLumkw6E",
+      "proofPurpose": "assertionMethod",
+      "proofValue": "z2scr94SNNrGpP2bE7ajvKWeUHm7HJ2edDkxpARvFAQ8V3USzwEzibqrXKaLHBrWostswsfvg82twQR88BgtnsrXY"
+    }
+  ]
+}
+
+

+In step 6, we use the previous document (unsecured document with previous proofs +added to it) to compute the proofValue attribute. This gives the signed +configuration options (proof) shown below: +

+
+
+ Example 60: Signed Configuration Options (proof) +
{
+  "type": "DataIntegrityProof",
+  "id": "urn:uuid:d94f792a-c546-4d06-b38a-da070ab56c23",
+  "cryptosuite": "eddsa-rdfc-2022",
+  "created": "2023-02-26T22:06:38Z",
+  "verificationMethod": "did:key:z6MkmEq87wkHCYnWnNZkigeDMGTN7oUw1upkhzd77KuXERS1#z6MkmEq87wkHCYnWnNZkigeDMGTN7oUw1upkhzd77KuXERS1",
+  "proofPurpose": "assertionMethod",
+  "previousProof": [
+    "urn:uuid:26329423-bec9-4b2e-88cb-a7c7d9dc4544",
+    "urn:uuid:8cc9022b-6b14-4cf3-8571-74972c5feb54"
+  ],
+  "proofValue": "zWaPeEvBAkhQpNQj8pknuvg5STcKnt3cvM9t4kAYeJETFjvVMSXEEjadC4uxC9fKCn6JHbjt6fj2fhoaVNynBm6J"
+}
+
+

+The signed proof options above gets appended to the allProofs +variable, which then gets set as the proof attribute of the unsigned document +to produce the final signed document as shown below. +

+
+
+ Example 61: Signed Proof Chain +
{
+  "@context": [
+    "https://www.w3.org/ns/credentials/v2",
+    "https://www.w3.org/ns/credentials/examples/v2"
+  ],
+  "id": "urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33",
+  "type": [
+    "VerifiableCredential",
+    "AlumniCredential"
+  ],
+  "name": "Alumni Credential",
+  "description": "A minimum viable example of an Alumni Credential.",
+  "issuer": "https://vc.example/issuers/5678",
+  "validFrom": "2023-01-01T00:00:00Z",
+  "credentialSubject": {
+    "id": "did:example:abcdefgh",
+    "alumniOf": "The School of Examples"
+  },
+  "proof": [
+    {
+      "type": "DataIntegrityProof",
+      "id": "urn:uuid:26329423-bec9-4b2e-88cb-a7c7d9dc4544",
+      "cryptosuite": "eddsa-rdfc-2022",
+      "created": "2023-02-24T23:36:38Z",
+      "verificationMethod": "did:key:z6MktgKTsu1QhX6QPbyqG6geXdw6FQCZBPq7uQpieWbiQiG7#z6MktgKTsu1QhX6QPbyqG6geXdw6FQCZBPq7uQpieWbiQiG7",
+      "proofPurpose": "assertionMethod",
+      "proofValue": "z66vWyqwAghu52WbpRkCwFRTu6Msn92ArtjpJ3gGMSVoU5RADwBfszoDt1QWY8owqLPz4nTj7hAwV7xFti1p93zdr"
+    },
+    {
+      "type": "DataIntegrityProof",
+      "id": "urn:uuid:8cc9022b-6b14-4cf3-8571-74972c5feb54",
+      "cryptosuite": "eddsa-rdfc-2022",
+      "created": "2023-02-24T23:36:38Z",
+      "verificationMethod": "did:key:z6MkhWqdDBPojHA7cprTGTt5yHv5yUi1B8cnXn8ReLumkw6E#z6MkhWqdDBPojHA7cprTGTt5yHv5yUi1B8cnXn8ReLumkw6E",
+      "proofPurpose": "assertionMethod",
+      "proofValue": "z2scr94SNNrGpP2bE7ajvKWeUHm7HJ2edDkxpARvFAQ8V3USzwEzibqrXKaLHBrWostswsfvg82twQR88BgtnsrXY"
+    },
+    {
+      "type": "DataIntegrityProof",
+      "id": "urn:uuid:d94f792a-c546-4d06-b38a-da070ab56c23",
+      "cryptosuite": "eddsa-rdfc-2022",
+      "created": "2023-02-26T22:06:38Z",
+      "verificationMethod": "did:key:z6MkmEq87wkHCYnWnNZkigeDMGTN7oUw1upkhzd77KuXERS1#z6MkmEq87wkHCYnWnNZkigeDMGTN7oUw1upkhzd77KuXERS1",
+      "proofPurpose": "assertionMethod",
+      "previousProof": [
+        "urn:uuid:26329423-bec9-4b2e-88cb-a7c7d9dc4544",
+        "urn:uuid:8cc9022b-6b14-4cf3-8571-74972c5feb54"
+      ],
+      "proofValue": "zWaPeEvBAkhQpNQj8pknuvg5STcKnt3cvM9t4kAYeJETFjvVMSXEEjadC4uxC9fKCn6JHbjt6fj2fhoaVNynBm6J"
+    }
+  ]
+}
+
+
+

B.5.3 Extended Proof Chain

+ +

+This collection of test vectors demonstrates construction of an extended proof +chain. We start with the output of the previous section and add an additional +proof that is dependent on one of the existing proofs. This example uses +keyPair4, and the starting document is given below. +

+
+
+ Example 62: Starting Document for Extended Proof Chain +
{
+  "@context": [
+    "https://www.w3.org/ns/credentials/v2",
+    "https://www.w3.org/ns/credentials/examples/v2"
+  ],
+  "id": "urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33",
+  "type": [
+    "VerifiableCredential",
+    "AlumniCredential"
+  ],
+  "name": "Alumni Credential",
+  "description": "A minimum viable example of an Alumni Credential.",
+  "issuer": "https://vc.example/issuers/5678",
+  "validFrom": "2023-01-01T00:00:00Z",
+  "credentialSubject": {
+    "id": "did:example:abcdefgh",
+    "alumniOf": "The School of Examples"
+  },
+  "proof": [
+    {
+      "type": "DataIntegrityProof",
+      "id": "urn:uuid:26329423-bec9-4b2e-88cb-a7c7d9dc4544",
+      "cryptosuite": "eddsa-rdfc-2022",
+      "created": "2023-02-24T23:36:38Z",
+      "verificationMethod": "did:key:z6MktgKTsu1QhX6QPbyqG6geXdw6FQCZBPq7uQpieWbiQiG7#z6MktgKTsu1QhX6QPbyqG6geXdw6FQCZBPq7uQpieWbiQiG7",
+      "proofPurpose": "assertionMethod",
+      "proofValue": "z66vWyqwAghu52WbpRkCwFRTu6Msn92ArtjpJ3gGMSVoU5RADwBfszoDt1QWY8owqLPz4nTj7hAwV7xFti1p93zdr"
+    },
+    {
+      "type": "DataIntegrityProof",
+      "id": "urn:uuid:8cc9022b-6b14-4cf3-8571-74972c5feb54",
+      "cryptosuite": "eddsa-rdfc-2022",
+      "created": "2023-02-24T23:36:38Z",
+      "verificationMethod": "did:key:z6MkhWqdDBPojHA7cprTGTt5yHv5yUi1B8cnXn8ReLumkw6E#z6MkhWqdDBPojHA7cprTGTt5yHv5yUi1B8cnXn8ReLumkw6E",
+      "proofPurpose": "assertionMethod",
+      "proofValue": "z2scr94SNNrGpP2bE7ajvKWeUHm7HJ2edDkxpARvFAQ8V3USzwEzibqrXKaLHBrWostswsfvg82twQR88BgtnsrXY"
+    },
+    {
+      "type": "DataIntegrityProof",
+      "id": "urn:uuid:d94f792a-c546-4d06-b38a-da070ab56c23",
+      "cryptosuite": "eddsa-rdfc-2022",
+      "created": "2023-02-26T22:06:38Z",
+      "verificationMethod": "did:key:z6MkmEq87wkHCYnWnNZkigeDMGTN7oUw1upkhzd77KuXERS1#z6MkmEq87wkHCYnWnNZkigeDMGTN7oUw1upkhzd77KuXERS1",
+      "proofPurpose": "assertionMethod",
+      "previousProof": [
+        "urn:uuid:26329423-bec9-4b2e-88cb-a7c7d9dc4544",
+        "urn:uuid:8cc9022b-6b14-4cf3-8571-74972c5feb54"
+      ],
+      "proofValue": "zWaPeEvBAkhQpNQj8pknuvg5STcKnt3cvM9t4kAYeJETFjvVMSXEEjadC4uxC9fKCn6JHbjt6fj2fhoaVNynBm6J"
+    }
+  ]
+}
+
+

+The options input to +Section 4.4: Add Proof Set/Chain in [VC-DATA-INTEGRITY] +is shown below. Note that it includes a previousProof attribute since we are +constructing a proof chain, however this time it is a single value. +

+
+
+ Example 63: Options for Extended Proof Chain +
{
+  "type": "DataIntegrityProof",
+  "cryptosuite": "eddsa-rdfc-2022",
+  "created": "2023-02-26T22:16:38Z",
+  "verificationMethod": "did:key:z6Mkm1S51iPHJvDEkJ9MRtxJmT8Pqo6wHipAFwBAjN83vntT#z6Mkm1S51iPHJvDEkJ9MRtxJmT8Pqo6wHipAFwBAjN83vntT",
+  "proofPurpose": "assertionMethod",
+  "previousProof": "urn:uuid:d94f792a-c546-4d06-b38a-da070ab56c23"
+}
+
+

+Per the algorithm of +Section 4.4: Add Proof Set/Chain in [VC-DATA-INTEGRITY], +we create an array variable, allProofs, and add the proofs from the +starting document to it. Since the options contains the previousProof +attribute, we compute the matchingProofs variable per step 4 +of Section 4.4: Add Proof +Set/Chain, and we set the +unsecuredDocument.proof equal to the matchingProofs. This +produces the document shown below. +

+
+
+ Example 64: Temporary Unsecured Document for Binding Previous Proofs (Extended Chain) +
{
+  "@context": [
+    "https://www.w3.org/ns/credentials/v2",
+    "https://www.w3.org/ns/credentials/examples/v2"
+  ],
+  "id": "urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33",
+  "type": [
+    "VerifiableCredential",
+    "AlumniCredential"
+  ],
+  "name": "Alumni Credential",
+  "description": "A minimum viable example of an Alumni Credential.",
+  "issuer": "https://vc.example/issuers/5678",
+  "validFrom": "2023-01-01T00:00:00Z",
+  "credentialSubject": {
+    "id": "did:example:abcdefgh",
+    "alumniOf": "The School of Examples"
+  },
+  "proof": [
+    {
+      "type": "DataIntegrityProof",
+      "id": "urn:uuid:d94f792a-c546-4d06-b38a-da070ab56c23",
+      "cryptosuite": "eddsa-rdfc-2022",
+      "created": "2023-02-26T22:06:38Z",
+      "verificationMethod": "did:key:z6MkmEq87wkHCYnWnNZkigeDMGTN7oUw1upkhzd77KuXERS1#z6MkmEq87wkHCYnWnNZkigeDMGTN7oUw1upkhzd77KuXERS1",
+      "proofPurpose": "assertionMethod",
+      "previousProof": [
+        "urn:uuid:26329423-bec9-4b2e-88cb-a7c7d9dc4544",
+        "urn:uuid:8cc9022b-6b14-4cf3-8571-74972c5feb54"
+      ],
+      "proofValue": "zWaPeEvBAkhQpNQj8pknuvg5STcKnt3cvM9t4kAYeJETFjvVMSXEEjadC4uxC9fKCn6JHbjt6fj2fhoaVNynBm6J"
+    }
+  ]
+}
+
+

+In step 6, we use the previous document (unsecured document with previous proofs +added to it) to compute the proofValue attribute. This gives the signed +configuration options (proof) shown below: +

+
+
+ Example 65: Signed Configuration Options (Extended) +
{
+  "type": "DataIntegrityProof",
+  "cryptosuite": "eddsa-rdfc-2022",
+  "created": "2023-02-26T22:16:38Z",
+  "verificationMethod": "did:key:z6Mkm1S51iPHJvDEkJ9MRtxJmT8Pqo6wHipAFwBAjN83vntT#z6Mkm1S51iPHJvDEkJ9MRtxJmT8Pqo6wHipAFwBAjN83vntT",
+  "proofPurpose": "assertionMethod",
+  "previousProof": "urn:uuid:d94f792a-c546-4d06-b38a-da070ab56c23",
+  "proofValue": "z4b5uUtxNiV4E541LiR8qLvA21xM1Vt4Hfn6nLmmDePdFvLB3jFj3HyEEJyRMbpJzv4Gfdr8ABeuRTxAvZv6KWRRh"
+}
+
+

+The signed proof options above gets appended to the allProofs +variable, which then gets set as the proof attribute of the unsigned document +to produce the final signed document as shown below. +

+
+
+ Example 66: Signed Proof Chain (Extended) +
{
+  "@context": [
+    "https://www.w3.org/ns/credentials/v2",
+    "https://www.w3.org/ns/credentials/examples/v2"
+  ],
+  "id": "urn:uuid:58172aac-d8ba-11ed-83dd-0b3aef56cc33",
+  "type": [
+    "VerifiableCredential",
+    "AlumniCredential"
+  ],
+  "name": "Alumni Credential",
+  "description": "A minimum viable example of an Alumni Credential.",
+  "issuer": "https://vc.example/issuers/5678",
+  "validFrom": "2023-01-01T00:00:00Z",
+  "credentialSubject": {
+    "id": "did:example:abcdefgh",
+    "alumniOf": "The School of Examples"
+  },
+  "proof": [
+    {
+      "type": "DataIntegrityProof",
+      "id": "urn:uuid:26329423-bec9-4b2e-88cb-a7c7d9dc4544",
+      "cryptosuite": "eddsa-rdfc-2022",
+      "created": "2023-02-24T23:36:38Z",
+      "verificationMethod": "did:key:z6MktgKTsu1QhX6QPbyqG6geXdw6FQCZBPq7uQpieWbiQiG7#z6MktgKTsu1QhX6QPbyqG6geXdw6FQCZBPq7uQpieWbiQiG7",
+      "proofPurpose": "assertionMethod",
+      "proofValue": "z66vWyqwAghu52WbpRkCwFRTu6Msn92ArtjpJ3gGMSVoU5RADwBfszoDt1QWY8owqLPz4nTj7hAwV7xFti1p93zdr"
+    },
+    {
+      "type": "DataIntegrityProof",
+      "id": "urn:uuid:8cc9022b-6b14-4cf3-8571-74972c5feb54",
+      "cryptosuite": "eddsa-rdfc-2022",
+      "created": "2023-02-24T23:36:38Z",
+      "verificationMethod": "did:key:z6MkhWqdDBPojHA7cprTGTt5yHv5yUi1B8cnXn8ReLumkw6E#z6MkhWqdDBPojHA7cprTGTt5yHv5yUi1B8cnXn8ReLumkw6E",
+      "proofPurpose": "assertionMethod",
+      "proofValue": "z2scr94SNNrGpP2bE7ajvKWeUHm7HJ2edDkxpARvFAQ8V3USzwEzibqrXKaLHBrWostswsfvg82twQR88BgtnsrXY"
+    },
+    {
+      "type": "DataIntegrityProof",
+      "id": "urn:uuid:d94f792a-c546-4d06-b38a-da070ab56c23",
+      "cryptosuite": "eddsa-rdfc-2022",
+      "created": "2023-02-26T22:06:38Z",
+      "verificationMethod": "did:key:z6MkmEq87wkHCYnWnNZkigeDMGTN7oUw1upkhzd77KuXERS1#z6MkmEq87wkHCYnWnNZkigeDMGTN7oUw1upkhzd77KuXERS1",
+      "proofPurpose": "assertionMethod",
+      "previousProof": [
+        "urn:uuid:26329423-bec9-4b2e-88cb-a7c7d9dc4544",
+        "urn:uuid:8cc9022b-6b14-4cf3-8571-74972c5feb54"
+      ],
+      "proofValue": "zWaPeEvBAkhQpNQj8pknuvg5STcKnt3cvM9t4kAYeJETFjvVMSXEEjadC4uxC9fKCn6JHbjt6fj2fhoaVNynBm6J"
+    },
+    {
+      "type": "DataIntegrityProof",
+      "cryptosuite": "eddsa-rdfc-2022",
+      "created": "2023-02-26T22:16:38Z",
+      "verificationMethod": "did:key:z6Mkm1S51iPHJvDEkJ9MRtxJmT8Pqo6wHipAFwBAjN83vntT#z6Mkm1S51iPHJvDEkJ9MRtxJmT8Pqo6wHipAFwBAjN83vntT",
+      "proofPurpose": "assertionMethod",
+      "previousProof": "urn:uuid:d94f792a-c546-4d06-b38a-da070ab56c23",
+      "proofValue": "z4b5uUtxNiV4E541LiR8qLvA21xM1Vt4Hfn6nLmmDePdFvLB3jFj3HyEEJyRMbpJzv4Gfdr8ABeuRTxAvZv6KWRRh"
+    }
+  ]
+}
+
+
+
+
+ +

C. Revision History

This section is non-normative.

+ + +

+This section contains the substantive changes that have been made to this +specification over time. +

+ +

+Changes since the + +First Candidate Recommendation: +

+ + + +

+Changes since the + +First Public Working Draft: +

+ + +
+ + +

D. Acknowledgements

This section is non-normative.

+ + +

+Work on this specification has been supported by the Rebooting the Web of Trust +community facilitated by Christopher Allen, Shannon Appelcline, Kiara Robles, +Brian Weller, Betty Dhamers, Kaliya Young, Manu Sporny, Drummond Reed, Joe +Andrieu, Heather Vescent, Kim Hamilton Duffy, Samantha Chase, Andrew Hughes, +Erica Connell, Shigeya Suzuki, Zaïda Rivai, Will Abramson, and Eric Schuh. The +participants in the Internet Identity Workshop, facilitated by Phil Windley, +Kaliya Young, Doc Searls, and Heidi Nobantu Saul, also supported the refinement +of this work through numerous working sessions designed to educate about, debate +on, and improve this specification. +

+ +

+The Working Group also thanks our Working Group Chair Brent Zundel, and ex-chair +Kristina Yasuda, as well as our W3C Staff Contact, Ivan Herman, for their expert +management and steady guidance of the group through the W3C standardization +cycle. We also thank the Chairs of the W3C Credentials Community Group, +Christopher Allen, Joe Andrieu, Kim Hamilton Duffy, Heather Vescent, Wayne +Chang, Mike Prorock, Harrison Tang, Kimberly Wilson Linson, and Will Abramson, +who oversaw the incubation of this work. +

+ +

+Portions of the work on this specification have been funded by the United States +Department of Homeland Security's Science and Technology Directorate under +contracts 70RSAT20T00000029, 70RSAT21T00000016, 70RSAT23T00000005, +70RSAT20T00000010/P00001, 70RSAT20T00000029, 70RSAT21T00000016/P00001, +70RSAT23T00000005, 70RSAT23C00000030, 70RSAT23R00000006, 70RSAT24T00000011, and +the National Science Foundation through NSF 22-572. The content of this +specification does not necessarily reflect the position or the policy of the +U.S. Government and no official endorsement should be inferred. +

+ +

+The Working Group would like to thank the following individuals for reviewing +and providing feedback on and implementations of the specification +(in alphabetical order by last name): +

+ +

+Greg Bernstein, +Simon Bihel, +Sebastian Crane, +Stas Dmytryshyn, +Tashi D. Gyeltshen, +Ivan Herman, +Andrew Jones, +Filip Kolarik, +Helge Krueger, +Dominik Kuziński, +Charles E. Lehner, +Dave Longley, +Tyler Minard, +Bryan Newbold, +Marty Reed, +Brian Richter, +Eugeniu Rusu, +Markus Sabadello, +Pritam Singh, +Patrick St. Louis, +Manu Sporny, +Orie Steele, +Ted Thibodeau Jr., +Benjamin Young, and +Dmitri Zagidulin. +

+ +
+ + + +

E. References

E.1 Normative references

+ +
[CONTROLLER-DOCUMENT]
+ Controlled Identifiers (CIDs) v1.0. Manu Sporny; Michael Jones. W3C. 26 January 2025. W3C Working Draft. URL: https://www.w3.org/TR/controller-document/ +
[FIPS-186-5]
+ FIPS PUB 186-5: Digital Signature Standard (DSS). U.S. Department of Commerce/National Institute of Standards and Technology. 3 February 2023. National Standard. URL: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf +
[INFRA]
+ Infra Standard. Anne van Kesteren; Domenic Denicola. WHATWG. Living Standard. URL: https://infra.spec.whatwg.org/ +
[JSON-LD11-API]
+ JSON-LD 1.1 Processing Algorithms and API. Gregg Kellogg; Dave Longley; Pierre-Antoine Champin. W3C. 16 July 2020. W3C Recommendation. URL: https://www.w3.org/TR/json-ld11-api/ +
[RDF-CANON]
+ RDF Dataset Canonicalization. Gregg Kellogg; Dave Longley; Dan Yamamoto. W3C. 21 May 2024. W3C Recommendation. URL: https://www.w3.org/TR/rdf-canon/ +
[RFC2119]
+ Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. March 1997. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc2119 +
[RFC6234]
+ US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF). D. Eastlake 3rd; T. Hansen. IETF. May 2011. Informational. URL: https://www.rfc-editor.org/rfc/rfc6234 +
[RFC8032]
+ Edwards-Curve Digital Signature Algorithm (EdDSA). S. Josefsson; I. Liusvaara. IETF. January 2017. Informational. URL: https://www.rfc-editor.org/rfc/rfc8032 +
[RFC8174]
+ Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words. B. Leiba. IETF. May 2017. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc8174 +
[RFC8785]
+ JSON Canonicalization Scheme (JCS). A. Rundgren; B. Jordan; S. Erdtman. IETF. June 2020. Informational. URL: https://www.rfc-editor.org/rfc/rfc8785 +
[VC-DATA-INTEGRITY]
+ Verifiable Credential Data Integrity 1.0. Manu Sporny; Ted Thibodeau Jr; Ivan Herman; Dave Longley; Greg Bernstein. W3C. 26 January 2025. CRD. URL: https://www.w3.org/TR/vc-data-integrity/ +
[vc-data-model-2.0]
+ Verifiable Credentials Data Model v2.0. Manu Sporny; Ted Thibodeau Jr; Ivan Herman; Gabe Cohen; Michael Jones. W3C. 27 January 2025. CRD. URL: https://www.w3.org/TR/vc-data-model-2.0/ +
[XMLSCHEMA11-2]
+ W3C XML Schema Definition Language (XSD) 1.1 Part 2: Datatypes. David Peterson; Sandy Gao; Ashok Malhotra; Michael Sperberg-McQueen; Henry Thompson; Paul V. Biron et al. W3C. 5 April 2012. W3C Recommendation. URL: https://www.w3.org/TR/xmlschema11-2/ +
+

E.2 Informative references

+ +
[Provable_Ed25519]
+ The Provable Security of Ed25519: Theory and Practice. Jacqueline Brendel; Cas Cremers; Dennis Jackson; Mang Zhao. Cryptology ePrint Archive, Paper 2020/823. 2020. URL: https://eprint.iacr.org/2020/823 +
[Taming_EdDSAs]
+ Taming the many EdDSAs. Konstantinos Chalkias; François Garillot; Valeria Nikolaenko. Cryptology ePrint Archive, Paper 2020/1244. 2020. URL: https://eprint.iacr.org/2020/1244 +
[VC-DI-BBS]
+ Data Integrity BBS Cryptosuites v1.0. Greg Bernstein; Manu Sporny. W3C. 15 October 2024. CRD. URL: https://www.w3.org/TR/vc-di-bbs/ +
[VC-DI-ECDSA]
+ Data Integrity ECDSA Cryptosuites v1.0. Manu Sporny; Dave Longley; Greg Bernstein. W3C. 26 January 2025. CRD. URL: https://www.w3.org/TR/vc-di-ecdsa/ +
+
\ No newline at end of file