This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Protocol

Low level reference documentation of the AQUA Protocol

This section of documentation gets into specific details about the AQUA Protocol and is meant for those doing an implementation or contributing to the Protocol itself.

1 - Whitepaper

High level outline of Aqua Protocol (AQP) specification
Current version: Aqua Protocol v1.1 Specification
Author: Tim Bansemer, Publius Dirac
Date: 30.12.2021
Status: DRAFT / Experimental
Implementation: https://github.com/inblockio/micro-pkc

Introduction

The Aqua Protocol (AQP) is a data accountability and exchange protocol between hosts in peer-to-peer environments. The AQP is used to realize the goal of accounting for data origin and history . The description for the proof-of-concept implementation of the AQP can be found in this page .

Motivation

In today’s world, there are no widely adopted trustless processes of checking if data have been manipulated or corrupted, are attributed to the wrong author, or are attributed to the wrong time. Today’s processes are dependent on centralized trusted services which retain all power over governing the data.

There is a lack of transparency or ability to check if data have been altered by an unauthorized party. Additionally, consumers of data are incapable of verifying if centralized services have altered the data. This leads to a world of untrustworthy information in which we don’t know how to conclude what is true.

In a world where every piece of information is a grain in a sandstorm, it has become impossible to navigate reality. In contrast, in a world where every piece of information is a fixed star in the sky for a lifetime, we are able to relate and make sense of the information given. The Aqua Protocol (AQP) turns grains of information into fixed stars of information.

The AQP adds a peer-to-peer layer of accountability, making it impossible to change data unnoticed. AQP adds an essential line of defense against attacks on data integrity, plagiarism, or misattribution. AQP is used to govern trusted data, which can be quickly verified. This includes the verification of its integrity and history, the verification of its account (the entity who creates or manipulates the data), and the verification of its existence and timestamp.

The Aqua Protocol provides trustworthiness to data by
securing data ✅ integrity, 🔏 account and ⌚ time.

In order to account data, it is necessary to track and verify its history. The AQP provides a globally unique resource identification (URI) for each revision of the verified data. This identifier is collision-free, and is referred the same way across multiple interacting hosts.

Terminology

Wallet

A wallet is a software for protecting and managing private cryptographic keys (of private-public key pairs) which are used to govern digital assets. This is done by authorization of transactions via digital signatures or by initiating decryption processes to access data.

See Separation of Concerns .

Account

We are following Ethereum’s account definition:

In general, there are two types of accounts. Externally owned accounts, controlled by private keys. And contract accounts, controlled by their contract code – Ethereum Whitepaper

In general, we can’t prove if an account owner is a person or a machine. With advancements in AI, it will become increasingly difficult to prove that a human is a human. Attempts are being made to increase trustworthiness of accounts which fall short in questions of privacy and security as they make public claims. Traditional know your customer (KYC) combined with the AQP and Aqua Identity Protocol (AIP) identification processes can provide similar “proof of being human” which can be attested to an account. This allows us to outsource the problem of identification, where we only focus on unique accounts which are sufficient for data accounting independent of humans or machines. Identity claims issued via the AIP will help to provide the context required to meaningfully interact between accounts.

For more on this topic, please read the Aqua Identity Protocol .

Domain

A domain is a unique namespace attributed to an account. It allows us to manage services and files within that namespace creating a domain of data governance After granted permissions, additional accounts can be added to share control over a domain or singular assets. To enforce boundaries of a domain, additional software like the Guardian is required.

E.g. by setting up the a data vault with your account it becomes your domain of data governance.

Revision

A revision is the smallest portable entity within the AQP. Multiple revisions form a single portable hash chain which is serialized in JSON format. They have existed before in unsecured systems where multiple revisions form a file which can be displayed as a page. The AQP adds the cryptographic harness to secure it. With presenting a portable hash chain, it is possible to track all incremental changes stored in each revision to understand the history of a page and how it came to be. This allows us to have version control on digital assets being able to restore earlier states and to relate to them. This allows us to have historical evidence of digital assets.

Page

A page is a visible representation of a file containing multiple or a single revision attributed to a shared origin. A page view could also be used to create a new revision by a used service which interfaces with the file for manipulation. In AQP all revisions share a global URI hash to attribute them together called a genesis hash.

Transaction Security

Transaction security is an economic measure of the level of integrity assurance for a transaction. It is defined as the cost required to forge a transaction. The transaction security can be increased by cryptographic security and by strong replication of transactions. Public distributed ledger systems are highly suitable for providing very high level of transaction security at the cost of privacy and immutability (data can’t be changed or deleted). Today, public distributed ledgers such as Bitcoin and Ethereum provide the highest level of transaction security.

Data Asset

Data turns into a valuable asset if it is accounted for. In an accounted form it can be easily priced, exchanged or traded.

Data Vault

Software used to store and manage data with an account. The software must apply a secure architecture and measures for keeping data assets safe. This is achieved through encryption, strong authentication and restrictive access to keep data private by default.

See Design Principles / Separation of Account and Service

Witness

We define witnessing as the process of observing an event. A witness is judged by their capability to recollect and share an observed event. In other words, witnessing is the process of storing input data for later playback to provide data symmetry around an event.

Witness Network

The digital service in a distributed ledger or similar infrastructure which provides transaction security and data symmetry for shared data within the network. An example of a witness network would be Ethereum.

E.g. Ethereum can be used to store a digital fingerprint of a domain snapshot of a data vault. A domain snapshot is the Merklized state of all witnessed hash chains being present in the data vault. It is required to pay the witness network for its service. In the case of Ethereum, this is done using ‘Ether’. This in return allows the account owner to create an ‘undeniable’ proof that a specific revision and the previous revisions within a hash chain has existed.

Portable Hash Chain

A hash chain is a linked list where each node contains the cryptographic hash of the previous node content. A portable hash chain is a hash chain that can be moved from one host to another.

See Immutable Hyperlinks .

Specification

To identify a revision with a unique fingerprint, we hash its content using the SHA3-512 hashing function which always has a 128 characters long output. This value can be used as a checksum to verify data integrity. The checksum can then be entangled in a hash-chain to create an immutable track record. We then calculate multiple properties associated with the revision, in addition to its content checksum. In the next section, we differentiate between REQUIRED and OPTIONAL properties for each revision.

All hashes are based on SHA3-512 . This encryption standard is used to construct portable hash chains , which are serializing of data and its history in a form that can be verified, and independent of location. The portable hash chain can be fully or partially exchanged between hosts depending on the application of the data. From here on, we refer the term “portable hash chain” as “hash chain.”

In order to implement the AQP, we need to utilize a software that is capable of generating portable hash chains and facilitating actions described in the AQP. We call those nodes which facilitate the Aqua Protocol ‘Aqua Data Vaults’ which given their role should be implemented as a software with secure architecture and measures for keeping data assets safe. This is achieved through encryption, authentication and restrictive access to keep data private by default.

Revision Verification Structure

A revision is RECOMMENDED to be limited to 50 Megabytes to ensure that the verification can take place on all imaginable clients which might have slow network connectivity, low memory, low cpu performance. Once a revision is verified, the next one can be verified. Clients with more performance will be able to parallelize the verification. Larger files can be chunked to be placed in multiple revisions.

A verified data structure is identified by its URI verification_hash and grouped by its genesis_hash. The first revision created will create a verification_hash which has a special meaning and is referred to as the genesis_hash. All future revisions building upon that first revision will be attributed to the genesis_hash as a unique URI for grouping the revisions. This allows us to understand if two revisions are related without needing to verify the whole history of the hash chain.

Verification Hash

revision_verification_hash is the hash sum over the string formed by the following operation

revision_verification_hash = calculate_hash_sum(
    content_hash + metadata_hash +
    signature_hash + witness_hash
)

The content_hash and metadata_hash are REQUIRED. The signature_hash and witness_hash are OPTIONAL.

Content

A content hash is the check sum for all content data fields which simplifies hash construction and the ability to identify data corruption in this part of the verification structure. content_hash is the hash sum over the string formed by following operation:

contentObj = {
    "main": content,
    "extension_key_1": content_extension_1,
    "extension_key_2": content_extension_2,
    ...,
    "extension_key_n": content_extension_n,
}
sortedContenObj = sort_by_keys(contentObj)
content_hash = calculate_hash_sum(
    sortedContenObjValue_1,
    sortedContenObjValue_2,
    ...,
    sortedContenObjValue_n,
)

Description:

  • content: The string input of the visible page using UTF-8 encoding schema. REQUIRED.
  • content extensions: more data MAY be encapsulated in addition to the main content. These could be a file, a stateful link, or a signature. The content extensions are sorted alphabetically by their key names. OPTIONAL.
  • The sort_by_keys function sorts the content object elements by their keys alphabetically. The JSON input MAY be a canonical JSON, in which the keys order is already alphabetical, but we sort it always to ensure the order is correct.

To see an example of contentObj of a revision, see the example section,

Metadata

metadata_hash = calculate_hash_sum(
    domain_id + time_stamp + previous_verification_hash
)

Description:

  • metadata_hash: The check sum for all metadata data fields. It simplifies the hash construction and the ability to identify data corrupton in this part of the verification structure.
  • domain_id: 10 digits hexadecimal randomly generated to identify the host system that runs the AQP service.
  • time_stamp: time-stamp of the current revision (decimal numbers YYYYMMDDHHMMSS e.g. 20211128092608).
  • previous_verification_hash: previous_revision_verification_hash if present

Signature

A signature in AQP is a cryptographic signature generated by public-private key pair. The protocol should be abstract, where it will support ‘Method’ in later iterations. This will allow us to use different types of implementations such as: PGP signatures, Ethereum, or Bitcoin wallet ’s signatures.

In this specification, we use the AQP reference implementation’s signing method, which is via an Ethereum wallet.

signature_hash = calculate_hash_sum(
    signature + public_key
)

The signature is generated by a wallet signing the following message:

I sign the following page verification_hash:" +[0x<revision_verification_hash>]

The revision_verification_hash MUST NOT be signed twice by the same key, to avoid information leakage of the private key.

For example, a wallet with an address of 0xa2026582b94feb9124231fbf7b052c39218954c2 and a public key of 0x041518581af65749b3ddc69889df3e5d229bc8ad79279a07ddeb368ade5e1592368c5ff3b69143d7a1e7cf64f7d0774a6724e6eaf138d318d07ddc30f6081ca89a signs the following message:

I sign the following page verification_hash:" +[0x9dab72c7635043452958c4cc2902f48ef7c4ae437058280197c6a2736ab9635f799cbf190d9d07dd76589055a8ad64e61c6bebd1487994207d4cb7918b471f57]

which results in the following signature:

0x19b5697c4541509c1add3db9fc2f678b7b80325ebffd4d945ca00db5f8b3f98a142edbf9a7faa0a0c7ec4f10ae1b64cf2ea62ce3ee73ed2e37ce916d6bd016601c

Witness

Witnessing allows one to undeniably prove the existence of a dataset (represented as a portable hash chain). To complete the witnessing process, a Domain Snapshot is created. This is a collection of all revision hashes within one domain. A Merkle tree is used to unify all hashes of the latest revisions of all portable hash chains within a domain into a single hash value.

The witness_event_verification_hash is written to the Witness Network . The witness_event_verification_hash is then generated by using the domain_snapshot_genesis_hash and the merkle_root hash together. This allows the page snapshot itself to also be witnessed.

A single revision which has been witnessed, will not store the whole Merkle tree, but only its relevant path to the Merkle root. Performing a Merkle proof means that its revision is included in the Merkle tree.

witness_hash = calculate_hash_sum(
    domain_snapshot_genesis_hash + merkle_root +
    witness_network + witness_event_transaction_hash
)

Description:

  • witness_hash: the checksum for all signature data fields. It simplifies hash construction and identifies data corruption in this part of the verification structure.
  • domain_snapshot_genesis_hash: Refers to the URI of the page which stores the whole Merkle tree of the witness event.
  • merkle_root: the root hash of the Merkle tree. The presence of the Merkle tree allows for lazy verification to reduce required computational steps for verification by skipping the Merkle proof as both datasets can be entangled in the chain by a newer revision and therefore be immutable.
  • witness_network: specifies which witness network was used to store the witness_event. The following structure shows an AQP hash chain with 3 revisions which wrote the witness_event_verification_hash into the witness network.

Additional context:

  • relative-merkle-tree-proof: This provide the relative path with all required hashes to verify the Merkle tree root from the first node which the verification_hash of the revision as a starting point.
  • witness_event_verification_hash: It is calculated by taking the sha3-512 checksum of the domain_snapshot_genesis_hash and the merkle_root hash. This ensures that thedomain_snapshot itself will be witnessed.

Example

The following structure shows an AQP hash chain with 3 revisions:

1st Revision

This revision features all REQUIRED (content, metadata) and all OPTIONAL (signature, witness) AQP data fields.

{
  "verification_context": {
    "has_previous_signature": false,
    "has_previous_witness": false
  },
  "content": {
    "rev_id": 358,
    "content": {
      "main": "First revision text",
      "transclusion-hashes": ""
    },
    "content_hash": "ae188be061822074716b43925b3ffa90a03c530342be73c3440d8f022765ffebbb56c16552f13cd1ea61f876d2d892e0a73dcba5173fc47d371b4251d6c094da"
  },
  "metadata": {
    "domain_id": "acfa9f682e",
    "time_stamp": "20220116090401",
    "previous_verification_hash": "",
    "metadata_hash": "d1025fd8866d9367735d2f6617b3aa87401e08d726f311cdf834ea9540955bfc59b428676bce5d47d5fed381394ab2ed838c5eecfc9cb37313705374752c247d",
    "verification_hash": "9dab72c7635043452958c4cc2902f48ef7c4ae437058280197c6a2736ab9635f799cbf190d9d07dd76589055a8ad64e61c6bebd1487994207d4cb7918b471f57"
  },
  "signature": {
    "signature": "0x19b5697c4541509c1add3db9fc2f678b7b80325ebffd4d945ca00db5f8b3f98a142edbf9a7faa0a0c7ec4f10ae1b64cf2ea62ce3ee73ed2e37ce916d6bd016601c",
    "public_key": "0x041518581af65749b3ddc69889df3e5d229bc8ad79279a07ddeb368ade5e1592368c5ff3b69143d7a1e7cf64f7d0774a6724e6eaf138d318d07ddc30f6081ca89a",
    "wallet_address": "0xa2026582b94feb9124231fbf7b052c39218954c2",
    "signature_hash": "cc42f40c4452a25f9ea48a97b6dfba6f69dec347db5c1adf25475b0b4a5da36af3fe48bf9f7ea0dda6bbed9367dc9c82834dbf8cc7f6220fd190cdb729d3f4ec"
  },
  "witness": {
    "witness_event_id": "2",
    "domain_id": "acfa9f682e",
    "domain_snapshot_title": "Data Accounting:DomainSnapshot:b33afaf53ed3d245f0319d4997db2032de9d77791ae11f5125189815eef44f2fba9633bebe2e57bc5ea4b0424872ed02fa6aa9ad909f467726b536933bf715bf",
    "witness_hash": "9707780cebcf6ed02b40bd7e6956b35ffe142a2b5f8cee15c703a652fa389eb118ef101e2f463e95663aa4013a42d9f1ce4a83eed3528b02bf98626e7599bbd8",
    "domain_snapshot_genesis_hash": "b33afaf53ed3d245f0319d4997db2032de9d77791ae11f5125189815eef44f2fba9633bebe2e57bc5ea4b0424872ed02fa6aa9ad909f467726b536933bf715bf",
    "merkle_root": "14f26d7dc0be77afff9131c03cab39a2fa9e1270c6face3fdc35b9b4b4ac4550d048c356a4713568c42411c3e7fe3553ec7b993c9bd7da97cb976e843d7e4d29",
    "witness_event_verification_hash": "67e187411f1e514f232ae2858168da29b15ddfd07523e7a7618bfbf91c583f54fe8e850146120539a92a63ce6138f96599fb8a46ed492e428fe6fde9b9ea82ae",
    "witness_network": "goerli",
    "smart_contract_address": "0x45f59310ADD88E6d23ca58A0Fa7A55BEE6d2a611",
    "witness_event_transaction_hash": "0x5900103adc09a789fd3bd7c23dfeff1ffce41dfba0a52b525ecc032e9279eb1f",
    "sender_account_address": "0xa2026582b94feb9124231fbf7b052c39218954c2",
    "source": "default",
    "structured_merkle_proof": [
      {
        "witness_event_verification_hash": "67e187411f1e514f232ae2858168da29b15ddfd07523e7a7618bfbf91c583f54fe8e850146120539a92a63ce6138f96599fb8a46ed492e428fe6fde9b9ea82ae",
        "depth": "4",
        "left_leaf": "2554fb53531f4de26ff3ad1fb8c61feea6ea47c3f13c4abda385c46ef8541361f7eee42433050281714a3900115f04fe52b5a8d781a71c4c439c5de6b91cbe3c",
        "right_leaf": "9dab72c7635043452958c4cc2902f48ef7c4ae437058280197c6a2736ab9635f799cbf190d9d07dd76589055a8ad64e61c6bebd1487994207d4cb7918b471f57",
        "successor": "789e508ccb23fe053b628cebc19a2d32f34e6aa21e878e8611f7c14d891625c7b2e243b3c3105b98295333b9183e5ea272a055a84ab65ad927f7fd9c27aae48e"
      },
      {
        "witness_event_verification_hash": "67e187411f1e514f232ae2858168da29b15ddfd07523e7a7618bfbf91c583f54fe8e850146120539a92a63ce6138f96599fb8a46ed492e428fe6fde9b9ea82ae",
        "depth": "3",
        "left_leaf": "789e508ccb23fe053b628cebc19a2d32f34e6aa21e878e8611f7c14d891625c7b2e243b3c3105b98295333b9183e5ea272a055a84ab65ad927f7fd9c27aae48e",
        "right_leaf": "c16a966333cd22ff3497875a62202874221c1dae2e74b4351d058910f8d37160be480fce9aab4ec5e725beb695509f0fd65ae581568c6f1ae25eb4f1440b287f",
        "successor": "80d7549af24e9a6bdfc32cefe0536d6528d665cc8e65859ef4cff87270f3db8d9b95aaecc167e10c9b5be9ce3ab36d8d880c3a518e1c5eb899ca9d95af24e9db"
      },
      {
        "witness_event_verification_hash": "67e187411f1e514f232ae2858168da29b15ddfd07523e7a7618bfbf91c583f54fe8e850146120539a92a63ce6138f96599fb8a46ed492e428fe6fde9b9ea82ae",
        "depth": "2",
        "left_leaf": "80d7549af24e9a6bdfc32cefe0536d6528d665cc8e65859ef4cff87270f3db8d9b95aaecc167e10c9b5be9ce3ab36d8d880c3a518e1c5eb899ca9d95af24e9db",
        "right_leaf": "f4e189a08b486253ea0a5cc7bf7150055e738898115c4caf00e45634d6925539d51852409d1fe9108469e9b15668b940f3369300bb27cc292d1fabc0c07cd593",
        "successor": "e227dd97e5166364483b41f058f0d176e3a50a7510299038b09ae3aef2cbafb26c787afad82563a945b433fa2d1279af3535755235ab69d6e5ab089179177c14"
      },
      {
        "witness_event_verification_hash": "67e187411f1e514f232ae2858168da29b15ddfd07523e7a7618bfbf91c583f54fe8e850146120539a92a63ce6138f96599fb8a46ed492e428fe6fde9b9ea82ae",
        "depth": "1",
        "left_leaf": "e227dd97e5166364483b41f058f0d176e3a50a7510299038b09ae3aef2cbafb26c787afad82563a945b433fa2d1279af3535755235ab69d6e5ab089179177c14",
        "right_leaf": "780f3eb08f24022be4463be141bcda6a33a157cd0fd44cf209312b8427ac4036637a63d239526555128a4e7f4bb588ebfdbd8a8cc7d797038e29b852a4fae26c",
        "successor": "f3bd4e82b1e3d304005a7ddf4ab940f3e4e1cf099ca1c058454c431ed3feb0674c044e53150eb5691073ba58a3491565f72f6a6c2a24562ea080b569b4496c9f"
      },
      {
        "witness_event_verification_hash": "67e187411f1e514f232ae2858168da29b15ddfd07523e7a7618bfbf91c583f54fe8e850146120539a92a63ce6138f96599fb8a46ed492e428fe6fde9b9ea82ae",
        "depth": "0",
        "left_leaf": "f3bd4e82b1e3d304005a7ddf4ab940f3e4e1cf099ca1c058454c431ed3feb0674c044e53150eb5691073ba58a3491565f72f6a6c2a24562ea080b569b4496c9f",
        "right_leaf": "4a0c120fbdd6219b774eb2cb2076f4050d606b621e384c3ec645be0e5dbcdac3132f1f2acb531fa5ff62429907b77cf8d29a760be3765eb4decd83949a2925f8",
        "successor": "14f26d7dc0be77afff9131c03cab39a2fa9e1270c6face3fdc35b9b4b4ac4550d048c356a4713568c42411c3e7fe3553ec7b993c9bd7da97cb976e843d7e4d29"
      }
    ]
  }
}

2nd Revision

This revision entangles all data fields of the previous revision. As the calculation of the revision_verification hash depends on the revision of the previous revision, it is shown in verification_context.

{
  "verification_context": {
    "has_previous_signature": true,
    "has_previous_witness": true
  },
  "content": {
    "rev_id": 362,
    "content": {
      "main": "First revision text",
      "signature-slot": "[\n    {\n        \"user\": \"0xa2026582b94feb9124231fbf7b052c39218954c2\",\n        \"timestamp\": \"20220116090439\"\n    }\n]",
      "transclusion-hashes": ""
    },
    "content_hash": "9732084a45fd344d63687ccf9b5cd942f99ffe1debd11622b05d0cd24a2de3e5608d5f5121bdd7559c0a2d39067f9258c4f9612e44728df2e8d9026a88ed650c"
  },
  "metadata": {
    "domain_id": "acfa9f682e",
    "time_stamp": "20220116090439",
    "previous_verification_hash": "9dab72c7635043452958c4cc2902f48ef7c4ae437058280197c6a2736ab9635f799cbf190d9d07dd76589055a8ad64e61c6bebd1487994207d4cb7918b471f57",
    "metadata_hash": "8df483539e2f81e64c9b9df0c7e13ae7778947b5defef860fbaed1260eade794999839bb254ea5006a5d4b6a89a37980ab576dc546d6336518d65b80bf2a5cb5",
    "verification_hash": "296347471b33f3d3c69cc6e0699d80b4cb68ffc79c3ecce96beb659fa324fab1de7a888932fbfb7c60bb8cc83c9445ce15532987a7b59440cada649681618293"
  },
  "signature": {
    "signature": "",
    "public_key": "",
    "wallet_address": "",
    "signature_hash": ""
  },
  "witness": null
}

3rd Revision

This revision features a transclusion-hash for an immutable link to another revision.

{
  "verification_context": {
    "has_previous_signature": false,
    "has_previous_witness": false
  },
  "content": {
    "rev_id": 363,
    "content": {
      "main": "First revision text\n\n[[File:Logo_inblockio.png]]",
      "signature-slot": "[\n    {\n        \"user\": \"0xa2026582b94feb9124231fbf7b052c39218954c2\",\n        \"timestamp\": \"20220116090439\"\n    }\n]",
      "transclusion-hashes": "[{\"dbkey\":\"Logo_inblockio.png\",\"ns\":6,\"verification_hash\":\"9b2b3cafb90a07433a2b61885a9e64641a99b1e9024cf53b640501d3706b142fed7bc372300973137ef9d92584fac70976c3889d5610abcfe1f187c248263a56\"}]"
    },
    "content_hash": "14b8256ccd5fa1d883983317f92f428eadb52f699f476b9be69f14c6892b41979ff7b5b7a7a978177985d6aaa0bcfd9857a2646aedc4cbb3299373daa647814b"
  },
  "metadata": {
    "domain_id": "acfa9f682e",
    "time_stamp": "20220116090556",
    "previous_verification_hash": "296347471b33f3d3c69cc6e0699d80b4cb68ffc79c3ecce96beb659fa324fab1de7a888932fbfb7c60bb8cc83c9445ce15532987a7b59440cada649681618293",
    "metadata_hash": "09688c05a83bb74bb255fb0c571cb6314b65f5b7f00750547a2c43f4959d4702ae2aec019c6fb4b0e5d23adea87fd456b0eaffc6ae271163a1fa45b4bae54230",
    "verification_hash": "b35894d74dfcf8b41ff95eed97705e1acf9081021e0d478d8645cb04b8a0b4a013ee8f7fb6e140d149f2c92f20bba984fad5535938a5e36ae6a799a18343b806"
  },
  "signature": {
    "signature": "",
    "public_key": "",
    "wallet_address": "",
    "signature_hash": ""
  },
  "witness": null
}

API Endpoints

The AQP provides 3 API endpoints which return data from a host that runs the AQP:

Get Hash Chain

/get_hash_chain_info/{identifier}?identifier=<title or genesis hash>
Input:

  • identifier_type: the value must either be “title” or “genesis_hash”
  • identifier: the title or genesis_hash string, e.g. “Main Page” or “02c3c2…215d8d” Returns: all context for the requested hash_chain.

Example:

API Request: /get_hash_chain_info/genesis_hash?identifier=dffd37be12adc9e774b51aa712f7c5bfc09f48b083540d8ca55f91f317e8685bf09daf004f7c841e53732b8c7992de3f3b9b79350d13570c3b46803ba5119c26

API Response:

{
  "genesis_hash": "dffd37be12adc9e774b51aa712f7c5bfc09f48b083540d8ca55f91f317e8685bf09daf004f7c841e53732b8c7992de3f3b9b79350d13570c3b46803ba5119c26",
  "domain_id": "acfa9f682e",
  "latest_verification_hash": "2554fb53531f4de26ff3ad1fb8c61feea6ea47c3f13c4abda385c46ef8541361f7eee42433050281714a3900115f04fe52b5a8d781a71c4c439c5de6b91cbe3c",
  "site_info": {
    "sitename": "Personal Knowledge Container",
    "dbname": "my_wiki",
    "base": "http://localhost:9352/index.php/Aqua",
    "generator": "MediaWiki 1.37.1",
    "case": "first-letter",
    "namespaces": {
      "0": {
        "case": true,
        "title": ""
      },
     "6942": {
        "case": true,
        "title": "Data Accounting"
      }
    },
    "version": "0.3.0"
  },
  "title": "Aqua",
  "namespace": 0,
  "chain_height": 3
}

Get Revision Hashes

/get_revision_hashes/{verification_hash} Input:

  • verification_hash Returns: the revision requested if it exists and/or a list of any newer revision than the one requested.

Example:

API Request: /get_revision_hashes/dffd37be12adc9e774b51aa712f7c5bfc09f48b083540d8ca55f91f317e8685bf09daf004f7c841e53732b8c7992de3f3b9b79350d13570c3b46803ba5119c26

API Response:

[
  "dffd37be12adc9e774b51aa712f7c5bfc09f48b083540d8ca55f91f317e8685bf09daf004f7c841e53732b8c7992de3f3b9b79350d13570c3b46803ba5119c26",
  "f483d7746f67e7099099bcfa8ea5a93148251c598857e8fad21ce842da62794467067802ef9e818d240cd3312a3346a769f363145a87bfc1eeae19fe8d21b328",
  "2554fb53531f4de26ff3ad1fb8c61feea6ea47c3f13c4abda385c46ef8541361f7eee42433050281714a3900115f04fe52b5a8d781a71c4c439c5de6b91cbe3c"
]

Get Revision

/get_revision/{verification_hash} Input:

  • verification_hash Returns: the revision content together with its verification data

Example: See example above.

API Request: /get_revision/dffd37be12adc9e774b51aa712f7c5bfc09f48b083540d8ca55f91f317e8685bf09daf004f7c841e53732b8c7992de3f3b9b79350d13570c3b46803ba5119c26

Verification Process

The verification process is a redo of the verification data generation process, and additionally a comparison of their results.

Verification of Content

All hashes are recalculated in a separate client implementation, and compared with the ones sent via the API. If the data was not altered or corrupted; nor was there a difference in the process to calculate the hash, they will match. This will create a high level of assurance that the integrity and history of the portable hash chain in question has not been altered.

Verification of Account

We cryptographically verify that the revision signature is indeed generated by the account specified in the verification data.

Verification of Time

To verify that the witness event included in a revision is correct, a lookup and comparison of the witness_event_verification_hash on-chain is performed and compared with the recalculated event.

Reference Implementation

Command-Line-Verification-Tool https://github.com/inblockio/aqua-verifier-js
Chrome Extension Verification Tool https://github.com/inblockio/aqua-verifier-webextension

Appendix

The following content is informational and not part of the specification. It should help to better understand utility, context and services which can be built on top of AQP.

Aqua Protocol v1.1 Changes

Moving over to revision based verification. This allows:

  • Bulk / in parallel verification; ensuring logarithmic verification times, not linear increasing verification times with longer history. In short: Much faster and scalable.
  • Single revision and range verification (you want to verify a specific part of the content-chain)
    • This is useful for verification of identity claims, where trusted parties have signed the claim and for the validator it’s sufficient to see that signature.
  • This allows direct verification after every edit via the Guardian. This is the preparation in the interaction to provide services through the Guardian .
  • Changing the design to include transclusions e.g. this allows the verification of subpages via their stateful links / revision_verification_hashes
    • This also allows the inclusion of media files in the verification process
    • You can upload pictures, PDF’s, Word-Documents and have them automatically included in the aqua protocol and therefore in the verified data-structure
  • Introduction of verification_context which indicates if the previous revision has signature or witness data, or if the current revision has transcluded resources. This will build the correct verification structure before verification.

Change in the data-structure:

  • when requesting a revision this is done via the GetRevisionHandler.php
  • the previous verification hash is always served as well
  • if signature or witness data is present in the previous revision, there is a flag (1/0) that this revision depends on the previous revision
  • transcluded resources will be added to the content hash for verification

Data Accounting Protocol v1.2 [TBD]

  • Generalization of the Signature-Metadata to inform which signature method was used.
    • GPG Signatures
    • BTC Wallet Signatures
    • Ethereum Wallet Signatures
    • Done by: Displaying method used for signing, displaying underlying architecture.
  • Including Account as part of the verified data structure
  • Defining maximum payload size per revision

Services on AQP (Not yet implemented, exploration)

Similar Projects

None of the listed projects apply the concepts of versioning to their documents, the concept of portable hash chains, the concept of personal data vaults for data management in comparison with the AQP reference implementation.

This following list is not exhaustive:

  • Surety The oldest blockchain-like timestamping service which has been publishing to the New York Times since 1995.
  • OpenTimestamp A free and open-source service provided by Peter Todd using the Bitcoin network as a distributed cryptographic clock. The AQP MAY use OpenTimestamp as a witness network.
  • OriginStamp A company providing paid timestamping services for their customers. It looks very similar to OpenTimestamps with open-source client libraries.
  • Factom Protocol A service which creates an architecture with an extra layer of blockchain, to provide an extra layer of trusted parties while providing their own token. In our opinion, it introduces unnecessary complexity and intermediaries as dependencies compared to the AQP.
  • OpenAttestation An implementation of a timestamping service for document certification. One application of it is for secure digital vaccination certificates by the Singaporean government. They use the MetaMask Ethereum wallet for signing documents making it the most similar project to AQP to our knowledge.

Blockchain Context

DISCLAIMER: AQP is not a permissionless distributed ledger. In order for the AQP to be valuable and working, a single node implementation and single node deployments are sufficient, and do not require the witnessing part. The AQP MAY benefit from being published to a distributed ledger technology (DLT)) to achieve a witness event with high transaction security. AQP does not have a token nor is it distributing data by default.

As some concepts are very similar as those used in DLT’s, please refer to the following:

A portable hash chain and its revisions are similar to a blockchain structure and its blocks, which has its own root hash and a set of transactions which are included inside.

Blockchain Term

AQP Term

Explanation

Transaction

Input Data

In a blockchain its a signed transaction. In AQP its all the input data provided to calculate the respective content slot hashes.

Block

Revision

A block contains the Merklized list of transactions. A revision contains various hashed data inputs such as

  • Content slots
  • Metadata data
  • Signature data
  • Witness data

Genesis Block

Genesis Revision

The first object in the hash chain / block chain.

Blockchain

Hash Chain The hash chain is not distributed but by default only in the local PKC, therefore it is not a distributed ledger. Furthermore the PKC is missing a consensus algorithm to create a shared truth between notes.

A side note

It has not escaped our notice that the provided AQP improves the existing process of double-entry bookkeeping and provides a foundation for a new data economy. This also allows to create unforgeable invoices which can be clearly attributed to its sender, avoiding fraud. This is one of many other use cases, e.g. providing trusted news via revision-controlled journalism.

2 - Identity Protocol

Shows how it is possible to build an identity protocol on top of Aqua using data vaults.

The Aqua Identity Protocol (AIP) is an experimental application protocol under development for Self Sovereign Identity’s (SSIs) on top of the Aqua Protocol. This is an active field of research which is related to the work of the Decentralized-Identity-Foundation (DIF)1 and the World-Wide-Web-Consortium2. As this is under active development, anything you see is experimental and subject to change. The goal is to provide a Self-Sovereign-Digital Identity Protocol to protect individual rights, freedom and the opportunity for the individual to participate in the digital economy.

We are building on the advancements and insights for rebooting the web-of-trust initiative3 and the definition of a Self-Sovereign-Identity provided by Christopher Allen in shortened form here.4

Self-Sovereign-Identity-Principles

  1. Existence: users must have an independent existence.
  2. Control: users must control their identities.
  3. Access: users must have access to their own data.
  4. Transparency: Systems and algorithms must be transparent.
  5. Persistence: Identities must be long-lived.
  6. Portability: Information and services about identity must be transportable.
  7. Interoperability: Identities should be as widely usable as possible.
  8. Consent: users must agree to the use of their identity.
  9. Minimization: Disclosure of claims must be minimized.
  10. Protection: The rights of users must be protected.

Those 10 stated principles are implemented within the Aqua Protocol and it’s existing reference implementation in various degrees. They are also represented in the Design Principles .

Architecture

For the Aqua Identity Protocol to be implemented in accordance with the above statements, SSI-Principles and critical component choices from outside the protocol need to be made, and required tools need to be provided. Data Vault’s will provide a space which is fully account controlled. Other architectural decisions enabling SSI can be found in the reference implementation PKC Architecture Documentation.

Usage of Data Vaults to protect identity claims

Pages with the namespace : must be ‘read and write able’ by only by default. This is to protect the personal-identifiable data of the user. This data should be stored in a place where only the account owner has access to. This can be achieved by having the data stored locally on a machine the account owner has, or by using cryptography which requires the account’s owner explicit interaction to decrypt it. The content should not be decrypted on the server, but within the web-browser or client-application to ensure that a potentially compromised service-provider can’t leak the sensitive information.

  • Identity claims are encrypted by default and can only be decrypted by the account owner or other accounts explicitly given permission to do so.
  • Identity claims must be given access by the account owner to e.g. let somebody else sign them.

Note: There should be an extra effort by any Data Vault implementation to protect identity claims. It is recommended to strongly regulate and audit the emerging solutions to ensure a high level of protection for citizens.

Self Issued Identity Claims

These are used to make statements about an account to form an identity. Those claims can be partially revealed on demand to other parties. Those claims can also be protected by advancements in privacy technologies like Zero-Knowledge-Proofs and ongoing advancements in key management.

Identity claims are sets of Verified Data which follow a structured data convention to claim or attest attributes to an account. For example, an attribute could be the year of birth of an account owner, or the legal name of an account owner. Claims should always be atomic to allow the account owner to disclose them selectivity. Different claims can be combined to represent a citizen ID or a drivers-license. Other claims can be educational certificates, like school certificates.

Identity claims in the Aqua Identity Protocol are always self issues. This means that the first signature on the claim needs to be from the private key which belongs to the account, i.e. the claim is issued for. This proves account ownership. This means:

  • All claims can only be issued from the account which they make a claim about. A claim belongs to it’s origin account and can only be managed from it’s address.
  • A claim can ‘accumulate trust’ by being signed by other accounts who support this claim.
  • Self-issuance protects accounts against spam, and the issuance of fraudulent claims to an account without the knowledge of the account owner.
Claim Attestation

Can be completed by a Trust Authority referring to the Identity Claim in collaboration with the account owner, or a referencing statement.

It is possible to attest to a claim by referencing the claim’s unique revision_verification hash within the attestation. This means you can make statements about an account or about a claim without involving the account owner in that process. An attestation contains a statement about the referenced data set, and is expected to be signed by the account who makes the attestation. This ensures there is clear account attribution. Attestations without signature should be disregarded, as they have no account attribution.


Specification for the Aqua Identity Protocol

Policies for Self-Issued-Identity-Claims:

The title is not protected against changes, but the content of the page is protected.*IMPORTANT: Therefore, we must compare the page stored ,. Then reassemble the title to check if they are consistent before proceeding with further validation of the identity claim.

Content of the page

  • Account:
    • Is repeated to reassemble the title to check it.
  • Attribute: <attribute_name>
    • Is repeated to reassemble the title to check it.
  • Value: Is the value of the claim. E.g. ‘1889’ for a year of birth.
    • The first revision must be signed by the account owner to create a self-issued identity claim
    • Values must not change within a hash-chain. If a value changes, the claim will be marked as invalid with the revision of the change. If a new attribute value needs to be defined for an account, this is done through a new claim.

Claim issuance Process

  1. Claim is created (based on template)
  2. Claim is signed by issuer (first revision)
  3. Claim is registered by issuer (optional, done via Claim Registry)
  4. Claim is verified by authority to accumulate trust (this might include the requirement to hold a revocation authority on a claim registered via a Claim Registry)

Trust-Chains with Identity Claims

Will build a web of trust, which can be applicable not only for public institutions, but also for commercial organizations and private entities.

A trust chain of identity claims for educational certificates (example)

  1. The certificate is issued as integrity verified data via the Aqua Protocol.
  2. The recipient of the certificate registers the certificate as an identity claim
  3. The certificate is signed after it was issued as an identity claim by a Trust Authority (e.g. the university professor) and the university director’s office (director)
  4. The university professor holds trust claims from the university director
  5. The university director holds trust claims by the ministry of education
  6. The educational ministry of education holds trust claims by the minister-president
  7. The minister-president holds trust claims of a verified election

The chain of trust is supplied by the party signing the statement.

IMPORTANT: The authority who is given authority needs to prove where their authority originated when they act in the function of that authority.

  1. E.g. the professor needs to supply the claim of the university entitling him
  2. E.g. the university director needs to supply the claim of the educational ministry
  3. E.g. the educational ministry needs to supply the claim of the minister-president.
  4. … and so on.

Verification Process

  1. Claim is presented
  2. Claim integrity is validated
    1. How can you trust the content of a claim: Claim content needs to be static. E.g. a given-name claim ‘Jarred Maxim’ cannot change, even if there are many revisions to the page. If the static content HAS changed, the claim is INVALID or at least only valid until the point where it changed. In the case of such an information change, a new claim needs to be issued.
  3. Claim registry is validated (root trust)
  4. Claim signatures are validated
    1. Comparison between signature time and validity of the signing authority. Is the account authority still valid?
    2. lookup of authority claims from expected root trust?

Trust in Signatures

If somebody signs an identity claim, we believe they do that to

  1. Vouch with their account for the integrity of the presented data. This can be supported via an Authoritative Claim and a comment which gets attached to the claim itself or is issued via an Attestation.
  2. To verify the signature, we use an automated verification process. This is done through implementations of an Aqua-Verifier like https://github.com/inblockio/aqua-verifier-js or https://github.com/inblockio/aqua-VerifyPage-chrome-extension which also checks against the restrictions given by the Aqua Identity Protocol or/and additional defined policies.
  3. Add access rights to a claim by adding a Data Usage Agreement which is enforced by the Guardian. Access rights can be restricted:
    1. to specific accounts
    2. to specific domain id’s representing an instance of a Data Vault
  4. Verification: The verification process considers which account it signed, and what was stated with the signature, or with the additional data added to the claim. To consider a claim valid, the relationship between the verifying party and the Trust Authority who signed it, is essential. Can the party be trusted? Why do I trust this party?
    1. Claims can be either chained (cascaded into each other) and offline verified, and/or online verified against an existing Claim-Registry. In both cases a known trusted party account reference point is required for the verifying party to trust.

Trust Authorities

are accounts which have an elevated trusted position. They issue Authoritative Trust Claims to give legitimacy to a self-issued identity claim.

Why do you trust a professor to issue an Educational Certificate ?

Because the professor is able to provide a trust chain, represented by a chained Authoritative Trust Claim , proving that he has authority to attest an Educational Certificate with his signature. With his signature, he is increasing the trust of the self-issued Identity Claim to allow it to have practical utility.

Claim Registries

A claim registry in the context of the Aqua Identity Protocol is a global registry to allow for real-time global claim revocation and re-instantiation of Identity Claim’s. This solves the problems related and known to certificate revocation. The Claim Registry acts like a global Claim Revocation List (CRL)5.

E.g. a driver’s license can be revoked by a Trust Authority and later be re-instantiated after the ‘Punishment for driving too fast’ is over. Identity claims are either valid or invalid. The Claim Registry is managing who can revoke / re-instantiate a registered claim.

There is ongoing research and optimizations on privacy concerns to reduce costs for on-chain Identity Claim.

Implementation in Ethereum with Smart-Contracts (Solidity). All claims are account bound.

Claim Registration Specification - Smart Contract Structure

  • <revision_verification_hash> as root trust of the self-issued identity claim. A claim has to be a verified page, which is signed and timestamped. If all are present, the next page-verification hash entangles all of those properties and becomes the ‘address’ of the claim. In the receipt of the publish process for the claim, there is an attached receipt, and by writing the receipt into the claim, there is also a new revision generated. This creates the second revision of the claim, which entangles the signature and the witness event with the hash-chain to make them immutable.
  • [type:boolean] of claim
    • 0 - valid
    • 1 - revoked
  • [type: date DDMMYYYY]: if current date past expiration date, the claim is considered expired and is not accepted anymore

  • < owner == sender address> [type:address] an account which updates the status of the claim, e.g. revocation or suspension of an account

  • < additional revocation authority> [type:address] list of accounts which are authorized to update status of the claim other than the owner. The owner has a special right to update the list of revocation authorities to hold new addresses.


    EXAMPLE: Claim Registration Data [Receipt]

The presence of Claim Registration Data [Receipt] means that the claim address (verification hash) has been written to a Claim Registry on a Witness Network.

Protocol: Aqua Identity Protocol Version 1.0

Registration Event: 1

  • Domain ID: e9ece84189
  • Claim address (verification hash of self-signed claim): 1db331add502cf1b1712468d1c3e5d66a0016a6f04885c5533619ffbb43fffb6dfa452e119d4bee7628e9792af69089d38d860a5f8d0708184bbb74b8cabdaf7
  • - Merkle Root: 7e9782fb8a6e749ef2ba48f8cd410b05335ba48b20ba42508efeb76add38b0f39e717e91381c8de34641af4c477c39fc169eaa0908dba25e0a54e8de615fcd00 - Claim Snapshot Verification Hash: 278f930a35d06d7b9d28aab37d402c147d1beffdbe53d212481c17ec686698e9469f9cf7d7d53b9a4435c4b99ca2e578b5dc5fec6c63cb802b540493fe927575
  • Witness Network: goerli
  • Claim Registry Smart Contract Address: 0x45f59310ADD88E6d23ca58A0Fa7A55BEE6d2a611
  • Transaction Hash: 0xa572e8d6ef8d4a1bb3b5087680817e70bb79a0376c3a9be9e2c6b4d92df228a1 Sender Account Address: 0xa2026582b94feb9124231fbf7b052c39218954c2

Claim Revocation

Traditional revocation:

  • Traditional strategies for certificate revocation can be applied.6
  • Most effective are short expiration dates where possible, due to the lack of effective revocation processes for certificates without global registries.

Using Distributed Ledgers

  • Done via Claim Registry (indicates the global status of an identity claim to be either valid or invalid)

Process:

  • Locally completed (within the Self-Issued Identity Claim) by changing the status to ‘revoked’ and signing by the issuer. This adds a receipt to the identity claim, which is displayed when verifying the claim. This includes the revocation transaction for the revocation on the Identity-Registry
  • If there is a new claim which is succeeding the previous identity claim Claim Registry , then this is also noticed within the revocation receipt under ‘Successor-Claim: .

Bulk Claim Registration (Should be part of Claim Registry)

  • To reduce costs during registration of the identity claims via a Claim Registry they can be clustered and registered together
  • We use the SmartContract:Identity-Registry for this. To scale our efforts we utilize a variant of the ‘Domain-Manifest-Generator / Publisher’ which is very similar. The differences are in the selection of what can be published, and the data structure which is published to the Claim Registry instead of the witness smart contract.
  • The Claim Snapshot Generator can only include ID claims of your own namespace.
  • The Claim Snapshot Publisher is registering all selected claims (select them by page name (filter required) and will populate the target SmartContract:Identity-Registry . Every claim will hold the relative merkle-proof to show the path for it’s registration.

Examples for Identity Claims with Aqua:

FAQ

  1. How to find Claim Registry ’s? By following the chain of trust of authoritative claims and validating them one by one.
  2. How to check if authority is still valid and how to find an authority registry? As before, by reading the chain of trust and looking up the status of the related identity claims.
  3. How to visually check authority dependencies? It is possible to visualize the links of links of links to represent the chain of trust.

Important References:

Thought leader Christopher Allen:

See Implementation Specific Aqua Identity Protocol Implementation in MW e


  1. https://identity.foundation/  ↩︎

  2. https://www.w3.org/  ↩︎

  3. https://www.weboftrust.info/  ↩︎

  4. https://github.com/WebOfTrustInfo/self-sovereign-identity/blob/master/self-sovereign-identity-principles.md  ↩︎

  5. https://www.securew2.com/blog/certificate-revocation-crl-explained  ↩︎

  6. https://social.technet.microsoft.com/wiki/contents/articles/34071.pki-certificate-revocation-process-explained.aspx  ↩︎

3 - Aqua Name Resolution (ANS)

ANS is used to hashes of various types to human readable names

ANS is used to resolve hashes of various types to human readable names.

The following hashes are resolved by the ANS:

  • wallet-addresses to names, organisations an aliases.
  • genesis_hashes to titles.
  • domain_ids to registered endpoints of that domain.

See the reference implementation .

4 - Assurance Levels (AAL)

Highlights the levels of assurances you can receive by using technology provided in the Aqua reference implementation.

How safe are the wallets to used? - Current PKC Pilot - relating to the ‘Authentication assurance level’s (AAL)’ according to the World Bank standards:

See short presentation Aqua_PKC_-_Wallet-Security.pdf

Level 1

The Metamask wallet alone has a low (level 1 ) level of assurance. MetaMask is the most common browser blockchain wallet applications on the web and their developer teams strive for increased security to keep crypto-assets of their 10 Million+ Users safe.

Level 2

Metamask offers integration with Hardware-Wallets which raises the level of assurance by having at least 2 authentication factors (e.g., a token with a password or PIN) to min. level 2. The Hardware-Tokens are build to be temper proof.

Level 3

  • It is possible to integrate the different layers of security at once

with Metamask (Password Protection) a hardware-token (temper proof) with PIN a one-time-password generator based on your mobile-phone (recommended is a hardened mobile phone which also uses biometrics for highest security) requires implementation of one-time-password authentication for logins after wallet-authentication see https://github.com/inblockio/micro-PKC/issues/37

  • Other high security options allow multi-signature logins with smart-contracts requiring multiple parties to confirm the operation to be executed. This can be defined based on the smart contract to extreme security as each of the layers mentioned above can be added to each party being involved in the multi-signature event to open a PKC or to SIGN a verified page within the PKC or to witness a data set via a witness network.

  • The mentioned security model is not dependent on the security of Metamask. If Metamask is hacked it will not allow to compromise the model above as the security of the private key of the hardware token is preserved.

5 - Data Accounting

Introduces the concept of Data Accounting

We first exchanged goods, then we used means to exchange goods, such as shells and coins. Today we use money. We have transitioned to a world where we present and exchange data to receive goods and services.

The system for accounting provided by Luca Pacioli, the double-entry accounting is the foundation of our work. We present a modern way to do double-entry bookkeeping for data.

Data accounting is the process of metering data in a standardized unit of exchange, and converting it into a form which can be exchanged to provide data symmetry between accounts.

The unit of exchange is not measured in a numeric value as found in cash systems. Data have multi-dimensional value, which means they depends on your perspective and your relationship to data. This determines how much this data-set is worth to the individual.

The standard measure of exchange is a hash, representing the state of the data. A SHA3-512 hash always has 128 characters, regardless of the size of the data it is representing.

Metering data / anchoring data in space

To meter data, we can refer to them using a digital fingerprint, i.e. their hash. This allows us to refer to the data in a consistent form. The hash has captured sufficient entropy to be unique, so it becomes a unique resource locator. This ensures that it is always deterministic to what data we relate to.

Accounting data / anchoring data to account

The second step is that the data is attributed to a specific account. This is achieved by using cryptographic signatures known as public/private key encryption . The public key acts as a unique account address. It is necessary that the accounts in use are globally unique, so there is no realistic probability of a name collision between accounts. This ensures that no data is attributed by mistake to two accounts or more.

Proof of existence / anchoring data to time

The last step to account data is the usage of a cryptographically secure clock, so we know which data were witnessed first. Data can be replicated, so the value lies within the social implications of the message within the published data. This cryptographic timestamping allows us to determine the first account to witness the data. The most secure witness-networks which provide a service for cryptographic witnessing of datasets are Bitcoin and Ethereum. The first known examples of partial data accounting were done by Surety in 1995 and OpenTimestamps in 2012 .

Practical accounting

The accounting book in the data accounting age is a ‘data vault’ which is controlled by one or multiple accounts. This allows both personal data vaults or organizational data vaults.

A data vault is controlled by a cryptographic wallet. The vault has the objective to govern the data for the account owner who is associated with the vault.

The vault provides a capability to export and import data, so it can be exchanged between data vaults. This allows for collaboration at scale, and the usage of data as a means of exchange.

Please contribute to this article (fixing errors) by exporting it and sending it back with your improvement to community[at]inblock[dot]io.

6 - Data Governance

Introduces the concept of Data Governance

Author: Ben Koo E-Mail: koo0905[at]gmail[dot]com Year: 2021

Data Governance identifies how to manage the value of data. A well-known turning point in history was the publication of Luca Pacioli ’s Summa de arithmetica . This encyclopedia of mathematics, had 26 pages worth of text on what we call Double-entry bookkeeping . This became the foundational literature for accounting , the progenitor of using data to assign value to accounts, and henceforth gave birth to the practice of data governance.

Accounting as the foundation of Data Governance

According to historian Jane-Gleeson White12, Pacioli’s double entry book keeping idea influenced the development of arts, sciences, and capitalism. Double-entry bookkeeping as a rigorous approach to ensure data integrity, not only influenced the practice of the accounting profession, and it had a significant impact on the the formulation of Hamiltonian Mechanics , which is a foundational theory of both classical mechanics and quantum mechanics.

Sir William Rowan Hamilton wrote a paper3 cited many many scholars to demonstrate that many ideas about complex algebraic manipulation that laid the foundation of scientific revolutions are based on the formulation of creating accountable mathematical formulation strategies through double entry book keeping. David Ellerman had a paper that explains the powers of double entry bookkeeping in sciences4. The notion that creating public addresses for transactions amongst different accounts has been documented as a scientific theory on Double Entry Book-keeping. This book can be found online5:

Digital Governance

Given the intellectual roots of data governance have strong linkages to mathematics and accounting, it is only after the introduction of personal computing devices , and later the ubiquity of Internet access that made data governance an idea relevant to public affairs. The argument is that many people’s basic privacy and property rights may be challenged by people who have access to data collection and deployment technologies. Imminent threats such as fake news, big brother monitoring practices, identity thefts, and crypto currency issuance are already challenging the stability of the existing social fabric. These type of social debates are often related to the ideas of Digital governance . At this time, digital governance has not yet become a mature field of study, and it needs to be grounded in simple principles, so that it can be transparently practiced with local adaptations.

Conceptualization of Data Governance

Beside the notion of digital governance, data as an asset class must be kept accountable, so that it can be evaluated, and transferred with an objective operational framework. Knowing how to organize data in formats that satisfy consistent abstraction strategies, such as Universal Resource Identifier and Universal Resource Locator are important starting points in this field. Earlier work in data governance in a web of hyperlinked media can be traced back to Project Xanadu by Ted Nelson .

More recent more publications in this fields are Lessig ’s Code v2 6 and soon to be published work of Alex Pentland ’s Building the New Economy 7.

References


  1. J. Gleeson-White, Double Entry: How the merchants of Venice shaped the modern world–and how their invention could make or break the planet, publisher Allen & Unwin, ISBN:978-1-74175-755-2 , November 2011 ↩︎

  2. J. Gleeson-White, SIX CAPITALS, or CAN ACCOUNTANTS SAVE THE PLANET?, publisher Allen & Unwin, ISBN-10:9780393246674, February 2015 ↩︎

  3. Hamilton, S.W.R. (1837) Theory of Conjugate Functions, or Algebraic Couples: with a Preliminary and Elementary Essay on Algebra as the Science of Pure Time, Transactions of the Royal Irish Academy, 17pp. 293–422. ↩︎

  4. David Ellerman, On Double-Entry Bookkeeping: The Mathematical Treatment, https://arxiv.org/pdf/1407.1898.pdf  ↩︎

  5. J.C. Colt, The Science of Double Entry Book-keeping, online media: https://core.ac.uk/download/pdf/56693696.pdf , last accessed: May 4th, 2021 ↩︎

  6. L. Lessig, Code: And Other Laws of Cyberspace, Version 2.0, Publisher: Basic Books, 2nd Revised edition, December 2006 ↩︎

  7. Alex Pentland, Alexander Lipton, and Thomas Hardjono, Building the New Economy, MIT Press, Work in Progress, https://wip.mitpress.mit.edu/new-economy  ↩︎

7 - Delegated Witnessing

Describes the process of sending domain snapshots to remote data vaults.

Describes the process of sending a domain snapshot to a remote data vault for witnessing. The domain snapshot is then included in the witnessing event and sent back to its original data vault. This makes the domain snapshot behave like an ordinary portable hash chain that can be witnessed. The relative path of the Merkle proof is used as a prefix for all other included portable hash chains included in the domain snapshot.

8 - Design Princiciples

Lists the design principles underlying our reference implementation

The following design principles pertain to Aqua reference Implementation PKC

Private is Default

The principle default to private is that no data of the PKC Data vault is shared without it being explicitly authorized by the associated account.

Domain Access Levels

Levels of access are:

Private: Only the account owner has access to files and services initialized by his account. Agreement / Permissioned access: The Account owner grants other Account’s access to files or services based on verifiable contracts which are themselves written with the Aqua Protocol to ensure they are forgery-proof and therefore safe. Public: Other Account’s have access to the file or service without agreements.

Offline Capability

The PKC Data Vault follow’s the principle of being able to run and be functional without internet connection after setup or through installation based on local installation files.

This allows PKC setups to be kept offline from any internet connectivity while still functional. This can provide the required assurances for very sensitive data.

Separation of Account and Service

Concern: There is a trend in the DIF/WC3 Identity space that some players like to accumulate personal identifiable data (PII) inside of Wallets. We think this is a ill-fated direction and there should be a clear separation between account and service. Wallets should not hold personal identifiable data.

Benefits:

  • If the service gets hacked, no account related data is leaked if it’s not stored.
  • Account is not compromised, as there is no password saved within the service with Password free login.

Wallet ’s have one job. Keep private keys safe! (Account Management)

  • Should be stupid, simple, safe!
  • Allowed operations:
    • Signing
    • De- / Encrypt
    • Publishing transactions to service (e.g. witness networks)
  • Ability to choose “high level of assurance” depending on the stakes associated with the account(s) managed by the wallet
  • Takes care of key recovery mechanisms

Data Vault (Service)- Has one job: keep the data safe!

  • Principle: Offline Capability so it can run offline; works offline on local machine
  • All significant actions authorized and managed though the wallet
  • Should offer good tooling for data storage and manipulation
  • Strong access control: By Principle: Default is Private which means data is only accessible by the owner.
  • Data is well protected
    • The Data Vault should apply additional security features to keep the data safe.
    • e.g. Encryption of files / databases if service is not used.
    • e.g. Encryption of pages with web-decryption (allowing for End-to-End Encryption).
  • Capabilities for sharing and publishing data
  • Offers full Backup and Recovery mechanisms to move data freely

Signature Login

We do not use passwords for login but instead we use a signature of a private key to authorize access to a service. This increases security and does not require the user to remember a password, creating a better user experience.

Pros:
* Account owner uses his wallet to complete a signature challenge for login. With this challenge he proves that he owns the private key to a public key. If the public key is registered as an account at the service, the account is granted access.

  • The password can’t be leaked as it does not exist.
  • Very high security

Contra:
* Requires access to the wallet which holds the private key to authorize access

  • Not commonly understood by users as a way to login (new process)

Principle: Data Portability

The Principle of Data Portability means that the Account owner can instruct the Service to Export all data associated with the Account and is free to move this data to a new service which is capable of importing the data.

Implementation Specifics

In PKC’s this is guaranteed by:
* providing a Backup and restore procedure which allows to move data between PKC’s and restore them in case of a required recovery.

  • providing a file import and export function
  • providing an import / export API

Furthermore we ensure with the development of the MediaWiki Data Accounting Extension, that the data is still compatible with the legacy import / export (which means only the text not the verification data is imported / exported.

9 - Guardian

Shows access and transport layer logic used to interconnect data vaults

Context

It is highly problematic to expose sensitive data, such as personal identifiable data, to the internet. The service who hosts that sensitive data, needs to be compromised only for a short amount of time, to leak all the data. Often caused by configuration mistakes or by vulnerabilities being present in the used technology stack.

We can’t effort to have leaks on personal-identifiable data in data vaults. To raise the bar on making attacks difficult and reducing the chance of leakage of information, we introduce the Guardian as a extra security layer to protect services like the PKC from attacks.

Summary

The Guardian is a software which manages the boundaries of your digital domain. Guardians are used to connect to secure transport networks (HTTPS, Matrix Network, Didcomm) and publishing networks (e.g. Swarm.eth). The Guardian is used to build trusted connections to other Guardians via trusted transport-layers to exchange data with them. As the Guardian connects to other Guardians, it also manages all connections to services in it’s domain and access to those services.

Goal

Secure all services behind the Guardian from attacks and unauthorized access. Keep the data vault and it’s data private and safe, while enabling the ability to exchange data with other Guardians.

How

Enforcement is handled on each connection and each data set so that services behind the Guardian are never directly exposed. This makes the Guardian the most security sensitive component in the Aqua reference implementation, as we expect the Guardian to handle all incoming and outgoing traffic. The Guardian enjoys additional attention and effort to be up to it’s task by hardening it and applying security best practices to ensure that it is fulfilling it’s security promise to keep services behind the Guardian safe.

Every transaction leaving or wanting to enter your domain will be supervised and checked by the Guardian. The core functionality of the Guardian is a library to verify the Aqua Protocol. Only if the verification succeeds additional steps are introduced to make decisions how the data is handled.

This allows the Guardian to read and understand Aqua verified data. This allows for the implementation of a wide set of behavioral rules and offers the opportunity to create various ‘Smart contract’ languages on top of it.

The Guardian verifies a file, reads its contents and checks it’s permissions to classify if an action is considered legal or illegal, permitted or denied. Basic functionality for a Guardian can be compared with a traditional firewall, or a application firewall but is much more sophisticated to manage access on the data-level.

Terminology:

Proving ownership over a domain by signing the domain ID with an self-issued identity claim which is also registered in a claim registry to ensure nobody claims to have owned that domain before by manipulating the digital clock and faking an earlier owner-ship claim over the domain.

Permission Agreements / Data Usage Agreement / Access Rights

are contracts which represent the terms and conditions under which files and/or services are shared with other accounts and/or their digital domains.

By nature those Permission Agreements will be compiled through pages and stored as files. To form an agreement, the other party must be notified about new resources as they become available. For example, when we share a page with another account. To complete a permission agreement, the counter party has to sign the permission agreement or reject it. If the permission agreement is signed, the other party enters a contractual relationship in which they will be liable for any agreement violates executed from their digital domain.

Processes

Domain Handshake

Establish trust between two Aqua domains. For this we have Alice and Bob which want to establish trust between their domains. They both have a Guardian in place to protect their data vaults.

Steps:

  1. Alice: Create access contract: I <Alice_account> want to connect from my <domain_id> to a <domain_id> controlled by <Bobs_account> with my <alice_domain_id> via the following channel: DNS/HTTPS via <alice_Guardian.domain.com>.
  2. Alice: sign contract
  3. Alice: SEND contract send the page via ‘mail’ / ‘matrix’ whatever to the remote PKC instance.
  4. Bob: veries the contract contract and imports it
  5. Bob: extend contract: I <bobs_acocunt> connect my PKC <bobs_domain_id> to your PKC <Alice_domain_id> via my Guardian_endpoint <bobs_guardian.domain2.com>.
  6. Bob: sign extended contract: Bob uses his wallet to sign his extended contract.
  7. Bob: send extended contract TO Alice: Bob sends his Contract to his Guardian.
  8. Bob’s Guardian: Verifies and sends the contract to Alice Guardian.
  9. Alice Guardian: Guardian verifies all data Sends OK back to Bob’s Guardian Sends Updates contract into Alice PKC Waits for Bob’s Guardian to request available pages
  10. Bob’s Guardian requests a list of pages: ' What pages do you share with me?'
  11. Alice Guardian: Returns list of accessible resources for Bob

Example: Sharing a File

Target: Sharing a file with another account. Using two Aqua data vaults with their two Guardians to manage access to them. We assume the Guardians already have executed a handshake to enter a trusted relationship. We also assume, that the file should underlay access basedon account restrictions and domain restrictions.

Example 1: Sharing a file without additional constrains with another account.

Alice wants to share her page ‘My secret research’ with Bob. Their Guardians have already formed a trusted connection. What Alice needs to do now is to add a sub-page with an immutable link under the ‘My secret research’ page and define access. To be able to define access Alice needs to have a claim over the ownership over the domain she is sharing from.

Alice creates an Access Permission for the whole page or for a single revision by creating a page with the following syntax:

  • <genesis_hash>:access_contract

  • To give access to the whole page with all it’s revisions.

  • <revision_hash>:access_contract

  • To give access to a specific revision.


Content of the page:

I Alice give access to Bob

  • option 1: to the whole page including it’s history <genesis_hash>
  • option 2: to the following revision <revision_hash>‘My secret research’

Additional one-sided conditions:

  • This access contract expires in 7 days

This contract will come into place with my signature.

The Guardian will react to a specific syntax of pages holding contracts, agreements and access rights to adjust his network access rights accordingly to it. Alice-Guardian will respond to the question what resources are shared by Bobs-Guardian with the answer that there is a new page available according to the access contract which now gives Bobs-Guardian the ability to query the content of ‘My secure research’ from Alice according to the contract. Depending on Bobs-Guardian setting, the Guardian might automatically load the resource and forward it into the post-box of Bobs Data Vault.

Example 2: Sharing a file with constrains forming a contract to do so.

Same as 1 expect that for the contract to come into place, Bob needs to sign the contract from Alice containing additional constrains.


Content of the page:

I Alice give access to Bob

  • option 1: to the whole page including it’s history <genesis_hash>
  • option 2: to the following revision <revision_hash>‘My secret research’

Under the following conditions:

  • Do not share outside your domain <Bobs-domain_id>
  • Do not share with any body else (Bobs domain can’t have another account registered to it, if there is an account registered the Guardian of Bob will say that Bobs domain does not fulfill the requirements to establish this contract.
  • Do not modify it.
  • Delete it after 7 days.

For this contract to be valid, signatures of first Alice and then Bob need to be present. This means, after Alice signed the access contract, the contract is a new available resource to Bob to be loaded. Bob can now sign the resource in his domain and return the contract. Leading to the contract send back to Alice domain and being updated there. Bob now gets access to ‘My secret research’ which has been updated as well, to contain via an immutable link the access contract.

Permission Templates, Complex Permissions (Groups and more)

It is possible to apply complex permissions based on templates, or and connecting multiple access contracts by using

  • instead of this syntax <genesis_hash>:permission_agreement
  • the following the syntax <genesis_hash>:<genesis_hash-2> in which the <genesis_hash-2> contains a list of sub-pages with access contracts which can be used to apply access via permission-objects which are represented by the <genesis_hash-2> page object.
  1. Alice wants to
  2. If the user wants to propose changes to the page, he will send an updated PAGE FILE to the OWNER of the PAGE.
  3. The owner can decide to ACCEPT the changes. Or to include the changes in the HISTORY File, but not COMMIT them. Or to NOT include the update of the PAGE, and disregard it.

Specifications:

The Guard Daemon checks if there is digital contract present in his domain. Those contracts set permissions for allowing a counter party to access a service or resource (like a file or a page, or a revision). It’s also defining the constrains under which permissions access is given. In this case it requires the digital signature of the receiving party for the agreement to come into place and be valid.

Guardians have administrative access to the services they manage. Therefore they can supervise the activities of services and use them as triggers to e.g. provide access according to a set permission without additional user action.

Guardian Components:

APIs

  • System-API to control a service via a service specific library. Each services will have their own control-library and control API to create an abstraction layer which allows for a unified control logic in the Guardian.

    • E.g. an account is allowed to access a service
    • E.g. a resource is shared with an account
    • E.g. a trust relationship between two services is established (based on an agreement between two accounts) to exchange data
    • Implementation Specific PKC: All interactions for system interaction with MediaWiki / PKC
      • Execute Actions: Move, Update, Edit, Delete Pages
      • Request send to the Guardian: Verify a specific page or a list of pages
  • Data-API to retrieve Aqua-Data between a service and the Guardian, or between two Guardians.

    • Send data to import API
    • Read data via export API
      • Implementation Specific PKC: Read special Pages used to give access e.g. Data Usage Agreements, Permission Agreements
  • Aqua Verification Library to be able to verify incoming and outgoing data

    • implementation of the ‘external-verifier’ in e.g. GO, Typescript or Javascript (current)
  • Account-Registry (Holding the list of trusted keys and the relationship between them)

    • This includes defined ‘trusted accounts’
  • Session-Handler/Registry (Acts like Stateful-Firewall on the page-object level to mange imports / exports). The Guardian verifies incoming and outgoing data and constructs sessions based on it.

  • Guardian Policies: Are sets of rules followed and enforced by the Guardian. This includes set of rules used to protect the domain from unauthorized operations and access. Part of that are page access permissions which are managed by the Data Usage Agreements .

    • <domain_id><genesis_hash><revision_hash>:<domain_id><genesis_hash><revision_hash>
  • Transport Layer API’s / Sub-Modules for connectivity to distributed services

    • The Guardian-to-Guardian communication handler (via DNS/HTTPS transport)
    • Ethereum Integration, Ethereum Handler (As a witness Network)
    • Matrix Integration, Matrix Handler (As a restrictive/ permissioned transport layer)
    • Schwarm Integration, Swarm Handler (As a publishing network)

Guardian-Integration-Services

The Guardian has a modular design to support integration with many services and transport layers.

Web (HTTPS / DNS) Integration Goal: Have a

handler to connect web-facing Guardians with each other in a safe way. Be able to run guardian procedures via two public Facing guardians which use a public DNS name and HTTPS to interconnect with each other. Guardian procedures are: Guardian handshakes to establish trust or remove trust Request or Send portable Hash-Chains based on access rights between each other

Ethereum Node

Integration Goal: Connect to a self-hosted or remote Ethereum Node. Option 1: Configuration via Alchemy (Providing Keys) via Special:DataAccountingConfig Option 2: Implementation of Ethereum Node via ./setup –ethereum-node (provide container) Configuration of Connection to RPC Ethereum node via address (if in same network) The Wallet can be directly be connected to a local Ethereum node via RPC to avoid meta-data gathering of large providers, like INFURA which could potential track which IP address has created which Ethereum Transaction with which Metamask-Wallet, leading to a de-pseudonymousation of the user. ### Ethereum Node Handler Goal: Accelerate lookups of the Guardian via caching Every-time a witness contract is called, the Ethereum Node Handler will start to cache the all Ethereum-Witness events of that Witness-Contract and Index them in it’s database. This will reduce access times to ms vs potential seconds in lookup times, making the Guardian more performant and responsive. ## Matrix Node Integration Goal: Connect to a self-hosted or remote synapse-server (MATRIX) Node. Configure a remote matrix server or a local one via Guardian. Implementation of Matrix-Node deployment via ./pkc setup –matrix-node (provide container).

Matrix Node Handler

Context: We use Ethereum Wallets as Identity-Anchors as they are globally unique addresses (which are collision free) broadly adopted with supported hardware ledgers as secure hardware elements with an existing fast moving ecosystem for further development. They act as ‘web-based’ PGP-like utilities which do not need any Blockchain-Interaction for Signing messages and can be used as a valuable off-line capable identity anchor. With this step we separate Identity and Service; even in case of compromising the computer of the user or by having a breach of secrets in the Element-Client the Identity would be safe (in case a hardware wallet would be used). This also drastically reduces attack surface to phish a users credentials; as there is no Password-Login there is no way to steal the password to impersonate the user. All security assumptions of the User-Identity come back to the security of his private key. For the Kolibri/PKC project this is the foundation for using wallet-addresses as Identities to route traffic with matrix bots between PKC’s. The following actions are required to use the Ethereum Wallet as a strong Identity Anchor within Matrix.

This requires the following functionality:

  • Register the user via an Ethereum wallet address (successfully piloted by inblockio)
  • Detect that it is an Ethereum Wallet-Address; Verify integrity of address with the Ethereum Wallet-Address Checksum (TBD)
  • Make username not changeable (Done via Matrix settings,successfully piloted by inblockio)
  • Wallet login with Web-Wallet Metamask via OIDC (Open ID Connect) (successfully Piloted by inblockio)
  • Verify Ownership of the Wallet by doing an Element-Client side Signature Challenge to the User. Challenge resolved by signing a message with sufficient entropy to not be ever the same (to protect against leakage) with the private key via the Ethereum Metamask Webwallet (or a connected Hardware-Wallet)
  • Implement a User-to-User request of proof of Identity Users / Server can challenge other users to proof that they hold the private Wallet-Key by triggering the Signature Challenge to the User; After the challenge is done, the requested party is provided with all information to do a manual verification of the signature (the Message which was Signed, the Signature, the used method used for the signature)

Matrix-BOT

Context: The Matrix-Network communicates with the PKC through the Guardian who will manage all access to the MediaWiki service. The Guardian uses a Matrix-Bot (to handle the communication) and a Matrix-Integration (to be flexible to use a private synapse or a remote synapse server) to interact with the Matrix Network as a permissioned transport layer.

Referenz-Implementation: Suitable options for a matrix-integration are ‘go-lang’ or ‘rust’. Guardian next generation Guardian will be written in Rust, so integration of security relevant components would be preferably in Rust and Webassambly. A central point to configure the guardian to connect to matrix and other services needs to be provided. The matrix server is connected to the guardian with a service bot which is able to open rooms to exchange revisions between PKC’s.

Required Functionality of the Matrix-Bot:

  • open new room for user (required) - to share resource invite / remove other users to/ from room (required) - to set permissions who can read
  • shared resource close room (required) - after resource share is revoked join a room the user is invited too (by other matrix-bot) *‘accept invite’ check for challenge (provided via text from remote Guardian), leave room if challenge is faulty and block user (required) delete? room / delete history? Note: Use matrix only as channel not as storage (optional) preferably the history of the channel is not kept
  • post content of (mediawiki API query results from the Guardian) into a room
  • (required) read content of room (send it to the Guardian for verification, before it’s send to the import API) (required)

10 - Immutable Hyperlinks

Shows how the Aqua URI’s can be used as immutable links.

Traditional hyperlinks are usually URL’s based on the DNS structure.

This allows the resource to be routed via DNS and specified via the URL on the remote server.

The limitations of URL’s is that they are not expressing a specific state of the resource they represent. There is no way to verify if the content of the page is consistent with the content of the page who send a URL. For news pages this means that the content of the page could have changed. E.g. two visitors of the same news page could see two different pages.

We need a better way to hyperlink so it’s sure, that what is linked is consistent across domains and users. Therefore we introduce Aqua URI’s which are used to enable the receive to verify the state of the resource.

Goal

Use Immutable Hyperlinks as Unique Resource Identifiers (URI’s) to allow a consistent referenciation of resources with the ability to verify them with the AQP.

Success Criteria

A Immutable Hyperlink schema which links to a specific state of a resource. Instead of a stateless hyperlink we use verification_hash as a URI which acts as the checksum to verify the retrieved revision.

Input

  • file upload wizard is executed with file-data and description as input
  • file is stored with in the service triggering a hook leading to the calculation of
  • verification_hash (calculated with the file as input for content_hash) which is stored in the revision_object (file or database)

Output

When linking the file it’s displayed in the following format: [SHA3-512 Hash|Descriptor Text]

Boundary conditions

  • File is too big to be hashed. We support currently up to 50 MB.
  • File can’t be hashed for some reason (error during the process to due an unexpected code execution)
  • File is empty (has no content)

Implementation

We create Immutable Hyperlinks by moving from URL’s to sha3-512 hashes as URI’s. These URI’s are globally unique and therefore collision resistant as the namespace is sufficiently large. By using the hashes as links we also refer to the state of the resource. As the hash is the verification_hash of the resource it allows us to verify the integrity of the resource with it.

We are referring to files with their SHA3-512 hash in this format [SHA3-512|human_readable_filename]. Displayed is the human readable filename white it’s stored with the full SHA3-512 hash which allows us to be used as Immutable Hyperlinks.

To allow routing between resources we can add the <domain_id> as a prefix to the <verification_hash> resulting in the following syntax:

example: aqua://<domain_id>/<page_verification_hash>

Note: Implementatstion specific to aqua-PKC:

  • The verification_hash is stored in the content-slot ‘transclusion hashes’ with the internal links which referne the resource.