Atestaria Protocol
The HTTP of Trust — an open standard for digital content authenticity, integrity verification, and creator identity.
Spec v1.0 published. Reference implementation in this repo; live JSON metrics at /trust/stats.json; status at /status. Comments and PRs welcome at [email protected].
Protocol Overview
The Atestaria Protocol defines a universal standard for establishing, verifying, and communicating digital content authenticity. It enables any platform, application, or service to participate in a global trust network where content provenance is cryptographically provable and human identity is verifiable.
Unlike centralized content moderation systems, Atestaria operates as a decentralized protocol layer that any entity can implement. Content is anchored with quantum-safe cryptographic proofs, stored in immutable blockchain records, and linked to verified human identities through a multi-level authentication system.
Core Principles
Immutability
Once anchored, content records cannot be altered. Blockchain anchoring guarantees permanent provenance.
Source: /trust/stats.json (live anchor count)Openness
Open standard. Any platform can implement verification, any developer can build on top.
Source: /api-docs · openapi.jsonPrivacy
Zero-knowledge proofs allow verification without exposing sensitive content or personal data.
Source: /privacy · /zkpQuantum-Safe
ML-DSA-65 (CRYSTALS-Dilithium) signatures, NIST-standardized post-quantum scheme.
Source: NIST FIPS 204Human-Centric
Multi-level Human Authenticity Levels (HAL) prove real humans behind content.
Source: HAL spec · verifierInteroperable
W3C-compatible credentials, JSON-LD format, DID-based identities for cross-platform trust.
Source: W3C VC Data ModelContent Passport Standard
A Content Passport is a verifiable credential that binds a piece of digital content to its creator, timestamp, and integrity proof. It follows the W3C Verifiable Credentials Data Model and extends it with Atestaria-specific properties.
JSON-LD Schema
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://atestaria.com/context/v1"
],
"type": ["VerifiableCredential", "ContentPassport"],
"issuer": "did:veritas:{issuer_id}",
"issuanceDate": "2024-01-15T10:30:00Z",
"credentialSubject": {
"id": "did:veritas:{creator_id}",
"contentHash": "sha256:a1b2c3d4...",
"hashAlgorithm": "SHA-256",
"contentType": "image/png",
"anchorTimestamp": "2024-01-15T10:30:00Z",
"merkleRoot": "0xabcdef...",
"integrityProof": {
"type": "QuantumSafeSignature",
"algorithm": "ML-DSA-65",
"proofPurpose": "assertionMethod",
"verificationMethod": "did:veritas:{issuer_id}#key-1"
},
"humanVerification": {
"level": "HAL2",
"method": "biometric+behavioral",
"verifiedAt": "2024-01-10T08:00:00Z"
}
},
"proof": {
"type": "MerkleInclusionProof",
"created": "2024-01-15T10:30:01Z",
"merkleRoot": "0xabcdef...",
"blockchainAnchor": {
"network": "polygon:mainnet",
"transactionHash": "0x123...",
"blockNumber": 52341678
}
}
}Required Fields
| Field | Type | Description |
|---|---|---|
contentHash | string | SHA-256 hash of the original content, prefixed with algorithm |
hashAlgorithm | string | Algorithm used for hashing (SHA-256, SHA-3-256) |
anchorTimestamp | ISO 8601 | Timestamp when content was anchored in the protocol |
integrityProof | object | Cryptographic proof of content integrity |
issuer | DID | Decentralized Identifier of the issuing node |
Optional Fields
| Field | Type | Description |
|---|---|---|
humanVerification | object | HAL level and verification method of the creator |
contentType | MIME type | Media type of the original content |
merkleRoot | hex string | Root hash of the Merkle tree containing this content |
blockchainAnchor | object | On-chain anchor details (network, tx hash, block) |
metadata | object | Additional creator-defined metadata |
Trust Score Algorithm
The AtestariaScore is a composite reputation metric (0-1000) calculated from four independent dimensions, each contributing up to 250 points.
| Dimension | Max | Signals | Weight |
|---|---|---|---|
| Integrity | 250 | Content anchored count, revocation ratio, age of oldest anchor | 25% |
| Humanity | 250 | HAL level (HAL0=0, HAL1=80, HAL2=160, HAL3=250), verified links | 25% |
| Consistency | 250 | Regular activity frequency, content signing rate, dispute record | 25% |
| Community | 250 | Licenses sold, endorsements received, API integrations | 25% |
Score Formula
# AtestariaScore Calculation v1.0 function calculateAtestariaScore(profile): # Integrity (0-250) anchor_score = min(150, profile.anchor_count * 1.5) revocation_pen = profile.revocation_ratio * 50 age_bonus = min(50, days_since(profile.first_anchor) / 7) integrity = min(250, anchor_score - revocation_pen + age_bonus) # Humanity (0-250) hal_scores = {HAL0: 0, HAL1: 80, HAL2: 160, HAL3: 250} humanity = hal_scores[profile.hal_level] # Consistency (0-250) activity = min(100, profile.active_weeks * 10) signing_rate = profile.signed_ratio * 100 dispute_clean = 50 if profile.disputes_lost == 0 else 0 consistency = min(250, activity + signing_rate + dispute_clean) # Community (0-250) license_score = min(100, profile.licenses_sold * 5) endorsements = min(100, profile.endorsements * 10) api_bonus = min(50, profile.api_integrations * 25) community = min(250, license_score + endorsements + api_bonus) return integrity + humanity + consistency + community
Verification Flow
The complete verification process from content creation to public verification follows this flow:
┌────────────────┐
│ Content Creator │
│ uploads content │
└────────┬───────┘
│
▼
┌────────────────┐ ┌────────────────┐
│ SHA-256 Hash │ │ ML-DSA-65 │
│ Generation ├────┤ Quantum-safe │
└────────┬───────┘ │ Signature │
│ └────────┬───────┘
▼ │
┌────────────────┐ │
│ Merkle Tree │ │
│ Insertion ├──────────┘
└────────┬───────┘
│
▼
┌────────────────┐
│ Blockchain │
│ Anchor (Polygon) │
└────────┬───────┘
│
▼
┌────────────────┐
│ Content Passport │
│ Generated (W3C) │
└────────┬───────┘
│
▼
┌────────────────┐
│ Public │
│ Verification │
└────────────────┘
Verification Steps
- Content Hashing: The original content is hashed using SHA-256, producing a unique fingerprint
- Quantum-Safe Signing: The hash is signed using ML-DSA-65 (CRYSTALS-Dilithium), a NIST-standardized post-quantum signature scheme
- Merkle Tree: The signed hash is inserted into a Merkle tree for batch anchoring efficiency
- Blockchain Anchoring: The Merkle root is committed to Polygon mainnet, creating an immutable timestamp
- Passport Generation: A W3C Verifiable Credential (Content Passport) is generated with all proofs
- Public Verification: Anyone can verify by re-hashing content and checking against the blockchain anchor
API Standard
The Atestaria API follows RESTful conventions with JSON request/response bodies. All endpoints require API key authentication via the X-API-Key header.
Core Endpoints
Anchor new content. Submit a SHA-256 hash to create an immutable record with blockchain proof.
Verify content authenticity. Returns anchor details, creator info, and trust score.
Create a quantum-safe digital signature using ML-DSA-65 algorithm.
Retrieve the full Content Passport (W3C Verifiable Credential) for anchored content.
Batch anchor multiple content hashes in a single Merkle tree for efficiency.
Get the AtestariaScore breakdown for a creator profile.
Authentication
# All API requests require an API key GET /v2/verify/{hash} HTTP/1.1 Host: api.atestaria.com X-API-Key: vk_live_your_api_key_here Content-Type: application/json
Response Format
{
"success": true,
"data": {
"anchor_id": "anc_a1b2c3d4",
"content_hash": "sha256:...",
"verified": true,
"created_at": "2024-01-15T10:30:00Z",
"creator": {
"did": "did:veritas:creator123",
"trust_score": 847,
"hal_level": "HAL2"
},
"blockchain": {
"network": "polygon:mainnet",
"tx_hash": "0x..."
}
},
"meta": {
"request_id": "req_xyz",
"timestamp": "2024-01-15T10:35:00Z"
}
}Cryptography
Atestaria uses a layered cryptographic architecture designed for long-term security against both classical and quantum threats.
| Layer | Algorithm | Purpose | Security Level |
|---|---|---|---|
| Content Hashing | SHA-256 / SHA-3-256 | Content fingerprinting | 128-bit classical |
| Digital Signatures | ML-DSA-65 (Dilithium) | Quantum-safe content signing | NIST Level 3 |
| Merkle Trees | SHA-256 binary tree | Batch anchoring, inclusion proofs | 128-bit classical |
| Zero-Knowledge | ZK-SNARKs | Privacy-preserving verification | Computational |
| Key Derivation | HKDF-SHA256 | Deterministic key generation | 128-bit classical |
Why ML-DSA-65?
ML-DSA-65 (formerly CRYSTALS-Dilithium) is a NIST FIPS 204 standardized post-quantum digital signature algorithm. It provides security against attacks from both classical and quantum computers, with signature sizes of ~3.3 KB and public keys of ~1.9 KB — practical for real-world deployment.
Hybrid signatures — what we actually do today
To be honest about what is implemented in production right now:
- New proofs are hybrid by default. Every C2PA manifest, W3C Verifiable Credential 2.0, and audit-chain head we sign starting on this release carries both an Ed25519 (classical) and an ML-DSA-65 (post-quantum) signature over the same payload. The post-quantum public key is embedded in the proof so any third party can verify the PQ layer offline, without access to our KMS.
- Legacy proofs remain valid. Proofs issued before this release are signed only with Ed25519. Our verifier accepts them and clearly reports
signature_layers.post_quantum: "absent". They are not retroactively quantum-safe just because we shipped the code. - Re-anchoring is incremental. An admin job (
POST /admin/quantum/reanchor/run) walks legacy anchors and adds an ML-DSA-65 layer over the sameobject_hash. Coverage is reported atGET /admin/quantum/status. There is no mandatory cutover — operators choose the pace. - Anti-downgrade is enforced. When we sign in hybrid mode we commit a
pq_policy.required = truefield inside the signed payload (C2PA: top-levelpq_policy; VC 2.0:pqRequired: trueinside the classical proof options that the Ed25519 signature already covers). Stripping the PQ block from a hybrid proof on the wire flips verification tovalid: false— an attacker cannot silently force a legacy-looking result. - What survives a quantum break of Ed25519. If a future quantum attacker forges Ed25519 signatures, attribution to our KMS key is no longer guaranteed for proofs that lack the PQ layer. The OpenTimestamps + Bitcoin layer still proves the content existed at the time of anchoring, but the link to the signing identity must come from the PQ layer. That is exactly why we are migrating now.
Per-layer status in /v1/verify
The public verifier returns a signature_layers object on every response so callers can decide for themselves what they accept:
{
"valid": true,
"signature_layers": {
"classical": "ok", // Ed25519 — KMS-managed
"post_quantum": "ok", // ML-DSA-65 — FIPS 204
"bitcoin_ots": "ok", // OpenTimestamps anchored
"ai_declaration": "absent" // see below
},
"quantum_safe": true
}AI-source declaration (what we read, not what we detect)
When a C2PA manifest is presented for verification we extract any c2pa.actions with digitalSourceType of trainedAlgorithmicMedia, compositeWithTrainedAlgorithmicMedia, algorithmicMedia, or compositeWithAlgorithmicMedia — the standard C2PA way for a producer to declare AI involvement — plus any c2pa.training-mining assertion. We surface this verbatim under ai_declaration.
What this is not: we do not run a forensic AI-content classifier and we do not infer AI involvement when no declaration is present. ai_declaration: "absent" means exactly “the producer did not declare AI”, never “this content is human-made”. Any product copy claiming the opposite would be wrong; this protocol page is the source of truth.
Blockchain Anchoring
Content hashes are anchored to public blockchains to create tamper-proof timestamps. The protocol supports multiple chains through a chain abstraction layer.
Supported Networks
| Network | Status | Finality | Use Case |
|---|---|---|---|
| Polygon PoS | Production | ~2 seconds | Primary anchoring chain, low cost |
| Ethereum L1 | Planned | ~12 minutes | High-value content, maximum security |
| Base (L2) | Planned | ~2 seconds | Alternative L2 anchoring |
Merkle Batch Anchoring
To minimize on-chain costs, multiple content hashes are grouped into Merkle trees. Only the root hash is committed on-chain, while individual inclusion proofs are stored off-chain. This reduces costs by up to 1000x while maintaining the same security guarantees.
# Merkle Tree Batch Structure Root Hash → Anchored on-chain / \ Hash(AB) Hash(CD) / \ / \ H(A) H(B) H(C) H(D) ← Individual content hashes # Inclusion proof for content A: # [H(B), Hash(CD)] + position bits # Verifier reconstructs: Hash(Hash(H(A)||H(B)) || Hash(CD)) == Root
Interactive: Passport Viewer
📄 Live Content Passport Generator
Enter content details to generate a sample Content Passport in JSON-LD format.
Click "Generate Passport" to create a sample Content Passport...
Interactive: Trust Score Calculator
📈 AtestariaScore Calculator
Adjust the parameters to see how the trust score is calculated.
Integrity: 125 / 250 Humanity: 160 / 250 Consistency: 200 / 250 Community: 50 / 250 ──────────────────────── Total: 535 / 1000
Implementation Guide
Implementing the Atestaria Protocol in your application involves three core steps:
Step 1: Register as a Verifier
# Create a developer account and get API keys curl -X POST https://api.atestaria.com/v2/register \ -H "Content-Type: application/json" \ -d '{ "name": "My App", "website": "https://myapp.com", "plan": "starter" }' # Response includes your API key # { "api_key": "vk_live_...", "app_id": "app_..." }
Step 2: Anchor Content
import hashlib import requests # 1. Hash your content with open("photo.jpg", "rb") as f: content_hash = hashlib.sha256(f.read()).hexdigest() # 2. Anchor it response = requests.post( "https://api.atestaria.com/v2/anchors", headers={"X-API-Key": "vk_live_..."}, json={ "hash": content_hash, "content_type": "image/jpeg", "metadata": {"title": "My Photo"} } ) anchor = response.json() print(f"Anchored: {anchor['data']['anchor_id']}")
Step 3: Verify Content
// Verify any content against the protocol const response = await fetch( `https://api.atestaria.com/v2/verify/${contentHash}`, { headers: { 'X-API-Key': 'vk_live_...' } } ); const result = await response.json(); if (result.data.verified) { console.log('Content is authentic!'); console.log(`Creator: ${result.data.creator.did}`); console.log(`Trust Score: ${result.data.creator.trust_score}`); console.log(`Anchored: ${result.data.created_at}`); } else { console.log('Content not found in Atestaria'); }
SDKs & Libraries
Official SDKs are available to simplify integration with the Atestaria Protocol:
| Language | Package | Status | Install |
|---|---|---|---|
| Python | veritaschain | Stable | pip install veritaschain |
| JavaScript | @veritas/sdk | Stable | npm install @veritas/sdk |
| Go | go-veritas | Planned | — |
| Rust | veritas-rs | Planned | — |
from veritaschain import AtestariaClient client = AtestariaClient(api_key="vk_live_...") # Anchor content anchor = client.anchor( content_hash="sha256:abc123...", content_type="image/png" ) # Verify content result = client.verify("sha256:abc123...") print(result.verified) # True print(result.trust_score) # 847 print(result.passport) # Full Content Passport
Ready to build on Atestaria?
Get an API key and anchor your first content in minutes. Or read the live operational state at /trust before you commit.
Get API keys View Trust Center [email protected]