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.

Introduction

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.

A conforming controller document is any concrete expression of the data model that follows the relevant normative requirements in Sections and .

A conforming verification method is any concrete expression of the data model that follows the relevant normative requirements in Sections and .

A conforming document is either a conforming controller document, or a conforming verification method.

A conforming processor is any algorithm realized as software and/or hardware that generates and/or consumes a conforming document according to the relevant normative statements in Section . Conforming processors MUST produce errors when non-conforming documents are consumed.

Terminology

Data Model

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

The `verificationMethod` property is REQUIRED for proofs, unlike controller documents, for which it is optional. See section .

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.
expires
The `expires` property is OPTIONAL. It is set, in advance, by the controller of a verification method to signal when that method can no longer be used for verification purposes. If provided, it MUST be an [[XMLSCHEMA11-2]] `dateTimeStamp` string specifying when the verification method SHOULD cease to be used. Once the value is set, it is not expected to be updated, and systems depending on the value are expected to not verify any proofs associated with the verification method at or after the time of expiration.
revoked
The `revoked` property is OPTIONAL. It is set by the controller of a verification method to signal when that method is to no longer to be used for verification purposes, such as after a security compromise of the verification method. If provided, it MUST be an [[XMLSCHEMA11-2]] `dateTimeStamp` string specifying when the verification method SHOULD cease to be used. Once the value is set, it is not expected to be updated, and systems depending on the value are expected to not verify any proofs associated with the verification method at or after the time of revocation.
    {
      "@context": [
        "https://www.w3.org/ns/did/v1",
        "https://w3id.org/security/data-integrity/v2"
      ]
      "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 methods include `JsonWebKey` and `Multikey`. A cryptographic suite specification is responsible for specifying the verification method `type` and its associated verification material format. For examples, see the Data Integrity ECDSA Cryptosuites and the Data Integrity EdDSA Cryptosuites. For a list of verification method types, please see the [[?SECURITY-VOCABULARY]].

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 easing implementation and providing support for formats that have historically had broad deployment.

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/jwk/v1",
        "https://w3id.org/security/multikey/v1"
      ]
      "id": "did:example:123456789abcdefghi",
      ...
      "verificationMethod": [{
        "id": "did:example:123#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A",
        "type": "JsonWebKey", // 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 encodes key types into a single binary stream that is then encoded as a Multibase value as described in Section .

When specifing a `Multikey`, the object takes the following form:

type
The value of the `type` property MUST contain the string `Multikey`.
publicKeyMultibase
The `publicKeyMultibase` property is OPTIONAL. If present, its value MUST be a Multibase encoded value as described in Section .
secretKeyMultibase
The `secretKeyMultibase` property is OPTIONAL. If present, its value MUST be a Multibase encoded value as described in Section .

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 base-58-btc-encoded using the Bitcoin base-encoding alphabet. The decoded binary data header is `0xed01`, 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, whose subtypes include symmetric keys and 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 base-58-btc-encoded using the Bitcoin base-encoding alphabet. The decoded binary data header is `0x8026`, which specifies that the remaining data is a 32-byte raw Ed25519 private key.

JsonWebKey

The JSON Web Key (JWK) data model is a specific type of verification method that uses the JWK specification [[RFC7517]] to encode key types into a set of parameters.

When specifing a `JsonWebKey`, the object takes the following form:

type
The value of the `type` property MUST contain the string `JsonWebKey`.
publicKeyJwk
The `publicKeyJwk` property is OPTIONAL. If present, its value MUST be a map representing a JSON Web Key that conforms to [[RFC7517]]. The map MUST NOT include any members of the private information class, such as `d`, as described in the JWK 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.
secretKeyJwk
The `secretKeyJwk` property is OPTIONAL. If present, its value MUST be a map representing a JSON Web Key that conforms to [[RFC7517]].

An example of an object that conforms to this data model is provided below:

{
  "@context": ["https://www.w3.org/ns/security/jwk/v1"],
  "id": "did:example:123456789abcdefghi#key-1",
  "type": "JsonWebKey",
  "controller": "did:example:123456789abcdefghi",
  "publicKeyJwk": {
    "kty": "OKP",
    "alg": "EdDSA"
    "crv": "Ed25519",
    "kid": "key-1",
    "x": "_1EiHquO2aUx9JARSu0P8jdYT_OVneYxYOnOMAmUcFI",
  }
}
            

In the example above, the `publicKeyJwk` value contains the JSON Web Key. The `kty` property encodes the key type of "OKP", which means "Octet string key pairs". The `alg` property identifies the algorithm intended for use with the public key. The `crv` property identifies the particular curve type of the public key. The `kid` property specifies how the public key might be referenced in software systems; if present, the `kid` value SHOULD match the `id` property of the encapsulating `JsonWebKey` object. Finally, the `x` property specifies the point on the Ed25519 curve that is associated with the public key.

The `publicKeyJwk` property MUST NOT contain any property marked as "Private" in any registry contained in the JOSE Registries [[JOSE-REGISTRIES]].

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

{
  "@context": ["https://www.w3.org/ns/security/jwk/v1"],
  "id": "did:example:123456789abcdefghi#key-1",
  "type": "JsonWebKey",
  "controller": "did:example:123456789abcdefghi",
  "secretKeyJwk": {
    "kty": "OKP",
    "alg": "EdDSA"
    "crv": "Ed25519",
    "kid": "key-1",
    "d": "Q6JwjCUdThSnoxfXHSFt5C1nVFycY_ZpW7qVzK644_g",
    "x": "_1EiHquO2aUx9JARSu0P8jdYT_OVneYxYOnOMAmUcFI",
  }
}
            

The private key example above is almost identical to the previous example of the public key, except that the information is stored in the `secretKeyJwk` property (rather than the `publicKeyJwk`), and the private key value is encoded in the `d` property thereof (alongside the `x` property, which still specifies the point on the Ed25519 curve that is associated with the public 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.0]].

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"
        }
      ],
      ...
    }
            

Multibase

The [[?MULTIBASE]] specification has been dispatched at IETF and may be standardized there. There is active discussion on this initiative in the Multiformats mailing list at IETF. If the Multibase draft is stabilized before this specification goes to the Proposed Recommendation phase, the table below will be replaced with normative references to the Multibase specification at IETF. It is the intention of the Working Group to ensure alignment between the Multibase values used in this specification and the Multibase values defined by the current Multibase community and any potential future IETF Multiformats Working Group.

A Multibase string includes a single character header which identifies the base and encoding alphabet used to encode a binary value, followed by the encoded binary value (using that base and alphabet). The common Multibase header values and their associated base encoding alphabets as provided below are normative:

Multibase Header Description
`u` The base-64-url-no-pad alphabet is used to encode the bytes. The base-alphabet consists of the following characters, in order: `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_`
`z` The base-58-btc alphabet is used to encode the bytes. The base-alphabet consists of the following characters, in order: `123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz`

Other Multibase encoding values MAY be used, but interoperability is not guaranteed between implementations using such values.

To base-encode a binary value into a Multibase string, an implementation MUST apply the algorithm in Section to the binary value, with the desired base encoding and alphabet from the table above, ensuring to prepend the associated Multibase header from the table above to the result. Any algorithm with equivalent output MAY be used.

To base-decode a Multibase string, an implementation MUST apply the algorithm in Section to the string following the first character (Multibase header), with the alphabet associated with the Multibase header. Any algorithm with equivalent output MAY be used.

Multihash

The [[?MULTIHASH]] specification has been dispatched at IETF and may be standardized. There is active discussion on this initiative in the Multiformats mailing list at IETF. If the IETF draft is stabilized before this specification goes to the Proposed Recommendation phase, the table below will be replaced with normative references to the Multihash specification. It is the intention of the Working Group to ensure alignment between the Multihash values used in this specification and the Multihash values defined by the current Multihash community and any potential future IETF Multiformats Working Group.

A Multihash value starts with a binary header, which identifies the specific cryptographic hash algorithm and parameters used to generate the digest, followed by the cryptographic digest value. The normative Multihash header values defined by this specification, and their associated output sizes and associated specifications, are provided below:

Multihash Identifier Multihash Header Description
`sha2-256` `0x12` SHA-2 with 256 bits (32 bytes) of output, as defined by [[RFC6234]].
`sha2-384` `0x20` SHA-2 with 384 bits (48 bytes) of output, as defined by [[RFC6234]].
`sha3-256` `0x16` SHA-3 with 256 bits (32 bytes) of output, as defined by [[SHA3]].
`sha3-384` `0x15` SHA-3 with 384 bits (48 bytes) of output, as defined by [[SHA3]].

Other Multihash encoding values MAY be used, but interoperability is not guaranteed between implementations.

To encode to a Multihash value, an implementation MUST prepend the associated Multihash header value to the cryptographic hash value.

To decode a Multihash value, an implementation MUST remove the prepended Multihash header value, which identifies the type of cryptographic hashing algorithm as well as its output length, leaving the raw cryptographic hash value which MUST match the output length associated with the Multihash header.

Contexts and Vocabularies

This section lists cryptographic hash values that might change during the Candidate Recommendation phase based on implementer feedback that requires the referenced files to be modified.

Implementations that perform JSON-LD processing MUST treat the following JSON-LD context URLs as already resolved, where the resolved document matches the corresponding hash values below:

URL and Media Type Content
https://w3id.org/security/data-integrity/v2
application/ld+json
sha256: v/POI0jhSjPansxhJAP1fwepCBZ2HK77fRZfCCyBDs0=

sha3-512: Sg1PLFxKyEYQns9Zr0BoYXtFeDNfrHUDNMkyq4QEWvwGIaX1v5xovnCG+dfceZEzr7BhBjm396noZF1HEeCM8g==
https://w3id.org/security/multikey/v1
application/ld+json
sha256: uiwYLeLZL35HGEvMqPzwvq7m05hsUnv2ZMGVu8fFhZc=

sha3-512: En0TOOp/cC10XtW/aQDtqKrEQZ2lRjGB/KAsJ+BQhRBufT7s6eoOFWvP9cP5nurTl3hcRTvFeffdVJapkeELXw==
https://w3id.org/security/jwk/v1
application/ld+json
sha256: 9h/GLRVuGCl0rn/ye6lzf219aN7Sgzq9yBFqUoOI54k=

sha3-512: VDH85TsaX6kH2nwmII0WXKzAi2MRNsJd+rJfYL5cw0b12sAVPKDsVvRNJo0MMGd1RhV5W6Ii6D9GM7PCFeq97A==

The security vocabulary terms that the JSON-LD contexts listed above resolve to are in the https://w3id.org/security# namespace. That is, all security terms in this vocabulary are of the form `https://w3id.org/security#TERM`, where `TERM` is the name of a term.

Implementations that perform RDF processing MUST treat the following JSON-LD vocabulary URL as already resolved, where the resolved document matches the corresponding hash values below.

When dereferencing the https://w3id.org/security# URL, the data returned depends on HTTP content negotiation. These are as follows:

Media Type Description and Cryptographic Hashes
application/ld+json The vocabulary in JSON-LD format [[?JSON-LD11]].

sha256: LEaoTyf796eTaSlYWjfPe3Yb+poCW9TjWYTbFDmC0tc=

sha3-512: f4DhJ3xhT8nT+GZ8UUZi4QC+HT//wXE2fRTgUP4UNwe4kvel2PFfd6jcofHBm9BjwEiGzVFGv4K+fFTKXRD2NA==
text/turtle The vocabulary in Turtle format [[?TURTLE]].

sha256: McnhLyt7+/A/0iLb3CUXD0itNw+7bwwjtzOww/zwoyI=

sha3-512: jZtZsqgPPPo+jphAcN8/St4VdRLLAmN3nEQhzs0twEMTmCY45euQ01Z4Zo7VlJMYNTf0KC6BMpogpSTAi/1J7Q==
text/html The vocabulary in HTML+RDFa Format [[?HTML-RDFA]].

sha256: eUHP1xiSC157iTPDydZmxg/hvmX3g/nnCn+FO25d4dc=

sha3-512: z53j8ryjVeX16Z/dby//ujhw37degwi09+LAZCTUB8WJZjjzW1AydhdEWmgHM0P5KUcPMmSe7edMlGr7G9rmcA==

It is possible to confirm the digests listed above by running the following command from a modern Unix command interface line: `curl -sL -H "Accept: <MEDIA_TYPE>" <DOCUMENT_URL> | openssl dgst -<DIGEST_ALGORITHM> -binary | openssl base64 -nopad -a`.

Authors of application-specific vocabularies and specifications SHOULD ensure that their JSON-LD context and vocabulary files are permanently cacheable using the approaches to caching described above or a functionally equivalent mechanism.

Implementations MAY load application-specific JSON-LD context files from the network during development, but SHOULD permanently cache JSON-LD context files used in conforming documents in production settings to increase their security and privacy characteristics. Caching goals MAY be achieved through approaches such as those described above or functionally equivalent mechanisms.

Some applications, such as digital wallets, that are capable of holding arbitrary verifiable credentials or other data-integrity-protected documents, from any issuer and using any contexts, might need to be able to load externally linked resources, such as JSON-LD context files, in production settings. This is expected to increase user choice, scalability, and decentralized upgrades in the ecosystem over time. Authors of such applications are advised to read the security and privacy sections of this document for further considerations.

For further information regarding processing of JSON-LD contexts and vocabularies, see Verifiable Credentials v2.0: Base Context and Verifiable Credentials v2.0: Vocabularies.

Context Injection

The `@context` property is used to ensure that implementations are using the same semantics when terms in this specification are processed. For example, this can be important when properties like `type` are processed and its value, such as `DataIntegrityProof`, are used.

If an `@context` property is not provided in a document that is being secured or verified, or the Data Integrity terms used in the document are not mapped by existing values in the `@context` property, implementations MUST inject or add an `@context` property with a value of `https://w3id.org/security/data-integrity/v2`.

Context injection is expected to be unnecessary sometimes, such as when the Verifiable Credential Data Model v2.0 context (`https://www.w3.org/ns/credentials/v2`) exists as a value in the `@context` property, as that context maps all of the necessary Data Integrity terms that were previously mapped by `https://w3id.org/security/data-integrity/v2`.

Datatypes

This section defines datatypes that are used by this specification.

The `cryptosuiteString` Datatype

This specification encodes cryptographic suite identifiers as enumerable strings, which is useful in processes that need to efficiently encode such strings, such as compression algorithms. In environments that support data types for string values, such as RDF [[?RDF-CONCEPTS]], cryptographic identifier content is indicated using a literal value whose datatype is set to `https://w3id.org/security#cryptosuiteString`.

The cryptosuiteString datatype is defined as follows:

The URL denoting this datatype
`https://w3id.org/security#cryptosuiteString`
The lexical space
The union of all cryptosuite strings, expressed using American Standard Code for Information Interchange [[ASCII]] strings, that are defined by the collection of all Data Integrity cryptosuite specifications.
The value space
The union of all cryptosuite types that are expressed using the `cryptosuite` property, as defined in Section .
The lexical-to-value mapping
Any element of the lexical space is mapped to the result of parsing it into an internal representation that uniquely identifies the cryptosuite type from all other possible cryptosuite types.
The canonical mapping
Any element of the value space is mapped to the corresponding string in the lexical space.

The `multibase` Datatype

Multibase-encoded strings are used to encode binary data into ASCII-only formats, which are useful in environments that cannot directly represent binary values. This specification makes use of this encoding. In environments that support data types for string values, such as RDF [[?RDF-CONCEPTS]], Multibase-encoded content is indicated using a literal value whose datatype is set to `https://w3id.org/security#multibase`.

The `multibase` datatype is defined as follows:

The URL denoting this datatype
`https://w3id.org/security#multibase`
The lexical space
Any string that starts with a Multibase character and the rest of the characters consist of allowable characters in the respective base-encoding alphabet.
The value space
The standard mathematical concept of all integer numbers.
The lexical-to-value mapping
Any element of the lexical space is mapped to the value space by base-decoding the value based on the base-decoding alphabet associated with the first Multibase character in the lexical string.
The canonical mapping
The canonical mapping consists of using the lexical-to-value mapping.

Algorithms

The algorithms defined below are generalized in that they require a specific transformation algorithm, hashing algorithm, proof serialization 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 algorithm that generates the verification hash will eventually be defined in this specification.

Base Encode

The following algorithm specifies how to encode an array of bytes, where each byte represents a base-256 value, to a different base representation that uses a particular base alphabet, such as base-64-url-no-pad or base-58-btc. The required inputs are the bytes, targetBase, and baseAlphabet. The output is a string that contains the base-encoded value. All mathematical operations MUST be performed using integer arithmetic. Alternatives to the algorithm provided below MAY be used as long as the outputs of the alternative algorithm remain the same.

  1. Initialize the following variables; zeroes to `0`, length to `0`, begin to `0`, and end to the length of bytes.
  2. Set begin and zeroes to the number of leading `0` byte values in bytes.
  3. Set baseValue to an empty byte array that is the size of the final base-expanded value. Calculate the final size of baseValue by dividing log(256) by log(targetBase) and then multiplying the length of bytes minus the leading zeroes. Add `1` to the value of size.
  4. Process each byte in bytes as byte starting at offset begin:
    1. Set the carry value to byte.
    2. Perform base-expansion by starting at the end of the baseValue array. Initialize an iterator i to `0`. Set basePosition to size minus `1`. Perform the following loop as long as carry does not equal `0` or i is less than length, and basePosition does not equal `-1`.
      1. Multiply the value in baseValue[basePosition] by `256` and add it to carry.
      2. Set the value at baseValue[basePosition] to the remainder after dividing carry by targetBase.
      3. Set the value of carry to carry divided by targetBase ensuring that integer division is used to perform the division.
      4. Decrement basePosition by `1` and increment i by `1`.
    3. Set length to i and increment begin by `1`.
  5. Set the baseEncodingPosition to size minus length. While the baseEncodingPosition does not equal size and the baseValue[baseEncodingPosition] does not equal `0`, increment baseEncodingPosition. This step skips the leading zeros in the base-encoded result.
  6. Initialize the baseEncoding by repeating the first entry in the baseAlphabet by the value of zeroes (the number of leading zeroes in bytes).
  7. Convert the rest of the baseValue to the base-encoding. While the baseEncodingPosition is less than size, increment the baseEncodingPosition: Set baseEncodedValue to baseValue[baseEncodingPosition]. Append baseAlphabet[baseEncodedValue] to baseEncoding.
  8. Return baseEncoding as the base-encoded value.
function baseEncode(bytes, targetBase, baseAlphabet) {
  let zeroes = 0;
  let length = 0;
  let begin = 0;
  let end = bytes.length;

  // count the number of leading bytes that are zero
  while(begin !== end && bytes[begin] === 0) {
    begin++;
    zeroes++;
  }

  // allocate enough space to store the target base value
  const baseExpansionFactor = Math.log(256) / Math.log(targetBase);
  let size = Math.floor((end - begin) * baseExpansionFactor + 1);
  let baseValue = new Uint8Array(size);

  // process the entire input byte array
  while(begin !== end) {
    let carry = bytes[begin];

    // for each byte in the array, perform base-expansion
    let i = 0;
    for(let basePosition = size - 1;
        (carry !== 0 || i < length) && (basePosition !== -1);
        basePosition--, i++) {
      carry += Math.floor(256 * baseValue[basePosition]);
      baseValue[basePosition] = Math.floor(carry % targetBase);
      carry = Math.floor(carry / targetBase);
    }

    length = i;
    begin++;
  }

  // skip leading zeroes in base-encoded result
  let baseEncodingPosition = size - length;
  while(baseEncodingPosition !== size &&
        baseValue[baseEncodingPosition] === 0) {
    baseEncodingPosition++;
  }

  // convert the base value to the base encoding
  let baseEncoding = baseAlphabet.charAt(0).repeat(zeroes)
  for(; baseEncodingPosition < size; ++baseEncodingPosition) {
    baseEncoding += baseAlphabet.charAt(baseValue[baseEncodingPosition])
  }

  return baseEncoding;
}
        

Base Decode

The following algorithm specifies how to decode an array of bytes, where each byte represents a base-encoded value, to a different base representation that uses a particular base alphabet, such as base-64-url-no-pad or base-58-btc. The required inputs are the sourceEncoding, sourceBase, and baseAlphabet. The output is an array of bytes that contains the base-decoded value. All mathematical operations MUST be performed using integer arithmetic. Alternatives to the algorithm provided below MAY be used as long as the outputs of the alternative algorithm remain the same.

  1. Initialize a baseMap mapping by associating each character in baseAlphabet to its integer position in the baseAlphabet string.
  2. Initialize the following variables; sourceOffset to `0`, zeroes to `0`, and decodedLength to `0`.
  3. Set zeroes and sourceOffset to the number of leading baseAlphabet[0] values in sourceEncoding.
  4. Set decodedBytes to an empty byte array that is the size of the final base-converted value. Calculate the size of decodedBytes by dividing log(sourceBase) by log(`256`) and then multiplying by the length of sourceEncoding minus the leading zeroes. Add 1 to the value of size.
  5. Process each character in sourceEncoding as character starting at offset sourceOffset:
    1. Set the carry value to the integer value in the baseMap that is associated with character.
    2. Perform base-decoding by starting at the end of the decodedBytes array. Initialize an iterator i to `0`. Set byteOffset to decodedSize minus `1`. Perform the following loop as long as, carry does not equal `0` or i is less than decodedLength, and byteOffset does not equal `-1`:
      1. Add the result of multiplying sourceBase by decodedBytes[byteOffset] to carry.
      2. Set decodedBytes[byteOffset] to the remainder of dividing carry by `256`.
      3. Set carry to carry divided by `256`, ensuring that integer division is used to perform the division.
      4. Decrement byteOffset by `1` and increment i by `1`.
    3. Set decodedLength to i and increment sourceOffset by `1`.
  6. Set the decodedOffset to decodedSize minus decodedLength. While the decodedOffset does not equal the decodedSize and decodedBytes[decodedOffset] equals `0`, increment decodedOffset by `1`. This step skips the leading zeros in the final base-decoded byte array.
  7. Set the size of the finalBytes array to zeroes plus, decodedSize minus decodedOffset. Initialize the first zeroes bytes in finalBytes to `0`.
  8. Starting at an offset equal to the number of zeroes in finalBytes plus `1`, copy all bytes in decodedBytes, up to decodedSize, starting at offset decodedOffset to finalBytes.
function baseDecode(sourceEncoding, sourceBase, baseAlphabet) {
  // build the base-alphabet to integer value map
  baseMap = {};
  for(let i = 0; i < baseAlphabet.length; i++) {
    baseMap[baseAlphabet[i]] = i;
  }

  // skip and count zero-byte values in the sourceEncoding
  let sourceOffset = 0;
  let zeroes = 0;
  let decodedLength = 0;
  while(sourceEncoding[sourceOffset] === baseAlphabet[0]) {
    zeroes++;
    sourceOffset++;
  }

  // allocate the decoded byte array
  const baseContractionFactor = Math.log(sourceBase) / Math.log(256);
  let decodedSize = Math.floor((
    (sourceEncoding.length - sourceOffset) * baseContractionFactor) + 1);
  let decodedBytes = new Uint8Array(decodedSize);

  // perform base-conversion on the source encoding
  while(sourceEncoding[sourceOffset]) {
    // process each base-encoded number
    let carry = baseMap[sourceEncoding[sourceOffset]];

    // convert the base-encoded number by performing base-expansion
    let i = 0
    for(let byteOffset = decodedSize - 1;
      (carry !== 0 || i < decodedLength) && (byteOffset !== -1);
      byteOffset--, i++) {
      carry += Math.floor(sourceBase * decodedBytes[byteOffset]);
      decodedBytes[byteOffset] = Math.floor(carry % 256);
      carry = Math.floor(carry / 256);
    }

    decodedLength = i;
    sourceOffset++;
  }

  // skip leading zeros in the decoded byte array
  let decodedOffset = decodedSize - decodedLength;
  while(decodedOffset !== decodedSize && decodedBytes[decodedOffset] === 0) {
    decodedOffset++;
  }

  // create the final byte array that has been base-decoded
  let finalBytes = new Uint8Array(zeroes + (decodedSize - decodedOffset));
  let j = zeroes;
  while(decodedOffset !== decodedSize) {
    finalBytes[j++] = decodedBytes[decodedOffset++];
  }

  return finalBytes;
}
        

Retrieve Verification Method

The following algorithm specifies how to safely retrieve a verification method, such as a cryptographic public key, by using a verification method identifier contained in a data integrity proof. Required inputs are a data integrity proof (proof) and a set of dereferencing options (options). A verification method is produced as output.

  1. Let vmIdentifier be set to proof.verificationMethod.
  2. Let vmPurpose be set to proof.proofPurpose.
  3. If vmIdentifier is not a valid URL, an error MUST be raised and SHOULD convey an error type of INVALID_VERIFICATION_METHOD_URL.
  4. Let controllerDocumentUrl be the result of parsing vmIdentifier according to the rules of the URL scheme and extracting the primary resource identifier (without the fragment identifier).
  5. Let vmFragment be the result of parsing vmIdentifier according to the rules of the URL scheme and extracting the secondary resource identifier (the fragment identifier).
  6. Let controllerDocument be the result of dereferencing controllerDocumentUrl, according to the rules of the URL scheme and using the supplied options.
  7. If controllerDocument.id does not match the controllerDocumentUrl, an error MUST be raised and SHOULD convey an error type of INVALID_CONTROLLER_DOCUMENT_ID.
  8. If controllerDocument is not a valid controller document, an error MUST be raised and SHOULD convey an error type of INVALID_CONTROLLER_DOCUMENT.
  9. Let verificationMethod be the result of dereferencing the vmFragment from the controllerDocument according to the rules of the media type of the controllerDocument.
  10. If verificationMethod is not a valid verification method, an error MUST be raised and SHOULD convey an error type of INVALID_VERIFICATION_METHOD.
  11. If verificationMethod is not associated with the array of vmPurposes in the controllerDocument, either by reference (URL) or by value (object), an error MUST be raised and SHOULD convey an error type of INVALID_PROOF_PURPOSE_FOR_VERIFICATION_METHOD.
  12. Return verificationMethod as the verification method.

The following example provides a minimum conformant controller document containing a minimum conformant verification method as required by the algorithm in this section:

{
  "id": "https://controller.example/123",
  "verificationMethod": [{
    "id": "https://controller.example/123#key-456",
    "type": "ExampleVerificationMethodType",
    "controller": "https://controller.example/123",
    // public cryptographic material goes here
  }],
  "authentication": ["#key-456"]
}
        

Processing Errors

The algorithms described in this specification throw specific types of errors. Implementers might find it useful to convey these errors to other libraries or software systems. This section provides specific URLs, descriptions, and error codes for the errors, such that an ecosystem implementing technologies described by this specification might interoperate more effectively when errors occur.

When exposing these errors through an HTTP interface, implementers SHOULD use [[RFC9457]] to encode the error data structure. If [[RFC9457]] is used:

INVALID_VERIFICATION_METHOD_URL (-21)
The `verificationMethod` value in a proof was malformed. See Section .
INVALID_CONTROLLER_DOCUMENT_ID (-22)
The `id` value in a controller document was malformed. See Section .
INVALID_CONTROLLER_DOCUMENT (-23)
The controller document was malformed. See Section .
INVALID_VERIFICATION_METHOD (-24)
The verification method in a controller document was malformed. See Section .

Security Considerations

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

Write Security Considerations section

Privacy Considerations

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

Write Privacy Considerations section

Accessibility Considerations

The following section describes accessibility considerations that developers implementing this specification are urged to consider in order to ensure that their software is usable by people with different cognitive, motor, and visual needs. As a general rule, this specification is used by system software and does not directly expose individuals to information subject to accessibility considerations. However, there are instances where individuals might be indirectly exposed to information expressed by this specification and thus the guidance below is provided for those situations.

Write Accessibility Considerations section

Presenting Time Values

This specification enables the expression of dates and times related to the validity period of cryptographic proofs. This information might be indirectly exposed to an individual if a proof is processed and is detected to be outside an allowable time range. When exposing these dates and times to an individual, implementers are urged to take into account cultural normas and locales when representing dates and times in display software. In addition to these considerations, presenting time values in a way that eases the cognitive burden on the individual receiving the information is a suggested best practice.

For example, when conveying the expiration date for a particular set of digitally signed information, implementers are urged to present the time of expiration using language that is easier to understand rather than language that optimizes for accuracy. Presenting the expiration time as "This ticket expired three days ago." is preferred over a phrase such as "This ticket expired on July 25th 2023 at 3:43 PM." The former provides a relative time that is easier to comprehend than the latter time, which requires the individual to do the calculation in their head and presumes that they are capable of doing such a calculation.

Revision History

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

Acknowledgements

The specification authors would like to thank the base-x software library contributors and the Bitcoin Core developers who wrote the original code, shared under an MIT License, found in Section and Section .