diff --git a/index.html b/index.html index e7f9476..b92355c 100644 --- a/index.html +++ b/index.html @@ -410,7 +410,7 @@

DataIntegrityProof

The `proofValue` property of the proof MUST be an ECDSA or deterministic ECDSA signature produced according to [[FIPS-186-5]] using the curves and hashes as -specified in section , encoded according to section 7 +specified in section , encoded according to section 7 of [[RFC4754]] (sometimes referred to as the IEEE P1363 format), and serialized according to [[MULTIBASE]] using the base58-btc base encoding.

@@ -1020,6 +1020,1788 @@

Proof Verification (jcs-ecdsa-2019)

+
+

jcs-ecdsa-2019

+ +

+The `jcs-ecdsa-2019` 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. The algorithms in this +section also include the verification of such a data integrity proof. +

+ +
+

Add Proof (jcs-ecdsa-2019)

+ +

+To generate a proof, the algorithm in + +Section 4.1: Add Proof of the Data Integrity +[[VC-DATA-INTEGRITY]] specification MUST be executed. +For that algorithm, the cryptographic suite-specific + +transformation algorithm is defined in Section +, the + +hashing algorithm is defined in Section , +and the + +proof serialization algorithm is defined in Section +. +

+
+ +
+

Verify Proof (jcs-ecdsa-2019)

+ +

+To verify a proof, the algorithm in + +Section 4.2: Verify Proof of the Data Integrity +[[VC-DATA-INTEGRITY]] specification MUST be executed. +For that algorithm, the cryptographic suite-specific + +transformation algorithm is defined in Section +, the + +hashing algorithm is defined in Section , +and the + +proof verification algorithm is defined in Section +. +

+
+ +
+

Transformation (jcs-ecdsa-2019)

+ +

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

+ +

+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 `jcs-ecdsa-2019`, then a `PROOF_TRANSFORMATION_ERROR` MUST be +raised. +
  2. +
  3. +Let canonicalDocument be the result of applying the +JSON Canonicalization Scheme [[RFC8785]] to the unsecuredDocument. +
  4. +
  5. +Set output to the value of canonicalDocument. +
  6. +
  7. +Return canonicalDocument as the transformed data document. +
  8. +
+
+ +
+

Hashing (jcs-ecdsa-2019)

+ +

+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 or +Section . One must use the +hash algorithm appropriate in security level to the curve used, i.e., for curve +P-256 one uses SHA-256, and for curve P-384 one uses SHA-384. +

+ +

+The required inputs to this algorithm are a transformed data document +(transformedDocument) and a 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) or SHA-384 (SHA-2 with 384-bit output) +cryptographic hashing algorithm [[RFC6234]] to the +respective curve P-256 or curve P-384 transformedDocument. +Respective transformedDocumentHash will be exactly 32 or 48 bytes +in size. +
  2. +
  3. +Let proofConfigHash be the result of applying the SHA-256 +(SHA-2 with 256-bit output) or SHA-384 (SHA-2 with 384-bit output) +cryptographic hashing algorithm [[RFC6234]] to the +respective curve P-256 or curve P-384 canonicalProofConfig. +Respective proofConfigHash will be exactly 32 or 48 bytes in size. +
  4. +
  5. +Let hashData be the result of concatenating proofConfigHash (the +first hash) followed by transformedDocumentHash (the second hash). +
  6. +
  7. +Return hashData as the hash data. +
  8. +
+ +
+ +
+

Proof Configuration (jcs-ecdsa-2019)

+ +

+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 an empty object. +
  2. +
  3. +Set proofConfig.type to +options.type. +
  4. +
  5. +If options.cryptosuite is set, set +proofConfig.cryptosuite to its value. +
  6. +
  7. +If options.type is not set to `DataIntegrityProof` and +proofConfig.cryptosuite is not set to `jcs-ecdsa-2019`, an +`INVALID_PROOF_CONFIGURATION` error MUST be raised. +
  8. +
  9. +Set proofConfig.created to +options.created. If the value is not a valid +[[XMLSCHEMA11-2]] datetime, an `INVALID_PROOF_DATETIME` error MUST be raised. +
  10. +
  11. +Set proofConfig.verificationMethod to +options.verificationMethod. +
  12. +
  13. +Set proofConfig.proofPurpose to +options.proofPurpose. +
  14. +
  15. +Let canonicalProofConfig be the result of applying the +JSON Canonicalization Scheme [[RFC8785]] to the proofConfig. +
  16. +
  17. +Return canonicalProofConfig. +
  18. +
+ +
+ +
+

Proof Serialization (jcs-ecdsa-2019)

+ +

+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 Elliptic Curve Digital +Signature Algorithm (ECDSA) [[FIPS-186-5]], with hashData as the data +to be signed using the private key specified by privateKeyBytes. +proofBytes will be exactly 64 bytes in size for a P-256 key, and +96 bytes in size for a P-384 key. +
  4. +
  5. +Return proofBytes as the digital proof. +
  6. +
+ +
+ +
+

Proof Verification (jcs-ecdsa-2019)

+ +

+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, Elliptic Curve Digital Signature Algorithm (ECDSA) [[FIPS-186-5]], +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. +
+ +
+
+ +
+

Selective Disclosure Functions

+ +

+The Working Group is seeking implementer feedback on these generalized selective +disclosure functions as well as horizonal security review on the features from +parties at W3C and IETF. Those reviews might result in significant changes to +these functions, migration of these functions to the core Data Integrity +specification (for use by other cryptographic suites), or the removal of the +algorithm from the specification during the Candidate Recommendation phase. +

+ +

+The following section contains a set of functions that are used throughout +cryptographic suites that perform selective disclosure. +

+ +
+

labelReplacementCanonize

+ +

+The following algorithm canonizes a JSON-LD document and replaces any blank node +identifiers in the canonicalized document by applying a label replacement +function, labelReplacementFunction. The required inputs are a JSON-LD +document (document) and a label replacement functon +(labelReplacementFunction). A N-Quads representation of the +canonized result, with the replaced blank node labels, and a map from +the old blank node IDs to the new blank node IDs, bnodeIdMap, is +produced as output. +

+ +
    +
  1. +Run the RDF Dataset Canonicalization Algorithm [[RDF-CANON]] on +document, passing any custom options (such as a document loader), and +get the canonicalized dataset as output, which includes a canonical bnode +identifier map, canonicalIdMap. +
  2. +
  3. +Pass canonicalIdMap to labelReplacementFunction to produce +a new bnode identifier map, bnodeIdMap. +
  4. +
  5. +Produce canonical N-Quads representation, canonized result, using +canonicalized dataset along with bnodeIdMap and return it. +
  6. +
+ +
+ +
+

hmacIdCanonize

+ +

+The following algorithm creates a label replacement function that uses an +HMAC to replace canonical blank node identifiers with their encoded HMAC +digests. The required inputs are a canonical node identifier map, +canonicalIdMap. A blank node identifier map, bnodeIdMap, is +produced as output. +

+ +
    +
  1. +Generate a new empty bnode identifier map, bnodeIdMap. +
  2. +
  3. +For each map entry in canonicalIdMap: +
      +
    1. +HMAC the canonical identifier from the entry to get an HMAC digest, +digest. +
    2. +
    3. +Generate a new string value, b64urlDigest, and initialize it to "u" +followed by appending a base64url-no-pad encoded version of the digest +value. +
    4. +
    5. +Add this new entry to bnodeIdMap. +
    6. +
    +
  4. +
  5. +Return bnodeIdMap. +
  6. +
+ +

+A different primitive could be created that sorted the resulting HMAC digests +and assigned labels using a prefix and integers based on their sorted order +instead. This primitive might be useful for index-based selective disclosure +schemes such as BBS. +

+ +
+ +
+

labelMapCanonize

+ +

+The following algorithm creates a label replacement function that uses a label +map to replace canonical blank node identifiers with the associated value from +the labeel map. The required inputs are a label map, labelMap. A +function, labelMapReplacementFunction, is produced as output. +

+ +
    +
  1. +Set labelMapReplacementFunction to a function that returns the +reverse of labelMap. +
  2. +
  3. +Return labelMapReplacementFunction. +
  4. +
+
+ +
+

skolemize

+ +

+The following algorithm replaces all blank node identifiers in an array of +N-Quad statements with a URN. The required inputs are an array of N-Quad strings +(inputNquads) and a URN scheme (urnScheme). An array of +N-Quad strings, skolemizedNquads, is produced as output. +

+ +
    +
  1. +Create a new array of N-Quad strings, skolemizedNquads. +
  2. +
  3. +For each N-Quad string, s1, in the input array: +
      +
    1. +Create a new string, s2, that is a copy of s1 replacing any +occurrence of a blank node identifier with a URN ("urn:"), plus the input +custom scheme (urnScheme), plus a colon (":"), and +the value of the blank node identifier. For example, a regular expression +of a similar form to the following would achieve the desired result: +s1.replace(/(_:([^\s]+))/g, '<urn:custom-scheme:$2>'). +
    2. +
    3. +Append s2 to skolemizedNquads. +
    4. +
    +
  4. +Return skolemizedNquads. +
  5. +
+
+ +
+

deskolemize

+ +

+The following algorithm replaces all custom scheme URNs in an array of +N-Quad statements with a blank node identifier. The required inputs are an array of N-Quad strings +(inputNquads) and a URN scheme (urnScheme). An array of +N-Quad strings, deskolemizedNquads, is produced as output. +

+ +
    +
  1. +Create a new array of N-Quad strings, deskolemizedNquads. +
  2. +
  3. +For each N-Quad string, s1, in the inputNquads array: +
      +
    1. +Create a new string, s2, that is a copy of s1 replacing any +occurrence of a URN ("urn:"), plus the input +custom scheme (urnScheme), plus a colon (":"), and +the value of the blank node identifier with a blank node prefix ("_:"), plus +the value of the blank node identifier. For example, a regular expression +of a similar form to the following would achieve the desired result: +s1.replace(/(<urn:custom-scheme:([^>]+)>)/g, '_:$2').. +
    2. +
    3. +Append s2 to deskolemizedNquads. +
    4. +
    +
  4. +Return deskolemizedNquads. +
  5. +
+
+ +
+

toSkolemizedJSONLD

+ +

+The following algorithm converts an array of N-Quads to a skolemized +JSON-LD document. The required inputs are an array of N-Quad strings +(inputNquads). A JSON-LD document, skolemizedJSONLD, is +produced as output. +

+ +
    +
  1. +Initialize `skolemizedQuads` to the result of calling the algorithm in +Section , with inputNQuads and +"custom-scheme" as parameters. Implementations MAY choose a different +urnSchemeName that is different than "custom-scheme" so long as the +same scheme name is used in the algorithm in Section +. +
  2. +
  3. +Join `skolemizedQuads` into a single N-Quads string, `dataset`. +
  4. +
  5. +Set skolemizedJSONLD to the result of the + +Serialize RDF as JSON-LD algorithm, passing any custom options (such as a +document loader), to convert `dataset` from RDF to a JSON-LD document. +
  6. +
  7. +Return skolemizedJSONLD. +
  8. +
+
+ +
+

toDeskolemizedRDF

+ +

+The following algorithm converts a skolemized JSON-LD document, such as one +created using the algorithm in Section , to an +array of deskolemized N-Quads. The required inputs are a JSON-LD document, +skolemizedJSONLD. An array of deskolemized N-Quad strings +(outputNquads) is produced as output. +

+ +
    +
  1. +Initialize `skolemizedDataset` to the result of calling the + +Deserialize JSON-LD to RDF algorithm, passing any custom options (such as a +document loader), to convert `skolemizedJSONLD` from JSON-LD to RDF in N-Quads +format. +
  2. +
  3. +Split `skolemizedDataset` into an array of individual N-Quads, +`skolemizedNquads`. +
  4. +
  5. +Set outputNquads to the result of calling the algorithm in Section + with `skolemizedNquads` and "custom-scheme" as +parameters. Implementations MAY choose a different urnSchemeName that +is different than "custom-scheme" so long as the same scheme name is used in +the algorithm in Section . +
  6. +
  7. +Return outputNquads. +
  8. +
+
+ +
+

jsonPointerToPaths

+ +

+The following algorithm converts a JSON Pointer [[RFC6901]] to an array of paths +into a JSON tree. The required input is a JSON Pointer string +(pointer). An array of paths (paths) is produced as output. +

+ +
    +
  1. +Initialize `paths` to an empty array. +
  2. +
  3. +Initialize `splitPath` to an array by splitting pointer on the +"/" character and skipping the first, empty, split element. In Javascript +notation, this step is equivalent to the following code: +`pointer.split('/').slice(1)` +
  4. +
  5. +For each `path` in `splitPath`: +
      +
    1. +If `path` does not include `~`, then add `path` to `paths`, converting it to +an integer if it parses as one, leaving it as a string if it does not. +
    2. +
    3. +Otherwise, unescape any JSON pointer escape sequences in `path` and add the +result to `paths`. +
    4. +
    +
  6. +
  7. +Return `paths`. +
  8. +
+
+ +
+

createInitialFrame

+ +

+The following algorithm creates an initial JSON-LD frame based on a JSON-LD +object. This is a helper function used within the algorithm in +Section . The required input is a +JSON-LD object (value). A JSON-LD frame frame is produced +as output. +

+ +
    +
  1. +Initialize frame to an empty object. +
  2. +
  3. +If value has an `id` that is not a blank node identifier, set +`frame.id` to its value. Note: All non-blank node identifiers in the path of +any JSON Pointer MUST be included in the frame, this includes any root document +identifier. +
  4. +
  5. +If value.`type` is set, set frame.`type` to its value. +Note: All `type`s in the path of any JSON Pointer MUST be included in the frame, +this includes any root document `type`. +
  6. +
  7. +Return frame. +
  8. +
+
+ +
+

jsonPointersToFrame

+ +

+The following algorithm converts an array of JSON Pointers and a JSON-LD +document to a JSON-LD Frame to be used on that specific document. The required +input is an array of JSON Pointers (pointers) and a JSON-LD document +(document). A JSON-LD frame (frame) is produced as output. +

+ +
    +
  1. +If `pointers` is empty, return `null`. +
  2. +
  3. +Initialize `frame` to an initial frame passing `document` as `value` to +the algorithm in Section . +
  4. +
  5. +For each `pointer` in `pointers` walk the document from root to the pointer +target value building the frame: +
  6. +
      +
    1. +Initialize `parentFrame` to `frame`. +
    2. +
    3. +Initialize `parentValue` to `document`. +
    4. +
    5. +Initialize `value` to `parentValue`. +
    6. +
    7. +Initialize `valueFrame` to `parentFrame`. +
    8. +
    9. +Parse the `pointer` into an array of `paths` using the algorithm in +Section . +
    10. +
    11. +For each `path` in `paths`: +
    12. +
        +
      1. +Set `parentFrame` to `valueFrame`. +
      2. +
      3. +Set `parentValue` to `value`. +
      4. +
      5. +Set `value` to `parentValue[path]`. If `value` is now undefined, throw an error +indicating that the JSON pointer does not match the given `document`. +
      6. +
      7. +Set `valueFrame` to `parentFrame[path]`. +
      8. +
      9. +If `valueFrame` is undefined: +
      10. +
          +
        1. +If `value` is an array, set `valueFrame` to an empty array. +
        2. +
        3. +Otherwise, set `valueFrame` to an initial frame passing `value` to +the algorithm in Section . +
        4. +
        5. +Set `parentFrame[path]` to `valueFrame`. +
        6. +
        +
      +
    13. +Note: Next we generate the final `valueFrame`. +
    14. +
    15. +If `value` is not an object, then a literal has been selected: Set `valueFrame` +to `value`. +
    16. +
    17. +Otherwise, if `value` is an array: Set `valueFrame` to the result of mapping +every element in `value` to a deep copy of itself. If any element in `value` is +also an `array`, throw an error indicating that arrays of arrays are not +supported. +
    18. +
    19. +Otherwise: Set `valueFrame` to an object that merges a shallow copy of +`valueFrame` with a deep copy of `value`, e.g., `{...valueFrame, +…deepCopy(value)}`. +
    20. +
    21. +If `paths` has a length of zero, then the whole `document` has been selected by +the `pointer`: Set `frame` to `valueFrame`. +
    22. +
    23. +Otherwise, a partial selection has been made by the pointer: +
        +
      1. +Get the last `path`, `lastPath`, from `paths`. +
      2. +
      3. +Set `parentFrame[lastPath]` to `valueFrame`. +
      4. +
      +
    24. +Set `frame['@context']` to a deep copy of `document['@context']`. +
    25. +
    26. +Return `frame`. +
    27. +
    +
+
+ +
+

strictFrame

+ +

+The following algorithm performs a JSON-LD framing operation on a JSON-LD +document with strict framing options. The required inputs are a JSON-LD Document +(document) and a JSON-LD Frame (frame). A JSON-LD document +(framedDocument) is generated as output. +

+ +
    +
  1. +Set framedDocument to the result of the + +JSON-LD Framing algorithm, passing `document` and `frame`, and setting the +options `requireAll`, `explicit`, and `omitGraph` to `true`. Any additional +custom options passed, such as a document loader, is included as well. +
  2. +
  3. +Return framedDocument. +
  4. +
+
+ +
+

groupNquads

+ +

+The following algorithm groups N-Quads into matching and non-matching groups. +The inputs are an array of N-Quads (nquads, an optional skolemized +JSON-LD document (skolemizedDocument), an optional JSON-LD frame +(frame) , and any options, such as a document loader, to be passed to +JSON-LD APIs. Each of the output groups (matching and non-matching) are +expressed as a map that maps an index into nquads to the N-Quad value. +This algorithm uses a JSON-LD frame to match specific N-Quads in the array of +given nquads. It internally skolemizes and then deskolemizes any +blank nodes around the framing operation to ensure blank node identifiers do not +change, preventing the matching operation from working properly. +An object containing a matching and nonmatching arrays of +N-Quads are generated as output. +

+ +
    +
  1. +Initialize `matching` to an empty map. +
  2. +
  3. +Initialize `nonMatching` to an empty map. +
  4. +
  5. +If `frame` is not given or `null`, then there are no matches so: +
      +
    1. +Add each entry (index, element) in `nquads` to `nonMatching`. +
    2. +
    3. +Return an object with "matching" set to `matching` and "nonMatching" set to +`nonMatching`. +
    4. +
    +
  6. +
  7. +If `skolemizedDocument` has not been given: Set `skolemizedDocument` to the +result of calling "createSkolemizedDocument", passing `nquads` and any custom +JSON-LD API options (such as a document loader). +
  8. +
  9. +Initialize `framed` to the result of calling "strictFrame", passing +`skolemizedDocument`, `frame`, and any custom JSON-LD API options. Note: This +step filters the skolemized document to get only data that matches the frame as +a new JSON-LD document. +
  10. +
  11. +Initialize `matchingDeskolemized` to the result of calling "toDeskolemizedRDF", +passing `framed` and any custom JSON-LD API options. Note: This step converts +any matching data back to deskolemized N-Quads, matching their original +expression. +
  12. +
  13. +For each entry (`index`, `nq`) in `nquads`: +
      +
    1. +If `matchingDeskolemized` includes `nq`, add the entry to `matching`. +
    2. +
    3. +Otherwise, add the entry to `nonMatching`. +
    4. +
    +
  14. +
  15. +Return an object with "matching" set to `matching` and "nonMatching" set to +`nonMatching`. +
  16. +
+
+ +
+

filterAndGroupNquads

+ +

+The following algorithm filters N-Quads, given in an array of N-Quads and a +JSON-LD filtering frame, and then groups the N-Quads that passed the filter into +matching and non-matching groups based on another JSON-LD grouping frame. This +function will internally perform skolemization and deskolemization around +framing operations to ensure that any blank node identifiers do not change, +which would prevent filtering and matching operations from working properly. The +inputs to the algorithm are an array of N-Quads (nquads), a JSON-LD +filtering frame (filterFrame), a JSON-LD grouping frame +(groupFrame). Additionally, any custom JSON-LD API options are +expected to be given as an input. An object containing two properties is +provided as output; matching and nonmatching each hold arrays +of their associated N-Quads. +

+ +
    +
  1. +Initialize `skolemizedDocument` to the result of calling the algorithm in +Section , passing `nquads` and any custom +JSON-LD API options (such as a document loader). +
  2. +
  3. +Initialize `filteredDocument` to the result of calling the algorithm in Section +, passing `skolemizedDocument`, `filterFrame`, and +any custom JSON-LD API options. +
  4. +
  5. +Initialize `filteredNQuads` to the result of calling the algorithm in Section , passing `filteredDocument` and any custom +JSON-LD API options. +
  6. +
  7. +Note: These next two steps can be performed in parallel. +
  8. +
      +
    1. +Get the canonical blank node identifier map, `canonicalIdMap`, by calling +[[RDF-CANON]], passing the joined `filteredNQuads`. Canonicalize `filteredNQuads +Note: These two steps can be performed in parallel. +
    2. +
    3. +Get the `groupResult` by calling the algorithm in Section +, passing `filteredNQuads`, `filteredDocument`, +`groupFrame`, and any custom JSON-LD API options. +
    4. +
    +
  9. +Note: Next generate matching and non-matching maps composed of original indexes +to original N-Quads. The `groupResult` is different; it contains matching and +non-matching maps using the `filteredNQuads` indexes. Both maps of indexes are +useful to callers. +
  10. +
  11. +Initialize `matching` to a new map. +
  12. +
  13. +Initialize `nonMatching` to a new map. +
  14. +
  15. +Initialize filteredMatches to the values in `groupResult.matching`. +
  16. +
  17. +Initialize filteredNonMatches to the values in `groupResult.nonMatching`. +
  18. +
  19. +For each entry (`index`, `nq`) in `nquads`: +
      +
    1. +If `filteredMatches` includes `nq` then add the entry to `matching`. +
    2. +
    3. +Otherwise, if `filteredNonMatching` includes `nq` then add the entry to +`nonMatching`. +
    4. +
    +
  20. +
  21. +Initialize `labelMap` to the reverse of `canonicalIdMap`. `labelMap` uses +canonical blank node identifiers as keys and original blank node identifiers as +values. +
  22. +
  23. +Return an object with "filtered" set to `groupResult`, "labelMap" set to +`labelMap`, "matching" to `matching`, and "nonMatching" to `nonMatching`. +
  24. +
+
+ +
+

hashMandatoryNQuads

+ +

+The following algorithm cryptographically hashes an array of mandatory to +disclose N-Quads using a provided hashing API. The required input is an array of +mandatory to disclose N-Quads (mandatory) and a hashing function +(hasher). A cryptographic hash (mandatoryHash) is produced +as output. +

+ +
    +
  1. +Initialize `bytes` to the UTF-8 representation of the joined `mandatory` +N-Quads. +
  2. +
  3. +Initialize `mandatoryHash` to the result of using `hasher` to hash `bytes`. +
  4. +
  5. +Return `mandatoryHash`. +
  6. +
+
+
+ + +
+

ecdsa-sd-2023 Functions

+ +

+The Working Group is seeking implementer feedback on these cryptographic suite +functions as well as horizonal security review on the feature from parties at +W3C and IETF. Those reviews might result in significant changes to these +algorithms, or the removal of the algorithms from the specification during the +Candidate Recommendation phase. +

+ +

+This section contains subalgorithms that are useful to the `ecdsa-sd-2023` +cryptographic suite. +

+ +
+

serializeSignData

+ +

+The following algorithm serializes the data that is to be signed by the private +key associated with the base proof verification method. The required inputs are +the proof options hash (proofHash), the proof-scoped multikey-encoded +public key (publicKey), and the mandatory hash +(mandatoryHash). A single sign data value, +represented as series of bytes, is produced as output. +

+ +
    +
  1. +Return the concatenation of proofHash, publicKey, and +mandatoryHash, in that order, as sign data. +
  2. +
+ +
+ +
+

serializeBaseProofValue

+ +

+The following algorithm serializes the base proof value, including the +base signature, public key, HMAC key, signatures, and mandatory pointers. +The required inputs are a base signature baseSignature, a public key +publicKey, an HMAC key hmacKey, an array of +signatures, and an array of mandatoryPointers. +A single base proof string value is produced as output. +

+ +
    +
  1. +Initialize a byte array, `proofValue`, that starts with the ECDSA-SD base proof +header bytes 0xd9, 0x5d, and 0x00. +
  2. +
  3. +Initialize `components` to an array with five elements containing the values of: +`baseSignature`, `publicKey`, `hmacKey`, `signatures`, and `mandatoryPointers`. +
  4. +
  5. +CBOR-encode `components` and append it to `proofValue`. +
  6. +
  7. +Initialize `baseProof` to a string with the multibase-base64url-no-pad-encoding +of `proofValue`. That is, return a string starting with "u" and ending with the +base64url-no-pad-encoded value of `proofValue`. +
  8. +
  9. +Return `baseProof` as base proof. +
  10. +
+ +
+ +
+

parseBaseProofValue

+ +

+The following algorithm parses the components of an `ecdsa-sd-2023` selective +disclosure base proof value. The required inputs are a proof value +(proofValue). A single object parsed base proof, containing +five elements, using the names "baseSignature", "publicKey", "hmacKey", +"signatures", and "mandatoryPointers", is produced as output. +

+ +
    +
  1. +Ensure the `proofValue` string starts with `u`, indicating that it is a +multibase-base64url-no-pad-encoded value, throwing an error if it does not. +
  2. +
  3. +Initialize `decodedProofValue` to the result of base64url-no-pad-decoding the +substring after the leading `u` in `proofValue`. +
  4. +
  5. +Ensure that the `decodedProofValue` starts with the ECDSA-SD base proof header +bytes 0xd9, 0x5d, and 0x00, throwing an error if it does not. +
  6. +
  7. +Initialize `components` to an array that is the result of CBOR-decoding the +bytes that follow the three-byte ECDSA-SD base proof header. Ensure the result +is an array of five elements. +
  8. +
  9. +Return an object with properties set to the five elements, using the names +"baseSignature", "publicKey", "hmacKey", "signatures", and "mandatoryPointers", +respectively. +
  10. +
+ +
+ +
+

createDisclosureData

+ +

+The following algorithm creates data to be used to generate a derived proof. The +inputs include a JSON-LD document (document), an ECDSA-SD base proof +(proof), an array of JSON pointers to use to selectively disclose +statements (selectivePointers), and any custom JSON-LD API options, +such as a document loader). A single object, disclosure data, is +produced as output, which contains the "baseSignature", "publicKey", +"signatures" for "filteredSignatures", "labelMap", "mandatoryIndexes", and +"revealDocument" fields. +

+ +
    +
  1. +Initialize `baseSignature`, `publicKey`, `hmacKey`, `signatures`, and +`mandatoryPointers` to the values of the associated properties in the object +returned when calling the algorithm in Section +, passing the `proofValue` from `proof`. +
  2. +
  3. +Initialize `hmac` to an HMAC API using `hmacKey`. The HMAC uses the same hash +algorithm used in the signature algorithm, i.e., SHA-256 for a P-256 curve. +
  4. +
  5. +Initialize `nquads` to the result of calling the algorithm in Section +, passing `document`, `hmac`, and any custom +JSON-LD API options as parameters. Note: This step transforms the document into +an array of canonical N-Quads with pseudorandom blank node identifiers based on +`hmac`. +
  6. +
  7. +Initialize `mandatoryFrame` to the result of calling the algorithm in Section , passing `document` and `mandatoryPointers` as +`pointers`. +
  8. +
  9. +Initialize `combinedFrame` to the result of calling the + primitive, passing `document` and the +concatenation of `mandatoryPointers` and `selectivePointers` as `pointers`. +
  10. +
  11. +If `mandatoryFrame` and `combinedFrame` are both `null`, then throw an error +indicating that nothing is to be disclosed. +
  12. +
  13. +Execute the following two steps in parallel (if the runtime environment allows +for parallel execution, otherwise, execute the operations serially): +
      +
    1. +Initialize `revealDocument` to the result of calling the algorithm in +Section , passing `document`, `combinedFrame` as +`frame`, and any custom JSON-LD API options. +
    2. +
    3. +Initialize `filterAndGroupResult` to the result of calling the algorithm in +Section , passing `nquads`, `combinedFrame` for +`filterFrame`, `mandatoryFrame` for `groupFrame`, and any custom JSON-LD API +options. +
    4. +
    +
  14. +
  15. +Initialize `labelMap` to the value of "labelMap" in `filterAndGroupResult`. +
  16. +
  17. +Initialize `relativeMandatory` to the value of "matching" in the value of +"filtered" in `filterAndGroupResult`. +
  18. +
  19. +Initialize `absoluteMandatory` to the value of "matching" in +`filterAndGroupResult`. +
  20. +
  21. +Initialize `absoluteNonMandatory` to the value of "nonMatching" in +`filterAndGroupResult`. +
  22. +
  23. +Initialize `mandatoryIndexes` to the keys from `relativeMandatory`. +
  24. +
  25. +Choose the signatures that match the selectively disclosed statements, which +requires shifting by any absolute mandatory indexes to cause the indexes in +`signatures` to match with `absoluteNonMandatory` map keys: +
      +
    1. +Initialize `index` to `0`. +
    2. +
    3. +Initialize `filteredSignatures` to an empty array. +
    4. +
    5. +For each `signature` in `signatures`: +
        +
      1. +While `index` is in `absoluteMandatory`, increment `index`. +
      2. +
      3. +If `index` is in `absoluteNonMandatory`, add `signature` to +`filteredSignatures`. +
      4. +
      5. +Increment `index`. +
      6. +
      +
    6. +
    +
  26. +
  27. +Return an object with properties matching `baseSignature`, `publicKey`, +"signatures" for `filteredSignatures`, `labelMap`, `mandatoryIndexes`, and +`revealDocument`. +
  28. +
+ +
+ +
+

compressLabelMap

+ +

+The following algorithm compresses a label map. The required inputs are +label map (labelMap). The output is a compressed label map. +

+ +
    +
  1. +Initialize `map` to an empty map. +
  2. +
  3. +For each entry (`k`, `v`) in `labelMap`: +
      +
    1. +Add an entry to `map` with a key that is a base-10 integer parsed from the +characters following the "c14n" prefix in `k` and a value that is a byte array +resulting from base64url-no-pad-decoding the characters after the "u" prefix in + `v`. +
    2. +
    +
  4. +Return `map` as compressed label map. +
  5. +
+ +
+ +
+

decompressLabelMap

+ +

+The following algorithm decompresses a label map. The required input is a +compressed label map (compressedLabelMap). The output is a +decompressed label map. +

+ +
    +
  1. +Initialize `map` to an empty map. +
  2. +
  3. +For each entry (`k`, `v`) in `compressedLabelMap`: +
      +
    1. +Add an entry to `map` with a key that adds the prefix "c14n" to `k` and a value +that adds a prefix of "u" to the base64url-no-pad-encoded value for `v`. +
    2. +
    +
  4. +Return `map` as decompressed label map. +
  5. +
+ +
+ +
+

serializeDerivedProofValue

+ +

+The following algorithm serializes a derived proof value. The required inputs +are a base signature (baseSignature), public key +(publicKey), an array of signatures (signatures), a label +map (labelMap), and an array of mandatory indexes +(mandatoryIndexes). A single derived proof value, serialized +as a byte string, is produced as output. +

+ +
    +
  1. +Initialize `compressedLabelMap` to the result of calling the algorithm in +Section , passing `labelMap` as the parameter. +
  2. +
  3. +Initialize a byte array, `proofValue`, that starts with the ECDSA-SD disclosure +proof header bytes `0xd9`, `0x5d`, and `0x01`. +
  4. +
  5. +Initialize `components` to an array with five elements containing the values of: +`baseSignature`, `publicKey`, `signatures`, `compressedLabelMap`, and +`mandatoryIndexes`. +
  6. +
  7. +CBOR-encode `components` and append it to `proofValue`. +
  8. +
  9. +Return the derived proof as a string with the +multibase-base64url-no-pad-encoding of `proofValue`. That is, return a string +starting with "u" and ending with the base64url-no-pad-encoded value of +`proofValue`. +
  10. +
+ +
+ +
+

parseDerivedProofValue

+ +

+The following algorithm parses the components of the derived proof value. +The required inputs are a derived proof value (proofValue). A +A single derived proof value value object is produced as output, which +contains a set to five elements, using the names "baseSignature", "publicKey", +"signatures", "labelMap", and "mandatoryIndexes". +

+ +
    +
  1. +Ensure the `proofValue` string starts with `u`, indicating that it is a +multibase-base64url-no-pad-encoded value, throwing an error if it does not. +
  2. +
  3. +Initialize `decodedProofValue` to the result of base64url-no-pad-decoding the +substring after the leading `u` in `proofValue`. +
  4. +
  5. +Ensure that the `decodedProofValue` starts with the ECDSA-SD disclosure proof +header bytes `0xd9`, `0x5d`, and `0x01`, throwing an error if it does not. +
  6. +
  7. +Initialize `components` to an array that is the result of CBOR-decoding the +bytes that follow the three-byte ECDSA-SD disclosure proof header. Ensure the +result is an array of five elements. Ensure the result is an array of five +elements: a byte array of length 64, a byte array of length 36, an array of byte +arrays, each of length 64, a map of integers to byte arrays of length 32, and an +array of integers, throwing an error if not. +
  8. +
  9. +Replace the fourth element in `components` using the result of calling the +algorithm in Section , passing the existing +fourth element of `components` as `compressedLabelMap`. +
  10. +
  11. +Return derived proof value as an object with properties set to the five +elements, using the names "baseSignature", "publicKey", "signatures", +"labelMap", and "mandatoryIndexes", respectively. +
  12. +
+ +
+ +
+

createVerifyData

+ +

+The following algorithm creates the data needed to perform verification of an +ECDSA-SD-protected verifiable credential. The inputs include a JSON-LD +document (document), an ECDSA-SD disclosure proof (proof), +and any custom JSON-LD API options, such as a document loader. A single +verify data object value is produced as output containing the following +fields: "baseSignature", "proofHash", "publicKey", "signatures", "nonMandatory", +and "mandatoryHash". +

+ +
    +
  1. +Initialize `proofHash` to the result of perform RDF Dataset Canonicalization +[[RDF-CANON]] on the proof options. The hash used is the same as the one used in +the signature algorithm, i.e., SHA-256 for a P-256 curve. Note: This step can be +performed in parallel; it only needs to be completed before this algorithm needs +to use the `proofHash` value. +
  2. +
  3. +Initialize `baseSignature`, `publicKey`, `signatures`, `labelMap`, and +`mandatoryIndexes`, to the values associated with their property names in the +object returned when calling the algorithm in Section +, passing `proofValue` from `proof`. +
  4. +
  5. +Initialize `nquads` to the result of calling the "labelReplacementCanonize" +primitive, passing `document`, the result of calling the "labelMapCanonize" +primitive (passing `labelMap`) as `labelReplacementFunction`, and any custom +JSON-LD API options. Note: This step transforms the document into an array of +canonical N-Quads with pseudorandom blank node identifiers based on `labelMap`. +
  6. +
  7. +Initialize `mandatory` to an empty array. +
  8. +
  9. +Initialize `nonMandatory` to an empty array. +
  10. +
  11. +For each entry (`index`, `nq`) in `nquads`, separate the N-Quads into mandatory +and non-mandatory categories: +
      +
    1. +If `mandatoryIndexes` includes `index`, add `nq` to `mandatory`. +
    2. +
    3. +Otherwise, add `nq` to `nonMandatory`. +
    4. +
    +
  12. +Initialize `mandatoryHash` to the result of calling the "hashMandatory" +primitive, passing `mandatory`. +
  13. +
  14. +Return an object with properties matching `baseSignature`, `proofHash`, +`publicKey`, `signatures`, `nonMandatory`, and `mandatoryHash`. +
  15. +
+ +
+ +
+ +
+

ecdsa-sd-2023

+ +

+The Working Group is seeking implementer feedback on this cryptographic suite +as well as horizonal security review on the feature from parties at W3C and +IETF. Those reviews might result in significant changes to this algorithm, or +the removal of the algorithm from the specification during the Candidate +Recommendation phase. +

+ +

+The `ecdsa-sd-2023` cryptographic suite takes an input document, canonicalizes +the document using the Universal 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. +

+ +
+

Add Base Proof (ecdsa-sd-2023)

+ +

+To generate a base 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 +, the + +hashing algorithm is defined in Section , +and the + +proof serialization algorithm is defined in Section +. +

+
+ +
+

Base Proof Transformation (ecdsa-sd-2023)

+ +

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

+ +

+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), a cryptosuite +identifier (cryptosuite), and a verification method +(verificationMethod). The transformation options MUST contain an +array of mandatory JSON pointers (mandatoryPointers) and MAY contain +additional options, such as a JSON-LD document loader. A transformed data +document is produced as output. Whenever this algorithm encodes strings, it +MUST use UTF-8 encoding. +

+ +
    +
  1. +Initialize `hmac` to an HMAC API using a locally generated and exportable HMAC +key. The HMAC uses the same hash algorithm used in the signature algorithm, +which is detected via the verificationMethod provided to the +function. i.e., SHA-256 for a P-256 curve. +
  2. +
  3. +Initialize `nquads` to the result of calling the algorithm in Section +, passing `unsecuredDocument`, the +result of calling the algorithm in Section + (passing `hmac`) as the +`labelReplacementFunction`, and any custom JSON-LD API options. Note: This step +transforms the document into an array of canonical N-Quads with pseudorandom +blank node identifiers based on `hmac`. +
  4. +
  5. +Initialize `mandatoryFrame` to the result of calling the algorithm in Section +, passing `document` and `mandatoryPointers` as +`pointers`. +
  6. +
  7. +Initialize `matching` and `nonMatching` to the result of calling the algorithm +in Section , passing `nquads`, `mandatoryFrame` as +`frame`, and any custom JSON-LD API options. Note: This step separates the +N-Quads to mandatory (to disclose) and non-mandatory groups. +
  8. +
  9. +Initialize `mandatory` to the values in the `matching` map. +
  10. +
  11. +Initialize `nonMandatory` to the values in the `nonMatching` map. +
  12. +
  13. +Initialize `hmacKey` to the result of exporting the HMAC key from `hmac`. +
  14. +
  15. +Return an object with "mandatoryPointers" set to `mandatoryPointers`, +"mandatory" set to `mandatory`, "nonMandatory" set to `nonMandatory`, +and "hmacKey" set to `hmacKey`. +
  16. +
+
+ +
+

Base Proof Hashing (ecdsa-sd-2023)

+ +

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

+ +

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

+ +
    +
  1. +Initialize `proofHash` to the result of calling the RDF Dataset Canonicalization +algorithm [[RDF-CANON]] on `canonicalProofConfig` and then cryptographically +hashing the result using the same hash that is used by the signature algorithm, +i.e., SHA-256 for a P-256 curve. Note: This step can be performed in parallel; +it only needs to be completed before this algorithm terminates as the result is +part of the return value. +
  2. +
  3. +Initialize `mandatoryHash` to the result of calling the the algorithm in Section +, passing +transformedDocument.`mandatory`. +
  4. +
  5. +Initialize `hashData` as a deep copy of transformedDocument and +add `proofHash` as "proofHash" and `mandatoryHash` as "mandatoryHash" to that +object. +
  6. +
  7. +Return `hashData` as hash data. +
  8. +
+ +
+ +
+

Base Proof Configuration (ecdsa-sd-2023)

+ +

+The following algorithm specifies how to generate a +proof configuration from a set of proof options +that is used as input to the +base 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 an empty object. +
  2. +
  3. +Set proofConfig.type to +options.type. +
  4. +
  5. +If options.cryptosuite is set, set +proofConfig.cryptosuite to its value. +
  6. +
  7. +If options.type is not set to `DataIntegrityProof` and +proofConfig.cryptosuite is not set to `ecdsa-sd-2023`, an +`INVALID_PROOF_CONFIGURATION` error MUST be raised. +
  8. +
  9. +Set proofConfig.created to +options.created. If the value is not a valid +[[XMLSCHEMA11-2]] datetime, an `INVALID_PROOF_DATETIME` error MUST be raised. +
  10. +
  11. +Set proofConfig.verificationMethod to +options.verificationMethod. +
  12. +
  13. +Set proofConfig.proofPurpose to +options.proofPurpose. +
  14. +
  15. +Set proofConfig.@context to +unsecuredDocument.@context. +
  16. +
  17. +Let canonicalProofConfig be the result of applying the +Universal RDF Dataset Canonicalization Algorithm +[[RDF-CANON]] to the proofConfig. +
  18. +
  19. +Return canonicalProofConfig. +
  20. +
+ +
+ +
+

Base Proof Serialization (ecdsa-sd-2023)

+ +

+The following algorithm specifies how to create a base proof; called by an +issuer of an ECDSA-SD-protected Verifiable Credential. The base proof is to be +given only to the holder, who is responsible for generating a derived proof from +it, exposing only selectively disclosed details in the proof to a verifier. 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. +Initialize `proofHash`, `mandatoryPointers`, `mandatoryHash`, `nonMandatory`, +and `hmacKey` to the values associated with their property names +hashData. +
  2. +
  3. +Initialize `proofScopedKeyPair` to a locally generated P-256 ECDSA key pair. +Note: This key pair is scoped to the specific proof; it is not used for anything +else and the private key will be destroyed when this algorithm terminates. +
  4. +
  5. +Initialize `signatures` to an array where each element holds the result of +digitally signing the UTF-8 representation of each N-Quad string in +`nonMandatory`, in order. The digital signature algorithm is ES256, i.e., uses a +P-256 curve over a SHA-256 digest, and uses the private key from +`proofScopedKeyPair`. Note: This step generates individual signatures for each +statement that can be selectively disclosed using a local, proof-scoped key pair +that binds them together; this key pair will be bound to the proof by a +signature over its public key using the private key associated with the base +proof verification method. +
  6. +
  7. +Initialize `publicKey` to the multikey expression of the public key exported +from `proofScopedKeyPair`. That is, an array of bytes starting with the bytes +0x80 and 0x24 (which is the multikey p256-pub header (0x1200) expressed as a +varint) followed by the compressed public key bytes (the compressed header with +`2` for an even `y` coordinate and `3` for an odd one followed by the `x` +coordinate of the public key). +
  8. +
  9. +Initialize `toSign` to the result of calling the algorithm in Section +, passing `proofHash`, `publicKey`, and +`mandatoryHash` as parameters to the algorithm. +
  10. +
  11. +Initialize `baseSignature` to the result of digitally signing `toSign` using the +private key associated with the base proof verification method. +
  12. +
  13. +Initialize `proofValue to the result of calling the algorithm in Section +, passing `baseSignature`, +`publicKey`, `hmacKey`, `signatures`, and `mandatoryPointers` as parameters +to the algorithm. +
  14. +
  15. +Return `proofValue` as digital proof. +
  16. +
+ +
+ +
+

Add Derived Proof (ecdsa-sd-2023)

+ +

+The following algorithm creates a selective disclosure derived proof; called by +a holder of an `ecdsa-sd-2023`-protected verifiable credential. +The derived proof is to be given to the verifier. The inputs include a +JSON-LD document (document), an ECDSA-SD base proof +(proof), an array of JSON pointers to use to selectively disclose +statements (selectivePointers), and any custom JSON-LD API options, +such as a document loader. A single selectively revealed document +value, represented as an object, is produced as output. +

+ +
    +
  1. +Initialize `baseSignature`, `publicKey`, `signatures`, `labelMap`, +`mandatoryIndexes`, `revealDocument` to the values associated with their +property names in the object returned when calling the algorithm in +Section , passing the `document`, `proof`, +`selectivePointers`, and any custom JSON-LD API options, such as a document +loader. +
  2. +
  3. +Initialize `newProof` to a shallow copy of `proof`. +
  4. +
  5. +Replace `proofValue` in `newProof` with the result of calling the algorithm +in Section , passing +`baseSignature`, `publicKey`, `signatures`, `labelMap`, and `mandatoryIndexes`. +
  6. +
  7. +Set the value of the "proof" property in `revealDocument` to `newProof`. +
  8. +
  9. +If `revealDocument` has an `@context` field that includes a verifiable +credential base context and it has a "credentialSubject" property that is a +string, set the "credentialSubject" value to an object with an "id" value that +matches the original string value. +
  10. +
  11. +Return `revealDocument` as the selectively revealed document. +
  12. +
+ +
+ +
+

Verify Derived Proof (ecdsa-sd-2023)

+ +

+The following algorithm attempts verification of an `ecdsa-sd-2023` derived +proof. This algorithm is called by a verifier of an ECDSA-SD-protected +verifiable credential. The inputs include a JSON-LD document +(document), an ECDSA-SD disclosure proof (proof), and any +custom JSON-LD API options, such as a document loader. A single boolean +verification result value is produced as output. +

+ +
    +
  1. +Initialize `baseSignature`, `proofHash`, `publicKey`, `signatures`, +`nonMandatory`, and `mandatoryHash` to the values associated with their property +names in the object returned when calling the algorithm in Section +, passing the `document`, `proof`, and any +custom JSON-LD API options, such as a document loader. +
  2. +
  3. +If the length of `signatures` does not match the length of `nonMandatory`, throw +an error indicating that the signature count does not match the non-mandatory +message count. +
  4. +
  5. +Initialize `publicKeyBytes` to the public key bytes expressed in `publicKey`. +Instructions on how to decode the public key value can be found in Section +. +
  6. +
  7. +Initialize `toVerify` to the result of calling the algorithm in Setion +, passing `proofHash`, `publicKey`, and +`mandatoryHash`. +
  8. +
  9. +Initialize `verificationResult` be the result of applying the verification +algorithm of the Elliptic Curve Digital Signature Algorithm (ECDSA) [FIPS-186-5], +with `toVerify` as the data to be verified against the `baseSignature` using +the public key specified by `publicKeyBytes`. If `verificationResult` is +`false`, return `false`. +
  10. +
  11. +For every entry (`index`, `signature`) in `signatures`, verify every signature +for every selectively disclosed (non-mandatory) statement: +
      +
    1. +Initialize `verificationResult` to the result of applying the verification +algorithm Elliptic Curve Digital Signature Algorithm (ECDSA) [FIPS-186-5], with +the UTF-8 representation of the value at `index` of `nonMandatory` as the data +to be verified against `signature` using the public key specified by +`publicKeyBytes`. +
    2. +
    3. +If `verificationResult` is `false`, return `false`. +
    4. +
    +
  12. + +
  13. +Return `verificationResult` as verification result. +
  14. +
+ +
+ +
+

Security Considerations