# Verifiable Credentials

The foundation of Ontology's trust mechanism is based on a **verifiable credential system**.

Entities issue credentials and sell them to their customers, and this gives rise to a verification scenario. The closed loop of issuing requests, creation, and consumption of credentials is what makes up the trust mechanism. All entities can make and verify claims.

![Credential Workflow](https://1077617372-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LvPXC4l2V4Z8gRDNIoZ%2F-LvskKw8s9Pwh0-imBPd%2F-LvskNrkwyRj08alaH6S%2Fclaim-workflow.jpg?generation=1576131471711907\&alt=media)

Here are the parties that are involved in the process.

* **Credential owner -** has an `ONT ID`. This entity acquires a verifiable credential issued by another entity that is referred to as the `credential issuer`. This entity is able to manipulate credentials, with [**anonymous credential**](https://github.com/ont-project/documentation/blob/master/prod-doc/en/ontid/framework/credential-store/anonymous-credential.md) technology, and provide the credentials to the `credential consumer`. Thus, they play the role of a **trust seller.**
* **Credential issuer -**  has an `ONT ID`. This entity issues credentials to endorse a target entity for certain qualifications or credentials. The category of **credential Issuer** includes **trust anchors,** i.e. the partners or **entities** that provide **authentication services** in the Ontology ecosystem. Trust anchors could be **government agencies**, **universities**, **banks**, third-party **authentication services**, **bio-metric technology companies**, etc. Credential issuers provide multi-dimensional authentication for entities that are part of the trust network. The authentication process and result are recorded on the Ontology blockchain with data privacy protection. Credential issuers provide a **standardized and credible** authentication method for **credential consumers to verify** the credentials. Credential issuers **play the role of a** trust endorser.
* **Credential consumers -**  accept the user's verifiable credentials and initiate the credential verification process for the respective credentials. This includes many different scenarios, e.g., the employers who need to verify the interviewer's identity information/degree/industry skills. They the play the role of **trust buyer.**

## Verifiable Credential Protocol

![Credential Verification Process](https://1077617372-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LvPXC4l2V4Z8gRDNIoZ%2F-MFE793-WeDV9QHJVl1t%2F-MFE7OmE2UZGvCjacCdf%2Fclaim%20process.png?alt=media\&token=dadeb459-1c1c-40e4-b059-5ed52d52301b)

It is clear from the workflow illustrated above that the process involves three major actions:

1. Credential **request**
2. Credential **issue**
3. Credential **verification**

The **issuing** process involves two parties, the credential issuer and the entity that owns the **ONT ID.**

A **verifiable credential** includes the contents of the credential (that would vary depending upon the system), the digital signatures, and blockchain attestation records. Some of the records are:

* **Credential ID:** Unique identifier for credentials
* **Credential content:** Specific credentials or information, for instance a degree certificate
* **Credential metadata-**
  * **Created time:** Timestamp for when the credential was created
  * **Issuer:** **ONT ID** of the issuer
  * **Recipient:** **ONT ID** of the recipient party
  * **Expiration time:** **UNIX** timestamp for the credential automatically expires
  * **Revocation mechanism:** Use the **revocation list** or record the revocation information directly in the **attestation contract**
* **Blockchain proof**
* **Signature-**
  * Public key of the **issuer**
  * Signature **value**

{% hint style="info" %}
A verifiable credential template for an employee's salary certificate is available [**here**](https://github.com/ontio/ontology-DID/blob/master/claimtemplate/en/employment_certification_claimtemplate.md).
{% endhint %}

{% hint style="warning" %}
For centralized **ONT ID** systems, the first step in the workflow might differ in terms of the request that is sent to the credential issuer, since the owners will have **delegated** another body with access to their **ONT ID** and credentials. The request may not necessarily be sent by the owner themselves. The delegated body may also initiate and authorize credentials.
{% endhint %}

### Issuance process

The issuance process involves four main steps:

1. The **ONT ID** owner initiates the process by sending a request to the credential issuer.&#x20;
2. The **credential issuer** generates a verifiable credential and transmits it to the **recipient** using a secure method. The credential is **encrypted** using the recipient's **public key**.
3. The **owner** (or the delegate) signs the credential and sends it back to the **credential issuer**.
4. The **credential issuer** finally completes the signing process and sets the status of the credential to **attested***.* Next, the credential is transmitted to both the **Ontology** **blockchain** and the **owner** (or the delegate).

This whole process basically covers **Steps 1\~3** in the **credential workflow** illustrated above.

### Credential verification

There are **three** major actions involved in verifying a credential and they correspond to the **steps 4 \~ 5** in the workflow illustrated above.

* **Verifying** whether the credential is in the blockchain
* Verifying the **signature** and whether it has **expired**
* Checking whether the credential has been **revoked**

#### Blockchain record verification

It is necessary to verify whether the record of the verifiable credential is present on the blockchain. In case the node is not fully synchronized with the Ontology blockchain, merkle proof can be used to verify the verifiable credential transaction.

**Merkle proof** consists of an array, and each element contains two data items, **direction** and **hash**.

* **Direction:** Represents branch of the merkle tree the particular array element is in. There are two possible values.
* **Hash:** Represents hash value of the element data.

The algorithm using which the merkle proof is verified is as follows:

1. Check if **transaction** is included in **block** indexed by `proof.BlockHeight`. If not, return `false`.
2. Execute `p <- GetBlockHash(proof.BlockHeight)`.
3. For each **element** in `proof.Nodes`, update `p` as
   * **if** `e.Direction == "Left"`, `p <- H(e.TargetHash, p)`;
   * **else**, `p <- H(p, e.TargetHash)`.
4. Return `true` if `p` equals to the `proof.MerkleRoot`. Otherwise, return `false`.

   In addition, it is also necessary to verify the status of the credential attestation. This can be carried out by calling the inquiry interface `GetStatus()` of the attestation contract with the address `proof.ContractAddr`. If the status is `not attested`, an error would be returned.

#### Signature verification and Expiration time

When verifying the signature, the **public key ID** needs to be used to fetch the public key **value** and its current **status**. The verification algorithm is then called to carry out the verification process.

The format of the pubic key ID is `<ONTID>#keys-<number>`

The public key ID is used to call the ONT ID smart contract method that queries the status of the public key. `GetPublicKeyStatus(byte[] ontId, byte[] pkId)`

The response contains the following:

* **publicKey**: Public key value (hex)
* **status**: Two possible values: `InUse`, `Revoked`

Three possible results of signature verification:

* Signature is **invalid**
* Signature is **valid**
* Signature is **valid** and the public key is `revoked`

Next, the expiration time can be verified by checking whether the **timeout** period has expired.

#### Revoking verification

Currently there are two revocation modes available- **revocation list** and **revocation inquiry** interface.

Here's an example of the revocation list credential **request**. It contains the `URL` of the list.

```yaml
"clm-rev": {
    "type": "RevocationList",
    "url": "https://example.com/rev/1234"
}
```

Using the revocation inquiry interface as an example, if the revocation information is placed in the **attestation contract**, when calling the inquiry interface `GetStatus` of attest contract, revocation verification will return `success` if and only if the returned status field is `attested`. It will return `fail` if the status field is `attest has been revoked`.

```javascript
"clm-rev": {
       "type": "AttestContract",
       "addr": "8055b362904715fd84536e754868f4c8d27ca3f6"
}
```

The revocation list mainly includes the **unique identifier** and the **revocation time** of the revoked verifiable credential.

## Format of a verifiable credential

We will use an extension of the [JSON Web Token](https://tools.ietf.org/html/rfc7519) format to build the structure of the **credential** which is transferred between the **issuer** and the **recipient**.

The fundamental structure of the token consists of three parts:

* **Header**
* **Payload**
* **Signature**

{% hint style="info" %}
The standard **JWT** attributes are used to a great extent while in certain special cases **custom** attributes are defined.
{% endhint %}

The standard **JWT** format is augmented by appending the blockchain proof at the end, a typical verifiable credential has the following layout: `header.payload.signature.blockchain_proof`

{% hint style="info" %}
The `blockchain_proof` is not required in some cases, and is thus optional.
{% endhint %}

#### Header

The `header` defines the format, the signature scheme, and the ID of the public key used to verify the signature on the credential.

```yaml
{
    "alg": "ES256",
    "typ": "JWT-X",
    "kid": "did:ont:TRAtosUZHNSiLhzBdHacyxMX4Bg3cjWy3r#keys-1"
}
```

| Attribute | Description                                                                                                                                                                                  |
| --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **alg**   | Specifies the signature scheme to use. A list of supported values can be found [here](https://github.com/ontio/ontology-DID/blob/master/docs/en/claim_spec.md##_Supported_signature_schemes) |
| **typ**   | <p>"JWT": blockchain proof is not contained in the credential</p><p>"JWT-X" : blockchain proof is a part of the credential</p>                                                               |

The credential ID, credential content and the metadata are packaged into a `JSON` object which then acts as the payload. It will use some of the registered credential names specified in the `JWT` specification, such as `jti`, `iss`, `sub`, `iat`, `exp`.

```yaml
{
    "ver": "0.7.0",
    "iss": "did:ont:TRAtosUZHNSiLhzBdHacyxMX4Bg3cjWy3r",
    "sub": "did:ont:SI59Js0zpNSiPOzBdB5cyxu80BO3cjGT70",
    "iat": 1525465044,
    "exp": 1530735444,
    "jti": "4d9546fdf2eb94a364208fa65a9996b03ba0ca4ab2f56d106dac92e891b6f7fc",
    "@context": "https://example.com/template/v1",
    "clm": {
        "Name": "Bob Dylan",
        "Age": "22"
    },
    "clm-rev": { 
        "typ": "AttestContract",
        "addr": "8055b362904715fd84536e754868f4c8d27ca3f6"
    }
}
```

| Attribute    | Description                                                                                                    |
| ------------ | -------------------------------------------------------------------------------------------------------------- |
| **ver**      | Specifies the version of the credential specification being followed                                           |
| **iss**      | ONT ID of the issuer                                                                                           |
| **sub**      | ONT ID of the recipient                                                                                        |
| **iat**      | UNIX timestamp when the credential was created                                                                 |
| **exp**      | UNIX timestamp of when the credential expires automatically                                                    |
| **jti**      | Unique identifier of the verifiable credential                                                                 |
| **@context** | URI of the credential content definition document that defines each field and the respective values explicitly |
| **clm**      | Object that contains the credential content                                                                    |
| **clm-rev**  | Object that defines the revocation mechanism the credential uses                                               |

{% hint style="info" %}
A list of the supported revocation mechanisms has been listed [**here**](https://github.com/ontio/ontology-DID/blob/master/docs/en/claim_spec.md#C-Revocation).
{% endhint %}

Next, to issue a credential, a JSON object needs to be constructed that would contain the credential ID, the content, and the metadata. The JSON object can then be **serialized** using the standard serialization method. One of the issuer's private keys is then used to **sign** the binary data of the payload and the header.

After serialization, the **payload** would look something like-

```yaml
{
   "ver": "0.7.0",
   "iss": "did:ont:TRAtosUZHNSiLhzBdHacyxMX4Bg3cjWy3r",
   "sub": "did:ont:SI59Js0zpNSiPOzBdB5cyxu80BO3cjGT70",
   "iat": 1525465044,
   "exp": 1530735444,
   "jti": "4d9546fdf2eb94a364208fa65a9996b03ba0ca4ab2f56d106dac92e891b6f7fc",
   "@context": "https://example.com/template/v1",
   "clm": {
      "Name": "Bob Dylan",
      "Age": "22"
   },
   "clm-rev": {
      "Type": "Contract",
      "Addr": "8055b362904715fd84536e754868f4c8d27ca3f6"
   }
}
```

#### Signature

After the header and payload of the request are constructed the signature is computed according to the **JWS standard**. Full description of the standard can be found in the [RF 7515 Section 5.1](https://tools.ietf.org/html/rfc7515#section-5.1) of the IETF documentation.

The process is as follows:

1. Calculate the signing input as serialization of the header and payload according to **JWS** specification.

```
sig := sign(Base64URL(header) || . || Base64URL(payload))
```

1. Compute the **JWS** signature using the specified method for the particular **signature scheme** being used for the signing input.
2. Encode the signature.

```
signature := Base64URL(sig)
```

#### Blockchain Proof

The general format of a proof object is as follows:

```yaml
{
    "Type": "MerkleProof",
    "TxnHash": "c89e76ee58ae6ad99cfab829d3bf5bd7e5b9af3e5b38713c9d76ef2dcba2c8e0",
    "ContractAddr": "8055b362904715fd84536e754868f4c8d27ca3f6",
    "BlockHeight": 10,
    "MerkleRoot": "bfc2ac895685fbb01e22c61462f15f2a6e3544835731a43ae0cba82255a9f904",
    "Nodes": [{
        "Direction": "Right",
        "TargetHash": "2fa49b6440104c2de900699d31506845d244cc0c8c36a2fffb019ee7c0c6e2f6"
    }, {
        "Direction": "Left",
        "TargetHash": "fc4990f9758a310e054d166da842dab1ecd15ad9f8f0122ec71946f20ae964a4"
    }]
}
```

| Attribute        | Description                                                                        |
| ---------------- | ---------------------------------------------------------------------------------- |
| **Type**         | Fixed value 'Merkleproof'                                                          |
| **TxnHash**      | Hash of the transaction that attests the credential ID in the attestation contract |
| **ContractAddr** | Address of the attestation contract                                                |
| **BlockHeight**  | Height of the block that contains the attestation contract                         |
| **MerkleRoot**   | Root of the merkle tree when the tree size equals the **BlockHeight**              |
| **Nodes**        | Inclusion proof of block in the merkle tree                                        |

The **MerkleProof** is encoded in the following manner:

```
BASE64URL(MerkleProof)
```

Hence, a complete **verifiable credential** is created. The final structure is as follows:

```
BASE64URL(Header) || '.' || BASE64URL(Payload) || '.' || BASE64URL(Signature)  '.' || BASE64URL(MerkleProof)
```

### Attestation Contract

The **attestation contract** of a verifiable credential provides **attestation service** and **record availability** information, that is, whether or not it has been revoked.

The available methods are described below:

* **Commit Attestation**

```
bool Commit(byte[] claimId, byte[] committerOntId, byte[] ownerOntId);
```

In the attestation contract, `claimID` serves as the unique identifier for a credential. It is the first parameter; The `committerOntId` is the **ONT ID** of the **attester**. The `ownerOntId` is the **ONT ID** of the owner.

This method will return `true` if and only if the credential is **not attested**, and the method has been called by the **committer**; Otherwise, it will return `false`.

After the attestation is done, the status of the credential will be updated to **attested.**

* **Revoke credential**

```
bool Revoke(byte[] claimId, byte[] revokerOntId);
```

This method will return `true` if and only if the credential is **attested**, and the `revokerOntId` is the same as the **attester's** `ONT ID`; Otherwise, it will return `false`.

* **Attestation Inquiry method**

```
byte[] GetStatus(byte[] claimId);
```

This method returns the status of the credential. The response contains **two parts** of information:

* Status: `Not attested` , `Attested`, `Attest has been revoked`;
* **ONT ID** of the **attester**.

## Signature schemes

Currently supported signature schemes are:

| Scheme      | Encryption Technology |
| ----------- | --------------------- |
| **ES224**   | ECDSA with SHA224     |
| **ES256**   | ECDSA with SHA256     |
| **ES384**   | ECDSA with SHA384     |
| **ES512**   | ECDSA with SHA512     |
| **ES3-224** | ECDSA with SHA3 224   |
| **ES3-256** | ECDSA with SHA3 256   |
| **ES3-384** | ECDSA with SHA3 384   |
| **ES3-512** | ECDSA with SHA3 512   |
| **ER160**   | ECDSA with RIPEMD160  |
| **SM**      | SM2 with SM3          |
| **EDS512**  | EDDSA with SHA256     |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ont.io/decentralized-identity-and-data/ontid/trust-mechanism.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
