Trust Mechanism

Outline of the trust model

The foundation of Ontology's trust mechanism is based on a claim system.

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

Claim Workflow

Here are the parties that are involved in the process.

  • Claim owner - has an ONT ID. This entity acquires a verifiable claim issued by another entity that is referred to as the claim issuer. This entity is able to manipulate claims, with anonymous credential technology, and provide the credentials to the claim consumer. Thus, they play the role of a trust seller.

  • Claim issuer - has an ONT ID. This entity issues claims to endorse a target entity for certain qualifications or credentials. The category of claim 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. Claim 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. Claim issuers provide a standardized and credible authentication method for claim consumers to verify the claims. Claim issuers play the role of a trust endorser.

  • Claim consumers - accept the user's verifiable claims and initiate the claim verification process for the respective claims. 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 Claim Protocol

Claim Verification Process

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

  1. Claim request

  2. Claim issue

  3. Claim verification

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

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

  • Claim ID: Unique identifier for claims

  • Claim content: Specific credentials or information, for instance a degree certificate

  • Claim metadata-

    • Created time: Timestamp for when the claim was created

    • Issuer: ONT ID of the issuer

    • Recipient: ONT ID of the recipient party

    • Expiration time: UNIX timestamp for the claim 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

A verifiable claim template for an employee's salary certificate is available here.

For centralized ONT ID systems, the first step in the workflow might differ in terms of the request that is sent to the claim 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 claims.

Issuance process

The issuance process involves four main steps:

  1. The ONT ID owner initiates the process by sending a request to the claim issuer.

  2. The claim issuer generates a verifiable claim and transmits it to the recipient using a secure method. The claim is encrypted using the recipient's public key.

  3. The owner (or the delegate) signs the claim and sends it back to the claim issuer.

  4. The claim issuer finally completes the signing process and sets the status of the claim to attested. Next, the claim is transmitted to both the Ontology blockchain and the owner (or the delegate).

This whole process basically covers Steps 1~3 in the claim workflow illustrated above.

Claim verification

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

  • Verifying whether the claim is in the blockchain

  • Verifying the signature and whether it has expired

  • Checking whether the claim has been revoked

Blockchain record verification

It is necessary to verify whether the record of the verifiable claim 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 claim 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 claim 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 claim request. It contains the URL of the list.

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

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

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

Format of a verifiable claim

We will use an extension of the JSON Web Token format to build the structure of the claim which is transferred between the issuer and the recipient.

The fundamental structure of the token consists of three parts:

  • Header

  • Payload

  • Signature

The standard JWT attributes are used to a great extent while in certain special cases custom attributes are defined.

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

The blockchain_proof is not required in some cases, and is thus optional.

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

{
"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‚Äč

typ

"JWT": blockchain proof is not contained in the claim

"JWT-X" : blockchain proof is a part of the claim

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

{
"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 claim specification being followed

iss

ONT ID of the issuer

sub

ONT ID of the recipient

iat

UNIX timestamp when the claim was created

exp

UNIX timestamp of when the claim expires automatically

jti

Unique identifier of the verifiable claim

@context

URI of the claim content definition document that defines each field and the respective values explicitly

clm

Object that contains the claim content

clm-rev

Object that defines the revocation mechanism the claim uses

A list of the supported revocation mechanisms has been listed here.

Next, to issue a claim, a JSON object needs to be constructed that would contain the claim 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-

{
"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 of the IETF documentation.

The process is as follows:

  1. Calculate the signing input as serialization of Header ans 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:

{
"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 claim 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 claim is created. The final structure is as follows:

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

Attestation Contract

The attestation contract of a verifiable claim 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 claim. 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 claim 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 claim will be updated to attested.

  • Revoke claim

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

This method will return true if and only if the claim 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 claim. 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