64 lines
6.0 KiB
Markdown
64 lines
6.0 KiB
Markdown
# AERE Verifiable Data
|
|
|
|
A dataset whose every answer can be checked against a short commitment, by anyone, without the data and without trusting the server.
|
|
Built from pieces that already exist beside it: the RFC 9162 Merkle tree of the verification layer (`verify-layer/arbore-merkle.mjs`),
|
|
the AIP-23 `data` envelope (`proof-kinds/`), the notary call of the agents (`agents/agent-ancora.mjs`) and the AIP-23 reference
|
|
verifier for the time of a version under a post-quantum certified anchor.
|
|
|
|
| what | how it is proven | with |
|
|
|---|---|---|
|
|
| a record is in the dataset at a version | inclusion proof in the version's log (RFC 9162, log2(n) hashes) | `verifica.mjs inregistrare` |
|
|
| a newer version only appended | consistency proof between the two log roots; the newer commitment names the older as `previous` | `verifica.mjs consistenta` |
|
|
| a query answer is correct AND complete | every row proves itself in the log and at its position in the SORTED index of the queried field; the rows are one contiguous run; the neighbour before the run is below the range and the one after is above it, each with its proof | `verifica.mjs raspuns` |
|
|
| a row reveals only what was asked | every field is committed as SHA-256(salt \| field \| value) in the record leaf; undisclosed fields stay hidden, disclosed ones cannot change | the same |
|
|
| the publisher serves what it committed to | availability sampling: random positions fetched and verified against the commitment; a withheld record fails the sample that lands on it | `verifica.mjs disponibilitate` |
|
|
| when a version existed | the commitment's AIP-23 envelope notarized on AereNotary and read back under a post-quantum certified anchor (`finality` of the reference verifier) | `verifica.mjs angajament --rpc` |
|
|
|
|
```
|
|
node vd.mjs creeaza ./set --nume users --index country,age
|
|
node vd.mjs adauga ./set records.ndjson # {"id":"u1","country":"RO","age":31,"email":"..."} per line
|
|
node vd.mjs angajeaza ./set --out c1.json # version 1: commitment + plicuri/1.json (its AIP-23 envelope)
|
|
node vd.mjs interogheaza ./set 1 --camp country --eq '"RO"' --campuri age --out a.json
|
|
node verifica.mjs raspuns a.json --angajament c1.json # VALID (n rows) | INVALID + reasons
|
|
node vd.mjs serveste ./set --port 8797 # GET /v1/vd/users/{commitments|record/1/7|query/1?field=age&from=30&to=40|consistency/1/2}
|
|
node verifica.mjs disponibilitate --url http://127.0.0.1:8797/v1/vd/users --angajament c1.json --esantioane 32
|
|
```
|
|
|
|
A commitment is `{ name, version, size, logRoot, indexes: { field: { root, size } }, createdAt, previous }`; its hash is the SHA-256 of its
|
|
canonical JSON, and that hash is the `sha256` of the version's `aere-proof-of-data` envelope. Records are flat JSON objects with a
|
|
string `id`; values are strings, finite numbers, booleans or null (an index needs a total order: by type, then numerically or by code
|
|
unit, in one function both sides use). A dataset appends; it never rewrites.
|
|
|
|
## What it is not, and what is not measured
|
|
|
|
- **Not zero knowledge.** Selective disclosure here is hash-based: the reader learns the disclosed values and the commitments of the
|
|
rest. A proof ABOUT rows without revealing them (a count, a sum, membership in a set, "some row satisfies P") needs a proving system;
|
|
the one this network verifies on chain (SP1, Groth16 over BN254) needs about 24 GiB to prove, measured 2026-09-26, and no such
|
|
circuit is built. Until it is, a "ZK query" is not offered, and this README says so instead of calling disclosure zero knowledge.
|
|
- **Completeness rests on the index being sorted.** A single answer proves its rows and its two neighbours against the committed index
|
|
root; that no matching row was omitted follows only if the index is in order, which the reader checks locally on the rows returned
|
|
(an unsorted pair is refused) and which anyone holding the data checks in full with `vd.mjs auditeaza`. A publisher that commits an
|
|
unsorted index is caught by the first answer that shows two rows out of order, or by an audit, not by a one-row answer.
|
|
- **Availability is retrievability under sampling, not a data-availability scheme.** k verified samples make a publisher that hides a
|
|
share s of its records survive with probability (1 - s)^k; there is no erasure coding and no network of samplers.
|
|
- **The time of a version is the chain's only when notarized**; an unnotarized commitment carries the publisher's `createdAt`.
|
|
- **Not storage.** The records live where the publisher keeps them (a folder here); this component commits, proves and serves, it does
|
|
not replicate, encrypt or back up.
|
|
- Index trees are rebuilt per version (sorted); consistency proofs cover the LOG only. Queries on fields that are not indexed are not
|
|
offered. Field values above 4096 characters, arrays and nested objects are refused.
|
|
|
|
## Probes
|
|
|
|
```
|
|
AERE_VERIFY_PROOF=<verify-proof.mjs from aere-node> node proba-verifiable-data.mjs # 23 rows: honest answers VALID, ten forged or malformed ones INVALID
|
|
# for their named reason, sampling on a local server
|
|
AERE_VERIFY_PROOF=... node proba-verifiable-data.mjs --control-negativ # 5 plantings on a copy of baza.mjs; each must make its
|
|
# forged fixture pass, which proves the check is load-bearing
|
|
AERE_VERIFY_PROOF=... AERE_NOTARY_KEY_FILE=<key> AERE_ETHERS_DIR=<dir with node_modules/ethers> node proba-verifiable-data.mjs --viu
|
|
# plus a notarization on testnet 28001 (a test key) read back
|
|
# under a post-quantum certified anchor; evidence in dovezi/
|
|
```
|
|
|
|
Without the AIP-23 verifier the envelope row is reported NEMASURAT and the exit code is 2. The probe never touches chain 2800; the notary
|
|
call refuses 2800 unless `AERE_CONFIRM_MAINNET=yes`.
|