This specification describes a mechanism for ensuring the authenticity and
integrity of Linked Data documents using mathematical proofs.
This is an experimental specification and is undergoing regular revisions. It
is not fit for production deployment.
Introduction
Cryptographic proofs enable functionality that is extremely useful to
implementors of distributed systems. For example, proofs can be used for
purposes such as:

Make statements that can be shared without loss of trust, because their
authorship can be verified by a third party, for example as part of Verifiable
Credentials [[VCDATAMODEL]] or social media posts.

Authenticate as an entity identified by a particular identifier, for example, as
the subject identified by a Decentralized Identifier (DID) [[DIDCORE]].

Delegate authorization for actions in a remote execution environment, via
mechanisms such as Authorization Capabilities [[ZCAP]].

Agree to contracts where the agreement can be verified by another party.

Additionally, many proofs that are based on cryptographic signatures provide the
benefit of integrity protection, making documents and data tamperevident.
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
linked data documents through the use of mathematical proofs without sacrificing
Linked Data features such as extensibility and
composability.
Design Goals and Rationale
The Linked Data Proofs specification achieves the following design goals:
 Simple for Developers

The proof format is designed to be easy to use for developers that don't
have significant cryptography training. For example, cryptographic suite
identifiers are used instead of specific cryptographic parameters to ensure
that it is difficult to accidentally produce a weak digital proof.
 Agile

Since digital proof mechanisms might be compromised without warning due to
technological advancements, it is important that proof types can be
easily and quickly replaced. This specification provides algorithm agility
while still keeping the digital proof format easy for developers to understand.
 Extensible

Creating and deploying new proof types is a fairly trivial undertaking
to ensure that the proof format increases the rate of innovation in the
digital proof space.
 Graph Syntax Agnostic

Cryptographic proofs over graph data structures is a difficult
problem, since graphs can be serialized in many different but equivalent ways.
For advanced use cases, these proof mechanisms can be used across a variety of
RDFbased graph serialization syntaxes such as JSONLD, NQuads, and TURTLE,
without the need to regenerate the proof.
Terminology
The following terms are used to describe concepts involved in the
generation and verification of Linked Data digital proofs.
 linked data document

A document comprised of Linked Data.
 linked data proof

A set of attributes that represent a Linked Data digital proof and
the parameters required to verify it.
 linked data signature

A type of Linked Data Proof that involves cryptographic signatures 
see the Linked Data Signatures specification [[LDSIGNATURES]] for examples of
signature algorithms.
 signed linked data document

A linked data document that has been digitally signed.
 public key

A cryptographic key that can be used to verify digital proofs created
with a corresponding private key.
 private key

A cryptographic key that can be used to generate digital proofs.
 proof type

A specified set of cryptographic primitives bundled together into a
cryptographic suite for the purposes of safety and convenience, by
cryptographers for developers. A proof type typically consists of a
canonicalization algorithm, a message digest algorithm, and a
specific corresponding proof algorithm (see section ).
 proof options

A set of options that is included in the proof data. These options might
include controller, challenge, domain, or other data
that is specific to the proof format.
 proof purpose

The specific intent for the proof, the reason why an entity created it. Acts as
a safeguard to prevent the proof from being misused for a purpose other than the
one it was intended for.
 verification method

A set of parameters required to independently verify the proof, such as an
identifier for a public/private key pair that would be used in the proof.
 controller

A link to a machinereadable object, such as a DID Document [[DIDCORE]], that
contains authorization relations that explicitly permit the use of certain
verification methods for specific purposes. For example, a controller object
could contain statements that restrict a public key to being used only
for signing Verifiable Credentials [[VCDATAMODEL]] and no other kinds of
documents.
 challenge

A random or pseudorandom value used by some authentication protocols to
mitigate replay attacks.
 domain

A string value that specifies the operational domain of a digital proof.
This could be an Internet domain name like
example.com
, an
adhoc value such as mycorplevel3access
, or a very
specific transaction value like 8zF6T$mqP
. A signer could
include a domain in its digital proof to restrict its use
to particular target, identified by the specified domain.
Linked Data Proof Overview
A linked data proof is comprised of information about the
proof, parameters required to verify it, and the proof value itself.
All of this information is provided using Linked Data vocabularies such as
[[SECURITYVOCABULARY]].
A linked data proof typically includes at least the
following attributes:
 type


Required. The specific proof type used. For example, an
Ed25519Signature2018
type indicates that the proof includes a
digital signature produced by an ed25519
cryptographic key.
 proofPurpose


Required. The specific intent for the proof, the reason why an entity
created it. Acts as a safeguard to prevent the proof from being misused for a
purpose other than the one it was intended for. For example, a proof can be used
for purposes of
authentication
, for asserting control of a
Verifiable Credential (assertionMethod
), and several others.
 verificationMethod


Required. A set of parameters required to independently verify the proof, such as an
identifier for a public/private key pair that would be used in the proof.
 created


Required. The string value of an [[ISO8601]] combined date and time
string generated by the Proof Algorithm.
 domain


Optional. A string value specifying the restricted domain of the proof.
 proof value


Required. One of any number of valid representations of proof
value generated by the Proof Algorithm.
Example:
jws
for detached JSON Web Signatures.
Since this specification is based on Linked Data, the terms type,
created, and domain above map to URLs. The vocabulary where these
terms are defined is the [[SECURITYVOCABULARY]].
A proof can be added to a Linked Data document like the following:
{
"@context": "https://w3id.org/identity/v1",
"title": "Hello World!"
}
by adding the parameters outlined in this section:
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://www.w3.org/2018/credentials/examples/v1"
],
"title": "Hello World!",
"proof": {
"type": "Ed25519Signature2018",
"proofPurpose": "assertionMethod",
"created": "20170923T20:21:34Z",
"verificationMethod": "did:example:123456#key1",
"challenge": "2bbgh3dgjg2302dd2b3gi423d42",
"domain": "example.org",
"jws": "eyJ0eXAiOiJK...gFWFOEjXk"
}
}
The proof example above uses the Ed25519Signature2018
proof type to produce a verifiable digital proof.
Create a separate section detailing an optional mechanism
for authenticating public key ownership via bidirectional links. How
to establish trust in key owner entities 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 `RsaSignature2018` 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 `LinkedDataProof` 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.
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 Linked Data Proofs; for example,
an algorithm could produce a merkle tree from a canonicalized set of
NQuads and then sign the root hash. Disclosure would involve including
the merkle paths for each NQuad 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 NQuad to prevent rainbow
table or similar attacks.
Verification Attributes
Each proof contains a set of attributes that are used by verifiers to ensure
that the verification material, such as cryptographic keys, have been authorized
by their controllers specifically for a purpose that is appropriate to a given
situation. These attributes include: verificationMethod, which describes
the cryptographic keys or other methods used in the proof,
proofPurpose, which identifies the purpose for which the method is to be
used, and the link to a controller, which provides external confirmation
that a given method is indeed intended to be used for the stated purpose.
Verification Method
Add section explaining what a Verification Method parameter is, and its relationship with the Controller document.
Proof Purpose
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 similar goal but allows for finergrained restrictions.
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.
 contractAgreement

Indicates that a proof is used for proofs that an entity agrees to a contract.
Note: The Authorization Capabilities [[ZCAP]] specification defines additional
proof purposes for that use case, such as capabilityInvocation
and
capabilityDelegation
.
Controller
Add section explaining what a Controller document
is, and how it is used to ensure that a given method is authorized to be used
for a purpose.
Add examples of common Controller documents, such as
DID Documents published on a ledgerbased registry, or on a mutable medium in
combination with an integrity protection mechanism such as Hashlinks.
Multiple Proofs
The Linked Data Proofs specification supports the concept of multiple
proofs in a single document. There are two types of multiproof
approaches that are identified: Proof Sets (unordered) 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": [
"https://www.w3.org/2018/credentials/v1",
"https://www.w3.org/2018/credentials/examples/v1"
],
"title": "Hello World!",
"proof": [{
"type": "Ed25519Signature2018",
"proofPurpose": "assertionMethod",
"created": "20190823T20:21:34Z",
"verificationMethod": "did:example:123456#key1",
"challenge": "2bbgh3dgjg2302dd2b3gi423d42",
"domain": "example.org",
"jws": "eyJ0eXAiOiJK...gFWFOEjXk"
},
{
"type": "RsaSignature2018",
"proofPurpose": "assertionMethod",
"created": "20170923T20:21:34Z",
"verificationMethod": "https://example.com/i/pat/keys/5",
"challenge": "2bbgh3dgjg2302dd2b3gi423d42",
"domain": "example.org",
"jws": "eyJ0eXAiOiJK...gFWFOEjXk"
}]
}
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 countersigning 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": [
"https://www.w3.org/2018/credentials/v1",
"https://www.w3.org/2018/credentials/examples/v1"
],
"title": "Hello World!",
"proofChain": [{
"type": "Ed25519Signature2018",
"proofPurpose": "assertionMethod",
"created": "20190823T20:21:34Z",
"verificationMethod": "did:example:123456#key1",
"domain": "example.org",
"jws": "eyJ0eXAiOiJK...gFWFOEjXk"
},
{
"type": "RsaSignature2018",
"proofPurpose": "assertionMethod",
"created": "20170923T20:21:34Z",
"verificationMethod": "https://example.com/i/pat/keys/5",
"domain": "example.org",
"jws": "eyJ0eXAiOiJK...gFWFOEjXk"
}]
}
Proof Types
Linked Data Signatures
A linked data signature is a type of [[!LDPROOF]], and is comprised of
information about the signature, parameters required to verify it, and the
signature value itself. All of this information is provided using Linked Data
vocabularies such as the [[!SECURITYVOCABULARY]].
A linked data signature typically includes at least the
following attributes:
 type (required)


A URI that identifies the digital signature suite that was used to create the
signature. For example:
Ed25519Signature2018
.
 created (required)


The string value of an [[!ISO8601]] combined date and time string generated
by the Signature Algorithm.
 domain (optional)


A string value specifying the restricted domain of the signature.
 nonce (optional, but strongly recommended)


A string value that is included in the digital signature and MUST only be
used once for a particular domain and window of time. This
value is used to mitigate replay attacks.
 signature value (required)


One of any number of valid representations of signature value
generated by the Signature Algorithm.
Example:
jws
for detached JSON Web Signatures.
Since this specification is based on Linked Data, the terms type
,
created
, domain
, nonce
, and
jws
above map to URLs. The vocabulary where these terms are defined
is the [[SECURITYVOCABULARY]].
A signature can be added to a Linked Data document like the following:
{
"@context": "https://www.w3.org/2018/credentials/examples/v1",
"title": "Hello World!"
}
by adding the parameters outlined in this section:
{
"@context": "https://www.w3.org/2018/credentials/examples/v1",
"title": "Hello World!",
"proof": {
"type": "Ed25519Signature2018",
"proofPurpose": "assertionMethod",
"created": "20190823T20:21:34Z",
"verificationMethod": "did:example:123456#key1",
"domain": "example.org",
"jws": "eyJ0eXAiOiJK...gFWFOEjXk"
}
}
The signature example above uses the Ed25519Signature2018
signature suite to produce a verifiable digital signature.
Create a separate section detailing an optional mechanism
for authenticating public key control via bidirectional links. How
to establish trust in key controller entities 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 `RsaSignature2018` 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 `LinkedDataSignature` that allows for easy filtering/discover of
signature nodes, but that type on its own doesn't specify any default
signature or hash algorithms, those must be given via other properties in the
nodes.
Add a note indicating that this specification should not
be construed to indicate that public key owners 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 illadvised due to privacy
considerations.
Add an explicit check on key type to prevent an
attacker from selecting an algorithm that may abuse how the key is
used/interpreted.
Add a note indicating that selective disclosure signature
mechanisms can be compatible with Linked Data Signatures; for example,
an algorithm could produce a merkle tree from a canonicalized set of
NQuads and then sign the root hash. Disclosure would involve including
the merkle paths for each NQuad 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 may also
be necessary to generate signature parameters such as a private key/seed
that can be used along with an algorithm to deterministically generate
nonces that are concatenated with each NQuad to prevent rainbow
table or similar attacks.
Other Proof Types
TODO: Add links and examples to proof types that
are not Linked Data Signatures, such as biometricsbased proofs and ZKP
proofs.
Advanced Terminology
These terms are relevant only to implementors of new cryptographic suites.
 canonicalization algorithm

An algorithm that takes an input document that has more than one possible
representation and always transforms it into a deterministic representation. For
example, alphabetically sorting a list of items is a type canonicalization. This
process is sometimes also called normalization.
 message digest algorithm

An algorithm that takes an input message and produces a cryptographic
output message that is often many orders of magnitude smaller than the
input message. These algorithms are often 1) very fast, 2)
nonreversible, 3) cause the output to change significantly when even one
bit of the input message changes, and 4) make it infeasible to find two
different inputs for the same output.
 proof algorithm

An algorithm that takes an input message and produces an output value where the
receiver of the message can mathematically verify that the message has not
been modified in transit and came from someone possessing a particular secret.
Creating New Proof Types
A Linked Data 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.
Ed25519Signature2018
) 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 details the cryptographic primitives that are available to
proof type developers.
At a minimum, a proof type is expected have the following attributes:
 id

A URL that identifies the cryptographic suite.
For example:
https://w3id.org/security#Ed25519Signature2018
.
 type

The value
ProofSuite
.
 canonicalizationAlgorithm

A URL that identifies the canonicalization algorithm to use on the
document. For example:
https://w3id.org/security#URDNA2015
.
 digestAlgorithm

A URL that identifies the message digest algorithm to use on the
canonicalized document. For example:
https://www.ietf.org/assignments/jwaparameters#SHA256
 proofAlgorithm

A URL that identifies the proof algorithm to use on the
data to be signed. For example:
https://w3id.org/security#ed25519
A complete example of a proof type is shown in the next example:
{
"id": "https://w3id.org/security/v1#Ed25519Signature2018",
"type": "Ed25519VerificationKey2018",
"canonicalizationAlgorithm": "https://w3id.org/security#URDNA2015",
"digestAlgorithm": "https://www.ietf.org/assignments/jwaparameters#SHA256",
"signatureAlgorithm": "https://w3id.org/security#ed25519"
}
Algorithms
The algorithms defined below are generalized in that they require a specific
canonicalization algorithm, message digest algorithm, and
proof algorithm to be used to achieve the algorithm's intended
outcome.
Proof Algorithm
The proof parameters should be included as headers
and values in the data to be signed.
The following algorithm specifies how to create a digital proof that can
be later used to verify the authenticity and integrity of a
linked data document. A linked data document,
document, proof options, options,
and a private key, privateKey, are required inputs.
The proof options MUST contain an identifier for the
public/private key pair, and an [[!ISO8601]] combined date and
time string, created, containing the current date and time,
accurate to at least one second, in Universal Time Code format. A domain might also be specified in the options. A
signed linked data document is produced as output. Whenever this
algorithm encodes strings, it MUST use UTF8 encoding.

Create a copy of document, hereafter referred to as output.

Generate a canonicalized document by canonicalizing
document according to a canonicalization algorithm
(e.g. the URDNA2015 [[!RDFDATASETNORMALIZATION]] algorithm).

Create a value tbs that represents the data to be signed, and
set it to the result of running the
Create Verify Hash Algorithm,
passing the information in options.

Digitally sign tbs using the privateKey and the
the digital proof algorithm (e.g. JSON Web Proof using
RSASSAPKCS1v1_5 algorithm). The resulting string is the
proof value.

Add a
proof
node to output containing
a linked data proof using the appropriate
type and proof value values as well as
all of the data in the proof options (e.g.
created, and if given, any additional proof
options such as domain).

Return output as the signed linked data document.
Proof Verification Algorithm
This algorithm is highly specific to digital signatures and needs to be
generalized to other proof mechanisms such as Equihash.
The following algorithm specifies how to check the authenticity and
integrity of a signed linked data document by verifying its
digital proof. This algorithm takes a
signed linked data document, signed document and
outputs a true
or false
value based on whether or
not the digital proof on signed document was verified. Whenever
this algorithm encodes strings, it MUST use UTF8 encoding.
Specify how the public key can be obtained, through
some outofband process and passed in or it can be retrieved by
derefencing its URL identifier, etc.

Get the public key by dereferencing its URL identifier in
the
proof
node of the default graph of
signed document. Confirm that the linked data document
that describes the public key specifies its owner and that its
owner's URL identifier can be dereferenced to reveal a bidirectional link back
to the key. Ensure that the key's owner is a trusted entity before proceeding
to the next step.

Let document be a copy of signed document.

Remove any
proof
nodes from the default graph in
document and save it as proof.

Generate a canonicalized document by canonicalizing
document according to the canonicalization algorithm
(e.g. the URDNA2015 [[!RDFDATASETNORMALIZATION]] algorithm).

Create a value tbv that represents the data to be verified, and
set it to the result of running the
Create Verify Hash Algorithm,
passing the information in proof.

Pass the proof value, tbv,
and the public key to the proof algorithm
(e.g. JSON Web Proof using RSASSAPKCS1v1_5 algorithm).
Return the resulting boolean value.
Create Verify Hash Algorithm
This algorithm is too specific to digital signatures and needs to be
generalized for algorithms such as Equihash.
The following algorithm specifies how to create the data that is used
to generate or verify a digital proof. It takes a canonicalized
linked data document, canonicalized document,
canonicalization algorithm, a message digest algorithm, and
proof options, input options (by reference).
The proof options MUST contain an identifier for the
public/private key pair, and an [[!ISO8601]] combined date and
time string, created, containing the current date and time,
accurate to at least one second, in Universal Time Code format. A domain
might also be specified in the options.
Its output is a data that can be used to generate or verify a
digital proof (it is usually further hashed as part of the
verification or signing process).

Let options be a copy of input options.

If the proof value parameter, such as
jws
,
exists in options, remove the entry.

If created does not exist in options, add an
entry with a value that is an [[!ISO8601]] combined date and
time string containing the current date and time accurate to at least one
second, in Universal Time Code format. For example:
20171113T20:21:34Z
.

Generate output by:

Creating a canonicalized options document by canonicalizing
options according to the canonicalization algorithm
(e.g. the URDNA2015 [[!RDFDATASETNORMALIZATION]] algorithm).

Hash canonicalized options document using the
message digest algorithm (e.g. SHA256) and set output
to the result.

Hash canonicalized document using the message digest algorithm
(e.g. SHA256) and append it to output.

This last step needs further clarification. Signing
implementations usually automatically perform their own integrated
hashing of an input message, i.e. signing algorithms are a combination
of a raw signing mechanism and a hashing mechanism such as
RS256 (RSA + SHA256). Current implementations of RSAbased
Linked Data Proof suites therefore do not perform this last step
before passing the data to a signing algorithm as it will be performed
internally. The Ed25519Proof2018 algorithm also does not perform
this last step  and, in fact, uses SHA512 internally. In short,
this last step should better communicate that the 64 bytes produced
from concatenating the SHA256 of the canonicalized options with the
SHA256 of the canonicalized document are passed into the signing
algorithm with a presumption that the signing algorithm will include
hashing of its own.
Note: It is presumed that the 64byte output will be used
in a signing algorithm that includes its own hashing algorithm, such
as RS256 (RSA + SHA256) or EdDsa (Ed25519 which uses SHA512).

Return output.
Security Considerations
The following section describes security considerations that developers
implementing this specification should be aware of in order to create secure
software.
TODO: We need to add a complete list of security
considerations.