This specification describes mechanisms for ensuring the authenticity and integrity of Verifiable Credentials and similar types of constrained digital documents using cryptography, especially through the use of digital signatures and related mathematical proofs.

Introduction

This specification describes mechanisms for ensuring the authenticity and integrity of Verifiable Credentials and similar types of constrained digital documents using cryptography, especially through the use of digital signatures and related mathematical proofs. Cryptographic proofs enable functionality that is useful to implementors of distributed systems. For example, proofs can be used to:

How it Works

The operation of Data Integrity is conceptually simple. To create a cryptographic proof, the following steps are performed: 1) Transformation, 2) Hashing, and 3) Proof Generation.


Diagram showing the three steps involved in the creation of a cryptographic
proof. The diagram is laid out left to right with a blue box labeled 'Data'
on the far left. The blue box travels, left to right, through three subsequent
yellow arrows labeled 'Transform Data', 'Hash Data', and 'Generate Proof'. The
resulting blue box at the far right is labeled 'Data with Proof'.
To create a cryptographic proof, data is transformed, hashed, and cryptographically protected.

Transformation is a process described by a transformation algorithm that takes input data and prepares it for the hashing process. One example of a possible transformation is to take a record of people's names that attended a meeting, sort the list alphabetically by the individual's family name, and rewrite the names on a piece of paper, one per line, in sorted order. Possible transformations include canonicalization and binary-to-text encoding.

Hashing is a process described by a hashing algorithm that calculates an identifier for the transformed data using a cryptographic hash function. This process is conceptually similar to how a phone address book functions, where one takes a person's name (the input data) and maps that name to that individual's phone number (the hash). Possible cryptographic hash functions include SHA-3 and BLAKE-3.

Proof Generation is a process described by a proof generation algorithm that calculates a value that protects the integrity of the input data from modification or otherwise proves a certain desired threshold of trust. This process is conceptually similar to the way a wax seal can be used on an envelope containing a letter to establish trust in the sender and show that the letter has not been tampered with in transit. Possible proof generation functions include digital signatures and proofs of stake.

To verify a cryptographic proof, the following steps are performed: 1) Transformation, 2) Hashing, and 3) Proof Verification.


Diagram showing the three steps involved in the verification of a cryptographic
proof. The diagram is laid out left to right with a blue box labeled
'Data with Proof' on the far left. The blue box travels, left to right, through
three subsequent yellow arrows labeled 'Transform Data', 'Hash Data', and
'Verify Proof'. The resulting blue box at the far right is labeled 'Data with
Proof'.
To verify a cryptographic proof, data is transformed, hashed, and checked for correctness.

During verification, the transformation and hashing steps are conceptually the same as described above.

Proof Verification is a process that is described by a proof verification algorithm that applies a cryptographic proof verification function to see if the input data can be trusted. Possible proof verification functions include digital signatures and proofs of stake.

This specification details how cryptographic software architects and implementers can package these processes together into things called cryptographic suites and provide them to application developers for the purposes of protecting the integrity of application data in transit and at rest.

Design Goals and Rationale

This specification optimizes for the following design goals:

Simplicity
The technology is designed to be easy to use for application developers, without requiring significant training in cryptography. It optimizes for the following priority of constituencies: application developers over cryptographic suite implementers, over cryptographic suite designers, over cryptographic algorithm specification authors. The solution focuses on sensible defaults to prevent the selection of ineffective protection mechanisms. See section and for further details.
Composability
A number of historical digital signature mechanisms have had monolithic designs which limited use cases by combining data transformation, syntax, digital signature, and serialization into a single specification. This specification layers each component such that a broader range of use cases are enabled, including generalized selective disclosure and serialization-agnostic signatures. See section , section , and for further rationale.
Resilience
Since digital proof mechanisms might be compromised without warning due to technological advancements, it is important that cryptographic suites provide multiple layers of protection and can be rapidly upgraded. This specification provides for both algorithmic agility and cryptographic layering, while still keeping the digital proof format easy for developers to understand and use. See section to understand the particulars.
Progressive Extensibility
Creating and deploying new cryptographic protection mechanisms is designed to be a deliberate, iterative, and careful process that acknowledges that extension happens in phases from experimentation, to implementation, to standardization. This specification strives to balance the need for an increase in the rate of innovation in cryptography with the need for stable production-grade cryptography suites. See section for instructions on establishing new types of cryptographic proofs.
Serialization Flexibility
Cryptographic proofs can be serialized in many different but equivalent ways and have often been tightly bound to the original document syntax. This specification enables one to create cryptographic proofs that are not bound to the original document syntax, which enables more advanced use cases such as being able to use a single digital signature across a variety of serialization syntaxes such as JSON and CBOR without the need to regenerate the cryptographic proof. See section for an explanation of the benefits of such an approach.

While this specification primarily focuses on Verifiable Credentials, the design of this technology is generalized, such that it can be used for non-Verifiable Credential use cases. In these instances, implementers are expected to perform their own due diligence and expert review as to the applicability of the technology to their use case.

Terminology

Data Model

This section specifies the data model that is used for expressing data integrity proofs and verification methods.

Proofs

A data integrity proof provides information about the proof mechanism, parameters required to verify that proof, and the proof value itself. All of this information is provided using Linked Data vocabularies such as the [[?SECURITY-VOCABULARY]].

The following attributes are defined for use in a data integrity proof:

type
The specific proof type used for the cryptographic proof MUST be specified as a string that maps to a URL [[URL]]. Examples of proof types include DataIntegrityProof and Ed25519Signature2020. Proof types determine what other fields are required to secure and verify the proof.
proofPurpose
The reason the proof was created MUST be specified as a string that maps to a URL [[URL]]. The proof purpose acts as a safeguard to prevent the proof from being misused by being applied to a purpose other than the one that was intended. For example, without this value the creator of a proof could be tricked into using cryptographic material typically used to create a Verifiable Credential (assertionMethod) during a login process (authentication) which would then result in the creation of a Verifiable Credential they never meant to create instead of the intended action, which was to merely logging into a website.
verificationMethod
The means and information needed to verify the proof MUST be specified as a string that maps to a [[URL]]. An example of a verification method is a link to a public key which includes cryptographic material that is used by a verifier during the verification process.
created
The date and time the proof was created MUST be specified as an [[XMLSCHEMA11-2]] combined date and time string.
domain
The creator of a proof SHOULD include a string value that indicates its intended usage, which a verifier SHOULD use to ensure the proof was intended to be used by them. The specification of the `domain` parameter is useful in challenge-response protocols where the verifier is operating from within a security domain known to the creator of the proof. Examples of a domain parameter include: `domain.example` (DNS domain), `https://domain.example:8443` (full Web origin), `mycorp-intranet` (well-known text string), and `b31d37d4-dd59-47d3-9dd8-c973da43b63a` (UUID).
challenge
A string value that SHOULD be included in a proof if a `domain` is specified. The value is used once for a particular domain and window of time. This value is used to mitigate replay attacks. Examples of a challenge value include: `1235abcd6789`, `79d34551-ae81-44ae-823b-6dadbab9ebd4`, and `ruby`.
proofValue
A string value that contains the data necessary to verify the digital proof using the `verificationMethod` specified. The contents of the value MUST be a multibase-encoded binary value. Alternative fields with different encodings MAY be used to encode the data necessary to verify the digital proof instead of this value. The contents of this value are determined by a cryptosuite and set to the proof value generated by the Generate Proof Algorithm.

All of the terms above map to URLs. The vocabulary where these terms are defined is the [[?SECURITY-VOCABULARY]].

A proof can be added to a JSON document like the following:

  {
    "title": "Hello world!"
  };
        

by adding the parameters outlined in this section:

  {
    "title": "Hello world!",
    "proof": {
      "type": "DataIntegrityProof",
      "cryptosuite": "example-signature-2022",
      "created": "2020-11-05T19:23:24Z",
      "verificationMethod": "https://di.example/issuer#z6MkjLrk3gKS2nnkeWcmcxi
        ZPGskmesDpuwRBorgHxUXfxnG",
      "proofPurpose": "assertionMethod",
      "proofValue": "zQeVbY4oey5q2M3XKaxup3tmzN4DRFTLVqpLMweBrSxMY2xHX5XTYV8nQA
        pmEcqaqA3Q1gVHMrXFkXJeV6doDwLWx"
    }
  }
        

The example proof above suggests a ficticious example-signature-2022 cryptography suite that produces a verifiable digital proof by presumptively transforming the input data using the JSON Canonicalization Scheme [[?RFC8785]] and then digitally signing it using an Ed25519 elliptic curve signature.

Similarly, a proof can be added to a JSON-LD data document like the following:

  {
    "@context": {"title": "https://schema.org/title"},
    "title": "Hello world!"
  };
        

by adding the parameters outlined in this section:

  {
    "@context": [
      {"title": "https://schema.org/title"},
      "https://w3id.org/security/data-integrity/v1"
    ],
    "title": "Hello world!",
    "proof": {
      "type": "DataIntegrityProof",
      "cryptosuite": "eddsa-2022",
      "created": "2020-11-05T19:23:24Z",
      "verificationMethod": "https://ldi.example/issuer#z6MkjLrk3gKS2nnkeWcmcxi
        ZPGskmesDpuwRBorgHxUXfxnG",
      "proofPurpose": "assertionMethod",
      "proofValue": "z4oey5q2M3XKaxup3tmzN4DRFTLVqpLMweBrSxMY2xHX5XTYVQeVbY8nQA
        VHMrXFkXJpmEcqdoDwLWxaqA3Q1geV6"
    }
  }
        

The proof example above uses the Ed25519Signature2020 proof type to produce a verifiable digital proof by canonicalizing the input data using the RDF Dataset Canonicalization algorithm [[?RDF-DATASET-C14N]] and then digitally signing it using an Ed25519 elliptic curve signature.

Create a separate section detailing an optional mechanism for authenticating public key control via bi-directional links. How to establish trust in controllers is out of scope but examples can be given.
Specify algorithm agility mechanisms (additional attributes from the security vocab can be used to indicate other signing and hash algorithms). Rewrite algorithms to be parameterized on this basis and move `Ed25519Signature2020` definition to a single supported mechanism; specify its identifier as a URL. In order to make it easy to specify a variety of combinations of algorithms, introduce a core type `DataIntegrityProof` that allows for easy filtering/discover of proof nodes, but that type on its own doesn't specify any default proof or hash algorithms, those need to be given via other properties in the nodes.

The pattern that Data Integrity Signatures use presently leads to a proliferation in signature types and JSON-LD Contexts. This proliferation can be avoided without any loss of the security characteristics of tightly binding a cryptography suite version to one or more acceptable public keys. The following signature suites are currently being contemplated: eddsa-2022, nist-ecdsa-2022, koblitz-ecdsa-2022, rsa-2022, pgp-2022, bbs-2022, eascdsa-2022, ibsa-2022, and jws-2022.

{
  "@context": ["https://w3id.org/security/data-integrity/v1"],
  "type": "DataIntegrityProof",
  "cryptosuite": "ecdsa-2022",
  "created": "2022-11-29T20:35:38Z",
  "verificationMethod": "did:example:123456789abcdefghi#keys-1",
  "proofPurpose": "assertionMethod",
  "proofValue": "z2rb7doJxczUFBTdV5F5pehtbUXPDUgKVugZZ99jniVXCUpojJ9PqLYV
                 evMeB1gCyJ4HqpnTyQwaoRPWaD3afEZboXCBTdV5F5pehtbUXPDUgKVugUpoj"
}
      
Add an explicit check on key type to prevent an attacker from selecting an algorithm that could abuse how the key is used/interpreted.
Add a note indicating that selective disclosure proof mechanisms can be compatible with Data Integrity; for example, an algorithm could produce a merkle tree from a canonicalized set of N-Quads and then sign the root hash. Disclosure would involve including the merkle paths for each N-Quad that is to be revealed. This mechanism would merely consume the normalized output differently (this, and the proof mechanism would be modifications to this core spec). It might also be necessary to generate proof parameters such as a private key/seed that can be used along with an algorithm to deterministically generate nonces that are concatenated with each N-Quad to prevent rainbow table or similar attacks.
Add a note indicating that this specification should not be construed to indicate that public key controllers should be restricted to a single public key or that systems that use this spec and involve real people should identify each person as only ever being a single entity rather than perhaps N entities with M keys. There are no such restrictions and in many cases those kinds of restrictions are ill-advised due to privacy considerations.

The Data Integrity specification supports the concept of multiple proofs in a single document. There are two types of multi-proof approaches that are identified: Proof Sets (un-ordered) and Proof Chains (ordered).

Proof Sets

A proof set is useful when the same data needs to be secured by multiple entities, but where the order of proofs does not matter, such as in the case of a set of signatures on a contract. A proof set, which has no order, is represented by associating a set of proofs with the proof key in a document.

{
  "@context": [
    {"title": "https://schema.org/title"},
    "https://w3id.org/security/data-integrity/v1"
],
  "title": "Hello world!",
  "proof": [{
    "type": "DataIntegrityProof",
    "cryptosuite": "eddsa-2022",
    "created": "2020-11-05T19:23:24Z",
    "verificationMethod": "https://ldi.example/issuer/1#z6MkjLrk3gKS2nnkeWcmcxi
      ZPGskmesDpuwRBorgHxUXfxnG",
    "proofPurpose": "assertionMethod",
    "proofValue": "z4oey5q2M3XKaxup3tmzN4DRFTLVqpLMweBrSxMY2xHX5XTYVQeVbY8nQA
      VHMrXFkXJpmEcqdoDwLWxaqA3Q1geV6"
  }, {
    "type": "DataIntegrityProof",
    "cryptosuite": "eddsa-2022",
    "created": "2020-11-05T13:08:49Z",
    "verificationMethod": "https://pfps.example/issuer/2#z6MkGskxnGjLrk3gKS2mes
      DpuwRBokeWcmrgHxUXfnncxiZP",
    "proofPurpose": "assertionMethod",
    "proofValue": "z5QLBrp19KiWXerb8ByPnAZ9wujVFN8PDsxxXeMoyvDqhZ6Qnzr5CG9876
      zNht8BpStWi8H2Mi7XCY3inbLrZrm95"
  }]
}
        

Proof Chains

A proof chain is useful when the same data needs to be signed by multiple entities and the order of when the proofs occurred matters, such as in the case of a notary counter-signing a proof that had been created on a document. A proof chain, where order needs to be preserved, is represented by associating an ordered list of proofs with the proofChain key in a document.

{
  "@context": [
    {"title": "https://schema.org/title"},
    "https://w3id.org/security/data-integrity/v1"
],
  "title": "Hello world!",
  "proofChain": [{
    "type": "DataIntegrityProof",
    "cryptosuite": "eddsa-2022",
    "created": "2020-11-05T19:23:42Z",
    "verificationMethod": "https://ldi.example/issuer/1#z6MkjLrk3gKS2nnkeWcmcxi
      ZPGskmesDpuwRBorgHxUXfxnG",
    "proofPurpose": "assertionMethod",
    "proofValue": "zVbY8nQAVHMrXFkXJpmEcqdoDwLWxaqA3Q1geV64oey5q2M3XKaxup3tmzN4
      DRFTLVqpLMweBrSxMY2xHX5XTYVQe"
  }, {
    "type": "DataIntegrityProof",
    "cryptosuite": "eddsa-2022",
    "created": "2020-11-05T21:28:14Z",
    "verificationMethod": "https://pfps.example/issuer/2#z6MkGskxnGjLrk3gKS2mes
      DpuwRBokeWcmrgHxUXfnncxiZP",
    "proofPurpose": "assertionMethod",
    "proofValue": "z6Qnzr5CG9876zNht8BpStWi8H2Mi7XCY3inbLrZrm955QLBrp19KiWXerb8
      ByPnAZ9wujVFN8PDsxxXeMoyvDqhZ"
  }]
}
        

Proof Purposes

A proof that describes its purpose helps prevent it from being misused for some other purpose.

Add a mention of JWK's key_ops parameter and WebCrypto's KeyUsage restrictions; explain that Proof Purpose serves a different goal and allows for finer-grained restrictions.

Dave Longley suggested that proof purposes enable verifiers to know what the proof creator's intent was so the message can't be accidentally abused for another purpose, e.g., a message signed for the purpose of merely making an assertion (and thus perhaps intended to be widely shared) being abused as a message to authenticate to a service or take some action (invoke a capability). It's a goal to keep the number of them limited to as few categories as are really needed to accomplish this goal.

The following is a list of commonly used proof purpose values.

authentication
Indicates that a given proof is only to be used for the purposes of an authentication protocol.
assertionMethod
Indicates that a proof can only be used for making assertions, for example signing a Verifiable Credential.
keyAgreement
Indicates that a proof is used for for key agreement protocols, such as Elliptic Curve Diffie Hellman key agreement used by popular encryption libraries.
capabilityDelegation
Indicates that the proof can only be used for delegating capabilities. See the Authorization Capabilities [[?ZCAP]] specification for more detail.
capabilityInvocation
Indicates that the proof can only be used for invoking capabilities. See the Authorization Capabilities [[?ZCAP]] specification for more detail.

Note: The Authorization Capabilities [[?ZCAP]] specification defines additional proof purposes for that use case, such as capabilityInvocation and capabilityDelegation.

Controller Documents

A controller document is a set of data that specifies one or more relationships between a controller and a set of data, such as a set of public cryptographic keys. The controller document SHOULD contain verification relationships that explicitly permit the use of certain verification methods for specific purposes.

Add examples of common Controller documents, such as controller documents published on a ledger-based registry, or on a mutable medium in combination with an integrity protection mechanism such as Hashlinks.

Verification Methods

A controller document can express verification methods, such as cryptographic public keys, which can be used to authenticate or authorize interactions with the controller or associated parties. For example, a cryptographic public key can be used as a verification method with respect to a digital signature; in such usage, it verifies that the signer could use the associated cryptographic private key. Verification methods might take many parameters. An example of this is a set of five cryptographic keys from which any three are required to contribute to a cryptographic threshold signature.

verificationMethod

The verificationMethod property is OPTIONAL. If present, the value MUST be a set of verification methods, where each verification method is expressed using a map. The verification method map MUST include the id, type, controller, and specific verification material properties that are determined by the value of type and are defined in . A verification method MAY include additional properties. Verification methods SHOULD be registered in the Data Integrity Specification Registries [TBD - DIS-REGISTRIES].

id

The value of the id property for a verification method MUST be a string that conforms to the conforms to the [[URL]] syntax.

type
The value of the type property MUST be a string that references exactly one verification method type. In order to maximize global interoperability, the verification method type SHOULD be registered in the Data Integrity Specification Registries [TBD -- DIS-REGISTRIES].
controller
The value of the controller property MUST be a string that conforms to the [[URL]] syntax.
    {
      "@context": [
        "https://www.w3.org/ns/did/v1",
        "https://w3id.org/security/data-integrity/v1"
      ]
      "id": "did:example:123456789abcdefghi",
      ...
      "verificationMethod": [{
        "id": ...,
        "type": ...,
        "controller": ...,
        "publicKeyJwk": ...
      }, {
        "id": ...,
        "type": ...,
        "controller": ...,
        "publicKeyMultibase": ...
      }]
    }
          

The semantics of the controller property are the same when the subject of the relationship is the controller document as when the subject of the relationship is a verification method, such as a cryptographic public key. Since a key can't control itself, and the key controller cannot be inferred from the controller document, it is necessary to explicitly express the identity of the controller of the key. The difference is that the value of controller for a verification method is not necessarily a controller. controllers are expressed using the controller property at the highest level of the controller document.

Verification Material

Verification material is any information that is used by a process that applies a verification method. The type of a verification method is expected to be used to determine its compatibility with such processes. Examples of verification material properties are publicKeyJwk or publicKeyMultibase. A cryptographic suite specification is responsible for specifying the verification method type and its associated verification material. For example, see JSON Web Signature 2020 and Ed25519 Signature 2020. For all registered verification method types and associated verification material available for controllers, please see the Data Integrity Specification Registries [TBD - DIS-REGISTRIES].

Ensuring that cryptographic suites are versioned and tightly scoped to a very small set of possible key types and signature schemes (ideally one key type and size and one signature output type) is a design goal for most Data Integrity cryptographic suites. Historically, this has been done by defining both the key type and the cryptographic suite that uses the key type in the same specification. The downside of doing so, however, is that there might be a proliferation of different key types in multikey that result in different cryptosuites defining the same key material differently. For example, one cryptosuite might use compressed Curve P-256 keys while another uses uncompressed values. If that occurs, it will harm interoperability. It will be important in the coming months to years to ensure that this does not happen by fully defining the multikey format in a separate specification so cryptosuite specifications, such as this one, can refer to the multikey specification, thus reducing the chances of multikey type proliferation and improving the chances of maximum interoperability for the multikey format.

To increase the likelihood of interoperable implementations, this specification limits the number of formats for expressing verification material in a controller document. The fewer formats that implementers have to implement, the more likely it will be that they will support all of them. This approach attempts to strike a delicate balance between ease of implementation and supporting formats that have historically had broad deployment. Two supported verification material properties are listed below:

publicKeyJwk

The publicKeyJwk property is OPTIONAL. If present, the value MUST be a map representing a JSON Web Key that conforms to [[RFC7517]]. The map MUST NOT contain "d", or any other members of the private information class as described in Registration Template. It is RECOMMENDED that verification methods that use JWKs [[RFC7517]] to represent their public keys use the value of kid as their fragment identifier. It is RECOMMENDED that JWK kid values are set to the public key fingerprint [[RFC7638]]. See the first key in for an example of a public key with a compound key identifier.

publicKeyMultibase

The publicKeyMultibase property is OPTIONAL. This feature is non-normative. If present, the value MUST be a string representation of a [[?MULTIBASE]] encoded public key.

Note that the [[?MULTIBASE]] specification is not yet a standard and is subject to change. There might be some use cases for this data format where publicKeyMultibase is defined, to allow for expression of public keys, but privateKeyMultibase is not defined, to protect against accidental leakage of secret keys.

A verification method MUST NOT contain multiple verification material properties for the same material. For example, expressing key material in a verification method using both publicKeyJwk and publicKeyMultibase at the same time is prohibited.

An example of a controller document containing verification methods using both properties above is shown below.

    {
      "@context": [
        "https://www.w3.org/ns/did/v1",
        "https://w3id.org/security/suites/jws-2020/v1",
        "https://w3id.org/security/multikey/v1"
      ]
      "id": "did:example:123456789abcdefghi",
      ...
      "verificationMethod": [{
        "id": "did:example:123#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A",
        "type": "JsonWebKey2020", // external (property value)
        "controller": "did:example:123",
        "publicKeyJwk": {
          "crv": "Ed25519", // external (property name)
          "x": "VCpo2LMLhn6iWku8MKvSLg2ZAoC-nlOyPVQaO3FxVeQ", // external (property name)
          "kty": "OKP", // external (property name)
          "kid": "_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A" // external (property name)
        }
      }, {
        "id": "did:example:123456789abcdefghi#keys-1",
        "type": "Multikey", // external (property value)
        "controller": "did:example:pqrstuvwxyz0987654321",
        "publicKeyMultibase": "z6MkmM42vxfqZQsv4ehtTjFFxQ4sQKS2w6WR7emozFAn5cxu"
      }],
      ...
    }
            

Multikey

The Multikey data model is a specific type of verification method that utilizes the [[MULTICODEC]] specification to encode key types into a single binary stream that is then encoded using the [[MULTIBASE]] specification. To encode a Multikey, the verification method `type` MUST be set to `Multikey` and the `publicKeyMultibase` value MUST be a [[MULTIBASE]] encoded [[MULTICODEC]] value. An example of a Multikey is provided below:

{
  "@context": ["https://w3id.org/security/multikey/v1"],
  "id": "did:example:123456789abcdefghi#keys-1",
  "type": "Multikey",
  "controller": "did:example:123456789abcdefghi",
  "publicKeyMultibase": "z6MkmM42vxfqZQsv4ehtTjFFxQ4sQKS2w6WR7emozFAn5cxu"
}
            

In the example above, the `publicKeyMultibase` value starts with the letter `z`, which is the [[MULTIBASE]] header that conveys that the binary data is base58-encoded using the Bitcoin base-encoding alphabet. The decoded binary data [[MULTICODEC]] header is `0xed`, which specifies that the remaining data is a 32-byte raw Ed25519 public key.

The Multikey data model is also capable of encoding secret keys, sometimes referred to as private keys.

{
  "@context": ["https://w3id.org/security/suites/secrets/v1"],
  "id": "did:example:123456789abcdefghi#keys-1",
  "type": "Multikey",
  "controller": "did:example:123456789abcdefghi",
  "secretKeyMultibase": "z3u2fprgdREFtGakrHr6zLyTeTEZtivDnYCPZmcSt16EYCER"
}
            

In the example above, the `secretKeyMultibase` value starts with the letter `z`, which is the [[MULTIBASE]] header that conveys that the binary data is base58-encoded using the Bitcoin base-encoding alphabet. The decoded binary data [[MULTICODEC]] header is `0x1300`, which specifies that the remaining data is a 32-byte raw Ed25519 private key.

Referring to Verification Methods

Verification methods can be embedded in or referenced from properties associated with various verification relationships as described in . Referencing verification methods allows them to be used by more than one verification relationship.

If the value of a verification method property is a map, the verification method has been embedded and its properties can be accessed directly. However, if the value is a URL string, the verification method has been included by reference and its properties will need to be retrieved from elsewhere in the controller document or from another controller document. This is done by dereferencing the URL and searching the resulting resource for a verification method map with an id property whose value matches the URL.

    {
...

      "authentication": [
        // this key is referenced and might be used by
        // more than one verification relationship
        "did:example:123456789abcdefghi#keys-1",
        // this key is embedded and may *only* be used for authentication
        {
          "id": "did:example:123456789abcdefghi#keys-2",
          "type": "Multikey", // external (property value)
          "controller": "did:example:123456789abcdefghi",
          "publicKeyMultibase": "z6MkmM42vxfqZQsv4ehtTjFFxQ4sQKS2w6WR7emozFAn5cxu"
        }
      ],

...
    }
            

Verification Relationships

A verification relationship expresses the relationship between the controller and a verification method.

Different verification relationships enable the associated verification methods to be used for different purposes. It is up to a verifier to ascertain the validity of a verification attempt by checking that the verification method used is contained in the appropriate verification relationship property of the controller document.

The verification relationship between the controller and the verification method is explicit in the controller document. Verification methods that are not associated with a particular verification relationship cannot be used for that verification relationship. For example, a verification method in the value of the authentication property cannot be used to engage in key agreement protocols with the controller—the value of the keyAgreement property needs to be used for that.

The controller document does not express revoked keys using a verification relationship. If a referenced verification method is not in the latest controller document used to dereference it, then that verification method is considered invalid or revoked.

The following sections define several useful verification relationships. A controller document MAY include any of these, or other properties, to express a specific verification relationship. In order to maximize global interoperability, any such properties used SHOULD be registered in the Data Integrity Specification Registries [TBD: DIS-REGISTRIES].

Authentication

The authentication verification relationship is used to specify how the controller is expected to be authenticated, for purposes such as logging into a website or engaging in any sort of challenge-response protocol.

authentication
The authentication property is OPTIONAL. If present, the associated value MUST be a set of one or more verification methods. Each verification method MAY be embedded or referenced.
    {
      "@context": [
        "https://www.w3.org/ns/did/v1",
        "https://w3id.org/security/multikey/v1"
      ],
      "id": "did:example:123456789abcdefghi",
      ...
      "authentication": [
        // this method can be used to authenticate as did:...fghi
        "did:example:123456789abcdefghi#keys-1",
        // this method is *only* approved for authentication, it may not
        // be used for any other proof purpose, so its full description is
        // embedded here rather than using only a reference
        {
          "id": "did:example:123456789abcdefghi#keys-2",
          "type": "Multikey",
          "controller": "did:example:123456789abcdefghi",
          "publicKeyMultibase": "z6MkmM42vxfqZQsv4ehtTjFFxQ4sQKS2w6WR7emozFAn5cxu"
        }
      ],
      ...
    }
            

If authentication is established, it is up to the application to decide what to do with that information.

This is useful to any authentication verifier that needs to check to see if an entity that is attempting to authenticate is, in fact, presenting a valid proof of authentication. When a verifier receives some data (in some protocol-specific format) that contains a proof that was made for the purpose of "authentication", and that says that an entity is identified by the `id`, then that verifier checks to ensure that the proof can be verified using a verification method (e.g., public key) listed under authentication in the controller document.

Note that the verification method indicated by the authentication property of a controller document can only be used to authenticate the controller. To authenticate a different controller, the entity associated with the value of controller needs to authenticate with its own controller document and associated authentication verification relationship.

Assertion

The assertionMethod verification relationship is used to specify how the controller is expected to express claims, such as for the purposes of issuing a Verifiable Credential [[?VC-DATA-MODEL-2]].

assertionMethod
The assertionMethod property is OPTIONAL. If present, the associated value MUST be a set of one or more verification methods. Each verification method MAY be embedded or referenced.

This property is useful, for example, during the processing of a verifiable credential by a verifier. During verification, a verifier checks to see if a verifiable credential contains a proof created by the controller by checking that the verification method used to assert the proof is associated with the assertionMethod property in the corresponding controller document.

    {
      "@context": [
        "https://www.w3.org/ns/did/v1",
        "https://w3id.org/security/multikey/v1"
      ],
      "id": "did:example:123456789abcdefghi",
      ...
      "assertionMethod": [
        // this method can be used to assert statements as did:...fghi
        "did:example:123456789abcdefghi#keys-1",
        // this method is *only* approved for assertion of statements, it is not
        // used for any other verification relationship, so its full description is
        // embedded here rather than using a reference
        {
          "id": "did:example:123456789abcdefghi#keys-2",
          "type": "Multikey", // external (property value)
          "controller": "did:example:123456789abcdefghi",
          "publicKeyMultibase": "z6MkmM42vxfqZQsv4ehtTjFFxQ4sQKS2w6WR7emozFAn5cxu"
        }
      ],
      ...
    }
            

Key Agreement

The keyAgreement verification relationship is used to specify how an entity can generate encryption material in order to transmit confidential information intended for the controller, such as for the purposes of establishing a secure communication channel with the recipient.

keyAgreement
The keyAgreement property is OPTIONAL. If present, the associated value MUST be a set of one or more verification methods. Each verification method MAY be embedded or referenced.

An example of when this property is useful is when encrypting a message intended for the controller. In this case, the counterparty uses the cryptographic public key information in the verification method to wrap a decryption key for the recipient.

    {
      "@context": "https://www.w3.org/ns/did/v1",
      "id": "did:example:123456789abcdefghi",
      ...
      "keyAgreement": [
        // this method can be used to perform key agreement as did:...fghi
        "did:example:123456789abcdefghi#keys-1",
        // this method is *only* approved for key agreement usage, it will not
        // be used for any other verification relationship, so its full description is
        // embedded here rather than using only a reference
        {
          "id": "did:example:123#zC9ByQ8aJs8vrNXyDhPHHNNMSHPcaSgNpjjsBYpMMjsTdS",
          "type": "X25519KeyAgreementKey2019", // external (property value)
          "controller": "did:example:123",
          "publicKeyMultibase": "z6LSn6p3HRxx1ZZk1dT9VwcfTBCYgtNWdzdDMKPZjShLNWG7"
        }
      ],
      ...
    }
            

Capability Invocation

The capabilityInvocation verification relationship is used to specify a verification method that might be used by the controller to invoke a cryptographic capability, such as the authorization to update the controller document.

capabilityInvocation
The capabilityInvocation property is OPTIONAL. If present, the associated value MUST be a set of one or more verification methods. Each verification method MAY be embedded or referenced.

An example of when this property is useful is when a controller needs to access a protected HTTP API that requires authorization in order to use it. In order to authorize when using the HTTP API, the controller uses a capability that is associated with a particular URL that is exposed via the HTTP API. The invocation of the capability could be expressed in a number of ways, e.g., as a digitally signed message that is placed into the HTTP Headers.

The server providing the HTTP API is the verifier of the capability and it would need to verify that the verification method referred to by the invoked capability exists in the capabilityInvocation property of the controller document. The verifier would also check to make sure that the action being performed is valid and the capability is appropriate for the resource being accessed. If the verification is successful, the server has cryptographically determined that the invoker is authorized to access the protected resource.

    {
      "@context": [
        "https://www.w3.org/ns/did/v1",
        "https://w3id.org/security/multikey/v1"
      ],
      "id": "did:example:123456789abcdefghi",
      ...
      "capabilityInvocation": [
        // this method can be used to invoke capabilities as did:...fghi
        "did:example:123456789abcdefghi#keys-1",
        // this method is *only* approved for capability invocation usage, it will not
        // be used for any other verification relationship, so its full description is
        // embedded here rather than using only a reference
        {
        "id": "did:example:123456789abcdefghi#keys-2",
        "type": "Multikey", // external (property value)
        "controller": "did:example:123456789abcdefghi",
        "publicKeyMultibase": "z6MkmM42vxfqZQsv4ehtTjFFxQ4sQKS2w6WR7emozFAn5cxu"
        }
      ],
      ...
    }
            

Capability Delegation

The capabilityDelegation verification relationship is used to specify a mechanism that might be used by the controller to delegate a cryptographic capability to another party, such as delegating the authority to access a specific HTTP API to a subordinate.

capabilityDelegation
The capabilityDelegation property is OPTIONAL. If present, the associated value MUST be a set of one or more verification methods. Each verification method MAY be embedded or referenced.

An example of when this property is useful is when a controller chooses to delegate their capability to access a protected HTTP API to a party other than themselves. In order to delegate the capability, the controller would use a verification method associated with the capabilityDelegation verification relationship to cryptographically sign the capability over to another controller. The delegate would then use the capability in a manner that is similar to the example described in .

    {
      "@context": [
        "https://www.w3.org/ns/did/v1",
        "https://w3id.org/security/multikey/v1"
      ],
      "id": "did:example:123456789abcdefghi",
      ...
      "capabilityDelegation": [
        // this method can be used to perform capability delegation as did:...fghi
        "did:example:123456789abcdefghi#keys-1",
        // this method is *only* approved for granting capabilities; it will not
        // be used for any other verification relationship, so its full description is
        // embedded here rather than using only a reference
        {
        "id": "did:example:123456789abcdefghi#keys-2",
        "type": "Multikey", // external (property value)
        "controller": "did:example:123456789abcdefghi",
        "publicKeyMultibase": "z6MkmM42vxfqZQsv4ehtTjFFxQ4sQKS2w6WR7emozFAn5cxu"
        }
      ],
      ...
    }
            

Relationship to Linked Data

The term Linked Data is used to describe a recommended best practice for exposing, sharing, and connecting information on the Web using standards, such as URLs, to identify things and their properties. When information is presented as Linked Data, other related information can be easily discovered and new information can be easily linked to it. Linked Data is extensible in a decentralized way, greatly reducing barriers to large scale integration.

With the increase in usage of Linked Data for a variety of applications, there is a need to be able to verify the authenticity and integrity of Linked Data documents. This specification adds authentication and integrity protection to data documents through the use of mathematical proofs without sacrificing Linked Data features such as extensibility and composability.

While this specification provides mechanisms to digitally sign Linked Data, the use of Linked Data is not necessary to gain some of the advantages provided by this specification.

Cryptographic Suites

A data integrity proof is designed to be easy to use by developers and therefore strives to minimize the amount of information one has to remember to generate a proof. Often, just the cryptographic suite name (e.g. eddsa-2022) is required from developers to initiate the creation of a proof. These cryptographic suites are often created or reviewed by people that have the requisite cryptographic training to ensure that safe combinations of cryptographic primitives are used. This section specifies the requirements for authoring cryptographic suite specifications.

The requirements for all data integrity cryptographic suite specifications are as follows:

The following language was deemed to be contentious: The specification MUST provide a link to an interoperability test report to document which implementations are conformant with the cryptographic suite specification.

The Working Group is seeking feedback on whether or not this is desired given the important role that cryptographic suite specifications play in ensuring data integrity.

DataIntegrityProof

A number of cryptographic suites follow the same basic pattern when expressing a data integrity proof. This section specifies that general design pattern, a cryptographic suite type called a `DataIntegrityProof`, which reduces the burden of writing and implementing cryptographic suites through the reuse of design primitives and source code.

When specifing a cryptographic suite that utilizes this design pattern, the `proof` value takes the following form:

type
The `type` property MUST contain the string `DataIntegrityProof`.
cryptosuite
The `cryptosuite` property MUST contain a string specifying the name of the cryptosuite.
proofValue
The `proofValue` property MUST be used, as specified in .

Cryptographic suite designers MUST use mandatory `proof` value properties defined in Section , and MAY define other properties specific to their cryptographic suite.

Algorithms

The algorithms defined below are generalized in that they require a specific transformation algorithm, hashing algorithm, proof generation algorithm, and proof verification algorithm to be specified by a particular cryptographic suite (see Section ).

At present the creation of the verification hash is delegated to the cryptographic suite specification when generating and verifying a proof. It is expected that this algorithm is going to be common to most cryptographic suites. It is predicted that the verification hash generation algorithm will eventually be defined in this specification.

Generate Proof

The following algorithm specifies how to create a digital proof that can be used to verify the authenticity and integrity of an unsecured data document. Required inputs are an unsecured data document (unsecuredDocument) and proof options (options). The proof options MUST contain a type identifier for the cryptographic suite (type) and any other properties needed by the cryptographic suite type; an identifier for the verification method (verificationMethod) that can be used to verify the authenticity of the proof; and an [[!XMLSCHEMA11-2]] combined date and time string (created) containing the current date and time, accurate to at least one second, in Universal Time Code format. A security domain (domain) and receiver-supplied challenge (challenge) might also be specified in the options. A secured data document is produced as output. Whenever this algorithm encodes strings, it MUST use UTF-8 encoding.

  1. Let output be a copy of unsecuredDocument.
  2. Let transformedDocument be the result of transforming unsecuredDocument according to a transformation algorithm associated with the cryptographic suite and the options parameters provided as inputs to the algorithm.
  3. Let hashData be the result of hashing the transformedDocument according to a hashing algorithm associated with the cryptographic suite and the options parameters provided as inputs to the algorithm.
  4. Let proof be the result of running the proof generation algorithm associated with the cryptographic suite with the hashData and options parameters provided as inputs to the algorithm.
  5. If the proof.type, proof.verificationMethod, or proof.proofPurpose values are not set, a `PROOF_GENERATION_ERROR` MUST be raised.
  6. If the cryptographic suite requires the use of a created timestamp, and the proof.created value is not set, a `PROOF_GENERATION_ERROR` MUST be raised.
  7. If options.domain is set, it MUST be equal to proof.domain or a `PROOF_GENERATION_ERROR` MUST be raised.
  8. If options.challenge is set, it MUST be equal to proof.challenge or a `PROOF_GENERATION_ERROR` MUST be raised.
  9. Set output.proof to the value of proof.
  10. Return output as the secured data document.

While the output of the hashing algorithm can be a single value, such as a 32 byte SHA2-256 value, implementers are advised that some cryptographic suite(s) might define `hashData` to be comprised of multiple values that might be processed independently in the proof generation algorithm. For example, this approach is known to be taken in certain cryptographic suites that allow selective disclosure or unlinkability via the digital proof.

Verify Proof

The following algorithm specifies how to check the authenticity and integrity of a secured data document by verifying its digital proof. Required inputs are a secured data document (securedDocument) and proof options (options). A verification result is produced as output.

  1. Let proof be set to securedDocument.proof.
  2. If the proof.type, proof.verificationMethod, or proof.proofPurpose values are not set, a `MALFORMED_PROOF_ERROR` MUST be raised.
  3. If the cryptographic suite requires the proof.created value, and it is not set, a `MALFORMED_PROOF_ERROR` MUST be raised.
  4. If the proof.proofPurpose value does not match options.expectedProofPurpose, a `MISMATCHED_PROOF_PURPOSE_ERROR` MUST be raised.
  5. Let unsecuredDocument be a copy of securedDocument with the `proof` value removed.
  6. Let transformedDocument be the result of transforming the unsecuredDocument according to a transformation algorithm associated with the cryptographic suite specified in proof and the options parameters provided as inputs to the algorithm. The type of cryptographic suite is specified by the proof.type value and MAY be further described by cryptographic suite-specific properties expressed in proof.
  7. Let hashData be the result of hashing the transformedDocument according to a hashing algorithm associated with the cryptographic suite specified in the proof and options parameters provided as inputs to the algorithm.
  8. Let isProofVerified be the result of running the proof verification algorithm associated with the cryptographic suite with the hashData and options parameters provided as inputs to the algorithm.
  9. If the proof.created is set and it deviates more than options.acceptableCreatedTimeDeviationInSeconds seconds, a `CREATED_TIME_DEVIATION_ERROR` MUST be raised.
  10. If options.domain is set and it does not match proof.domain, an `INVALID_DOMAIN_ERROR` MUST be raised.
  11. If options.challenge is set and it does not match proof.challenge, an `INVALID_CHALLENGE_ERROR` MUST be raised.
  12. Return isProofVerified as the verification result.

Specify how proof.verificationMethod can be obtained, e.g., through some out-of-band process, by dereferencing its URL identifier, etc. It is expected that the public key is retrieved by dereferencing its URL identifier in the proof node of the default graph of securedDocument. The algorithm needs to confirm that the verification method that describes the cryptographic material, such as the public key, specifies its controller, and that its controllers's URL identifier can be dereferenced to reveal a bi-directional link back to the key. Ensure that the key's controller is a trusted entity before proceeding to the next step.

Security Considerations

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

Versioning Cryptography Suites

Cryptography secures information through the use of secrets. Knowledge of the necessary secret makes it computationally easy to access certain information. The same information can be accessed if a computationally-difficult, brute-force effort successfully guesses the secret. All modern cryptography requires the computationally difficult approach to remain difficult throughout time, which does not always hold due to breakthroughs in science and mathematics. That is to say that Cryptography has a shelf life.

This specification plans for the obsolescence of all cryptographic approaches by asserting that whatever cryptography is in use today is highly likely to be broken over time. Software systems have to be able to change the cryptography in use over time in order to continue to secure information. Such changes might involve increasing required secret sizes or modifications to the cryptographic primitives used. However, some combinations of cryptographic parameters might actually reduce security. Given these assumptions, systems need to be able to distinguish different combinations of safe cryptographic parameters, also known as cryptographic suites, from one another. When identifying or versioning cryptographic suites, there are several approaches that can be taken which include: parameters, numbers, and dates.

Parametric versioning specifies the particular cryptographic parameters that are employed in a cryptographic suite. For example, one could use an identifier such as `RSASSA-PKCS1-v1_5-SHA1`. The benefit to this scheme is that a well-trained cryptographer will be able to determine all of the parameters in play by the identifier. The drawback to this scheme is that most of the population that uses these sorts of identifiers are not well trained and thus will not understand that the previously mentioned identifier is a cryptographic suite that is no longer safe to use. Additionally, this lack of knowledge might lead software developers to generalize the parsing of cryptographic suite identifiers such that any combination of cryptographic primitives becomes acceptable, resulting in reduced security. Ideally, cryptographic suites are implemented in software as specific, acceptable profiles of cryptographic parameters instead.

Numbered versioning might specify a major and minor version number such as `1.0` or `2.1`. Numbered versioning conveys a specific order and suggests that higher version numbers are more capable than lower version numbers. The benefit of this approach is that it removes complex parameters that less expert developers might not understand with a simpler model that conveys that an upgrade might be appropriate. The drawback of this approach is that its not clear if an upgrade is necessary, as software version number increases often don't require an upgrade for the software to continue functioning. This can lead to developers thinking their usage of a particular version is safe, when it is not. Ideally, additional signals would be given to developers that use cryptographic suites in their software that periodic reviews of those suites for continued security are required.

Date-based versioning specifies a particular release date for a specific cryptographic suite. The benefit of a date, such as a year, is that it is immediately clear to a developer if the date is relatively old or new. Seeing an old date might prompt the developer to go searching for a newer cryptographic suite, where as a parametric or number-based versioning scheme might not. The downside of a date-based version is that some cryptographic suites might not expire for 5-10 years, prompting the developer to go searching for a newer cryptographic suite only to not find one that is newer. While this might be an inconvenience, it is one that results in safer ecosystem behavior.

The following text is currently under debate:

It is highly encouraged that cryptographic suite identifiers are versioned using a year designation. For example, the cryptographic suite identifier `ecdsa-2022` implies that the suite is probably an acceptable of ECDSA in the year 2025, but might not be a safe choice in the year 2042. A date-based versioning mechanism, however, is not enough by itself. All cryptographic suites that follow this specification are intended to be registered [[?VC-EXTENSION-REGISTRY]] in a way that clearly signal which cryptosuites are deprecated, standardized, or experimental. Cryptosuite registration will follow CFRG, IETF, NIST, FIPS, and safecurves guidance. Use of deprecated suites are expected to throw errors in implementations unless a `useUnsafeCryptosuites` option is used specifying exactly the unsafe cryptosuite to use. Use of experimental suites are expected to throw errors in implementations unless a `useExperimentalCryptosuites` option is used specifying exactly the experimental cryptosuite to use.

The following text is debated due to the governance rules of the VC Extension Registry not being finalized:

Developers are urged to always refer to the [[?VC-EXTENSION-REGISTRY]] for the latest standardized cryptography suites as well as cross-checking their usage against, at least, the COSE Algorithms Registry, the JOSE Algorithms Registry, and the latest FIPS Digital Signature Standard guidance. Depending on your jurisdiction you may also need to consider additional guidance from ETSI or other regional regulatory and standards bodies.

Protecting Application Developers

Modern cryptographic algorithms provide a number of tunable parameters and options to ensure that the algorithms can meet the varied requirements of different use cases. For example, embedded systems have limited processing and memory environments and might not have the resources to generate the strongest digital signatures for a given algorithm. Other environments, like financial trading systems, might only need to protect data for a day while the trade is occurring, while other environments might need to protect data for multiple decades. To meet these needs, cryptographic algorithm designers often provide multiple ways to configure a cryptographic algorithm.

Cryptographic library implementers often take the specifications created by cryptographic algorithm designers and specification authors and implement them such that all options are available to the application developers that use their libraries. This can be due to not knowing which combination of features a particular application developer might need for a given cryptographic deployment. All options are often exposed to application developers.

Application developers that use cryptographic libraries often do not have the requisite cryptographic expertise and knowledge necessary to appropriately select cryptographic parameters and options for a given application. This lack of expertise can lead to an inappropriate selection of cryptographic parameters and options for a particular application.

This specification sets the priority of constituencies to protect application developers over cryptographic library implementers over cryptographic specification authors over cryptographic algorithm designers. Given these priorities, the following recommendations are made:

The guidance above is meant to ensure that useful cryptographic options and parameters are provided at the lower layers of the architecture while not exposing those options and parameters to application developers who may not fully understand the balancing benefits and drawbacks of each option.

The VCWG is seeking guidance on adding language to allow the use of experimental or deprecated cryptography. By default, those features will be disabled and will require the application developer to specifically allow use on a per-cryptographic suite basis. There will be requirements for all implementing libraries to throw errors or warnings when deprecated or experimental options are selected without the appropriate override flags.

Agility and Layering

Cryptographic agility is a practice by which one designs frequently connected information security systems to support switching between multiple cryptographic primitives and/or algorithms. The primary goal of cryptographic agility is to enable systems to rapidly adapt to new cryptographic primitives and algorithms without making disruptive changes to the systems' infrastructure. Thus, when a particular cryptographic primitive, such as the SHA-1 algorithm, is determined to be no longer safe to use, systems can be reconfigured to use a newer primitive via a simple configuration file change.

Cryptographic agility is most effective when the client and the server in the information security system are in regular contact. However, when the messages protected by a particular cryptographic algorithm are long-lived, as with Verifiable Credentials, and/or when the client (holder) might not be able to easily recontact the server (issuer), then cryptographic agility does not provide the desired protections.

Cryptographic layering is a practice where one designs rarely connected information security systems to employ multiple primitives and/or algorithms at the same time. The primary goal of cryptographic layering is to enable systems to survive the failure or one or more cryptographic algorithms or primitives without losing cryptographic protection on the payload. For example, digitally signing a single piece of information using RSA, ECDSA, and Falcon algorithms in parallel would provide a mechanism that could survive the failure of two of these three digital signature algorithms. When a particular cryptographic protection is compromised, such as an RSA digital signature using 768-bit keys, systems can still utilize the non-compromised cryptographic protections to continue to protect the information. Developers are urged to take advantage of this feature for all signed content that might need to be protected for a year or longer.

This specification provides for both forms of agility. It provides for cryptographic agility, which allows one to easily switch from one algorithm to another. It also provides for cryptographic layering, which allows one to simultaneously use multiple cryptographic algorithms, typically in parallel, such that any of those used to protect information can be used without reliance on or requirement of the others, while still keeping the digital proof format easy to use for developers.

Transformations

At times, it is beneficial to transform the data being protected during the cryptographic protection process. Such "in-line" transformation can enable a particular type of cryptographic protection to be agnostic to the data format it is carried in. For example, some Data Integrity cryptographic suites utilize RDF Dataset Canonicalization [[?RDF-DATASET-C14N]] which transforms the initial representation into a canonical form [[?N-QUADS]] that is then serialized, hashed, and digitally signed. As long as any syntax expressing the protected data can be transformed into this canonical form, the digital signature can be verified. This enables the same digital signature over the information to be expressed in JSON, CBOR, YAML, and other compatible syntaxes without having to create a cryptographic proof for every syntax.

Being able to express the same digital signature across a variety of syntaxes is beneficial because systems often have native data formats with which they operate. For example, some systems are written against JSON data, while others are written against CBOR data. Without transformation, systems that process their data internally as CBOR are required to store the digitally signed data structures as JSON (or vice-versa). This leads to double-storing data and can lead to increased security attack surface if the unsigned representation stored in databases accidentally deviates from the signed representation. By using transformations, the digital proof can live in the native data format to help prevent otherwise undetectable database drift over time.

This specification is designed to avoid requiring the duplication of signed information by utilizing "in-line" data transformations. Application developers are urged to work with cryptographically protected data in the native data format for their application and not separate storage of cryptographic proofs from the data being protected. Developers are also urged to regularly confirm that the cryptographically protected data has not been tampered with as it is written to and read from application storage.

The VCWG is seeking feedback on normative language that cryptographic suite implementers need to follow to ensure that they do not utilize data transformation mechanisms that can map to the same output. That is, given different inputs for canonicalization scheme #1 and canonicalization scheme #2, they must not produce the same output value. As an analogy, this is the same requirement for cryptographic hashing mechanisms and is why those schemes are designed to be collision resistant. Cryptographic canonicalization mechanisms have the same requirement. At present, this isn't a problem because the three expected canonicalization schemes — the Universal RDF Dataset Canonicalization Algorithm 2015 [[?RDF-DATASET-C14N]], JSON Canonicalization Scheme [[?RFC8785]], and a theoretical future base-encoding canonicalization — have entirely different outputs.

The VCWG is seeking feedback on whether to explain why modern canonicalization schemes are simpler than the far more complex XML Canonicalization schemes of the early 2000s. Some readers seem to be under the impression that all canonicalization is difficult and has to be avoided at all costs (including costs to application developers). The WG would like to understand if it would be helpful to include a section explaining why some simpler data syntaxes (such as JSON) are easier to canonicalize than more complex data syntaxes (such as XML).

Data Opacity

The inspectability of application data has effects on system efficiency and developer productivity. When cryptographically protected application data, such as base-encoded binary data, is not easily processed by application subsystems, such as databases, it increases the effort of working with the cryptographically protected information. For example, a cryptographically protected payload that can be natively stored and indexed by a database will result in a simpler system that:

Similarly, a cryptographically protected payload that can be processed by multiple upstream networked systems increases the ability to properly layer security architectures. For example, if upstream systems do not have to repeatedly decode the incoming payload, it increases the ability for a system to distribute processing load by specializing upstream subsystems to actively combat attacks. While a digital signature needs to always be checked before taking substantive action, other upstream checks can be performed on transparent payloads — such as identifier-based rate limiting, signature expiration checking, or nonce/challenge checking — to reject obviously bad requests.

Additionally, if a developer is not able to easily view data in a system, the ability to easily audit or debug system correctness is hampered. For example, requiring application developers to cut-and-paste base-encoded application data makes development more challenging and increases the chances that obvious bugs will be missed because every message needs to go through a manually operated base-decoding tool.

There are times, however, where the correct design decision is to make data opaque. Data that does not need to be processed by other application subsystems, as well as data that does not need to be modified or accessed by an application developer, can be serialized into opaque formats. Examples include digital signature values, cryptographic key parameters, and other data fields that only need to be accessed by a cryptographic library and need not be modified by the application developer. There are also examples where data opacity is appropriate when the underlying subsystem does not expose the application developer to the underlying complexity of the opaque data, such as databases that perform encryption at rest. In these cases, the application developer continues to develop against transparent application data formats while the database manages the complexity of encrypting and decrypting the application data to and from long-term storage.

This specification strives to provide an architecture where application data remains in its native format and is not made opaque, while other cryptographic data, such as digital signatures, are kept in their opaque binary encoded form. Cryptographic suite implementers are urged to consider appropriate use of data opacity when designing their suites, and to weigh the design trade-offs when making application data opaque versus providing access to cryptographic data at the application layer.

Verification Method Binding

Implementers must ensure that a verification method is bound to a particular controller by going from the verification method to the controller document, and then ensuring that the controller document also contains the verification method.

Verification Relationship Validation

Implementers need to ensure that when a verification method is used, that it matches the verification relationship associated with it and that it lines up with the proof purpose.

Canonicalization Method Correctness

Canonicalization mechanisms utilized for normalizing input to hashing functions need to have vetted mathematical proofs associted with them. Canonicalization mechanisms that create collisions in hash functions can be used to attack digital signatures.

Privacy Considerations

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

Unlinkability

When a digitally-signed payload contains data that is seen by multiple verifiers, it becomes a point of correlation. An example of such data is a shopping loyalty card number. Correlatable data can be used for tracking purposes by verifiers, which can sometimes violate privacy expectations. The fact that some data can be used for tracking might not be immediately apparent. Examples of such correlatable data include, but are not limited to, a static digital signature or a cryptographic hash of an image.

It is possible to create a digitally-signed payload that does not have any correlatable tracking data while also providing some level of assurance that the payload is trustworthy for a given interaction. This characteristic is called unlinkability which ensures that no correlatable data are used in a digitally-signed payload while still providing some level of trust, the sufficiency of which must be determined by each verifier.

It is important to understand that not all use cases require or even permit unlinkability. There are use cases where linkability and correlation are required due to regulatory or safety reasons, such as correlating organizations and individuals that are shipping and storing hazardous materials. Unlinkability is useful when there is an expectation of privacy for a particular interaction.

There are at least two mechanisms that can provide some level of unlinkability. The first method is to ensure that no data value used in the message is ever repeated in a future message. The second is to ensure that any repeated data value provides adequate herd privacy such that it becomes practically impossible to correlate the entity that expects some level of privacy in the interaction.

A variety of methods can be used to achieve unlinkability. These methods include ensuring that a message is a single use bearer token with no information that can be used for the purposes of correlation, using attributes that ensure an adequate level of herd privacy, and the use of cryptosuites that enable the entity presenting a message to regenerate new signatures while not compromising the trust in the message being presented.

Selective Disclosure

Selective disclosure is a technique that enables the recipient of a previously-signed message (that is, a message signed by its creator) to reveal only parts of the message without disturbing the verifiability of those parts. For example, one might selectively disclose a digital driver's license for the purpose of renting a car. This could involve revealing only the issuing authority, license number, birthday, and authorized motor vehicle class from the license. Note that in this case, the license number is correlatable information, but some amount of privacy is preserved because the driver's full name and address are not shared.

Not all software or cryptosuites are capable of providing selective disclosure. If the author of a message wishes it to be selectively disclosable by its recipient, then they need to enable selective disclosure on the specific message, and both need to use a capable cryptosuite. The author might also make it mandatory to disclose certain parts of the message. A recipient that wants to selectively disclose partial content of the message needs to utilize software that is able to perform the technique. An example of a cryptosuite that supports selective disclosure is `bbs-2022`.

It is possible to selectively disclose information in a way that does not preserve unlinkability. For example, one might want to disclose the inspection results related to a shipment, which include the shipment identifier or lot number, which might have to be correlatable due to regulatory requirements. However, disclosure of the entire inspection result might not be required as selectively disclosing just the pass/fail status could be deemed adequate. For more information on disclosing information while preserving privacy, see Section .