AMATELUS Protocol Spec

13 Merkle Revocation and Verification Freshness

Definition 25
#

A Merkle inclusion proof establishes membership in an issuer-authenticated active-credential snapshot. It does not by itself establish current validity.

13.1 Architecture and Responsibility

Issuers publish signed active-credential roots. Holders prove membership within ZKP without disclosing the credential leaf or path. Verifiers authenticate the snapshot and report its age; services decide whether that evidence is adequate. The protocol imposes no universal age or version-lag acceptance window. Individual issuers may issue non-revocable claims; that signed capability must remain distinguishable from a revocable credential whose status was not checked.

13.2 Signed Snapshot

SignedSnapshot:
  issuer, statusSeries, merkleRoot, version
  statusAsOf, validUntil, issuerSignature

All fields above are one canonically encoded signature payload. statusAsOf is when the issuer confirmed the represented state, not when someone downloaded it. Versions are ordered only within the same issuer and status series. validUntil indicates the normal update/expiry boundary; passing it does not make an authentic signature a forgery.

The Leaf identifies the original signed claim or credential according to the issuance profile. Extraction and repackaging must preserve that reference. A full-VC leaf requires proof of membership of the extracted claim in that original VC. A per-claim leaf includes the original signed claim conditions. Outer holder signatures cannot change the original revocation capability, expiry or delegation.

13.3 Merkle Tree Construction

13.3.1 Hash Function

  • SHA-256: Merkle Tree construction (ZKP circuit compatible)

  • SHA3-512: Other purposes (quantum safe)

13.3.2 Tree Construction Algorithm

Input: activeVCHashes = [h_1, h_2, ..., h_n]
Output: merkleRoot

Algorithm:
  1. Padding (adjust to power of 2)
     if n not power of 2:
       pad with H("") until next power of 2

  2. Level 0 (leaves)
     leaves = activeVCHashes + padding

  3. Upward computation
     while len(leaves) > 1:
       new_level = []
       for i in range(0, len(leaves), 2):
         parent = SHA-256(leaves[i] || leaves[i+1])
         new_level.append(parent)
       leaves = new_level

  4. Return root
     return leaves[0]

13.3.3 Merkle Proof Generation

Input:
  - vcHash (VC to prove)
  - activeVCHashes (all active VCs)
  - merkleRoot (for verification)

Output: MerkleProof

Algorithm:
  1. Find VC position
     leafIndex = activeVCHashes.indexOf(vcHash)
     if leafIndex == -1: return None

  2. Collect proof path
     siblingHashes = []
     currentIndex = leafIndex
     currentLevel = activeVCHashes + padding

     while len(currentLevel) > 1:
       siblingIndex = currentIndex XOR 1
       siblingHashes.append(currentLevel[siblingIndex])
       currentIndex = currentIndex / 2
       currentLevel = computeParentLevel(currentLevel)

  3. Return proof
     return MerkleProof {
       leafIndex,
       siblingHashes,
       treeDepth = log_2(paddedLeafCount)
     }

13.3.4 Merkle Proof Verification

Input:
  - vcHash (VC to verify)
  - proof (MerkleProof)
  - merkleRoot (expected root)

Output: Bool

Algorithm:
  1. Start from leaf
     currentHash = vcHash
     currentIndex = proof.leafIndex

  2. Compute to root
     for siblingHash in proof.siblingHashes:
       if currentIndex % 2 == 0:
         currentHash = SHA-256(currentHash || siblingHash)
       else:
         currentHash = SHA-256(siblingHash || currentHash)
       currentIndex = currentIndex / 2

  3. Compare with root
     return currentHash == merkleRoot

13.4 Circuit and Verification Contract

The circuit verifies the original claim signature and trusted provenance, subject/presentation binding, expiry, delegation scope, and status references. If status is checked, it computes the original leaf and verifies its Merkle path against the exact public root. The verifier additionally authenticates the issuer, series, version and signed time associated with that root. Public inputs are cryptographically bound to the verified proof, not independent display fields.

VerificationObservation:
  proofValid
  statusAtSnapshotActive
  statusAsOf: optional timestamp
  snapshotAgeSeconds: optional integer
  snapshotExpired: optional boolean
  currentStatus: unknown | confirmedRevoked
  newerAuthenticatedSnapshotKnown
Acceptance = verifier_policy(observation)

The implementation also retains root/version/issuer/series provenance for each observation. Multiple original claims and delegations yield multiple observations; none may be hidden by an aggregate label of "latest".

13.5 Verifier Processing

  1. Verify signatures, attribute predicates, subject relationships and the expected presentation context. An invalid cryptographic proof fails even in emergency mode.

  2. For a status-checking presentation, authenticate the snapshot and require the proof’s root and version to match it. Reject mismatched metadata.

  3. Calculate age from the signed statusAsOf only when the verifier’s clock is trusted. An unavailable clock or unsupported future timestamp gives unknown freshness; a profile may specify a bounded clock skew.

  4. Report whether the normal validUntil boundary has passed. Do not replace this fact with an unconditional protocol rejection.

  5. Retain the newest authenticated snapshot per issuer/series. An older presentation must not overwrite it. A newer root without an updated inclusion proof means insufficient current evidence, not confirmed individual revocation.

  6. Preserve individually confirmed revocation. Old positive evidence never clears that fact. Absence or failure of a membership proof alone cannot establish an individual credential’s current revocation.

  7. Apply the service policy and record the decision separately from these facts. Policies may tighten or relax freshness requirements without changing cryptographic verification results.

For example, if root v100 was published at 10:00, a credential revoked at 10:10 may still have a correct proof against v100 at 10:11. A new session challenge does not update that state snapshot. The result is "active at 10:00; current status unknown", unless separately authenticated individual revocation is known.

13.6 Offline and Disaster Operation

Both old-snapshot and no-snapshot presentations are supported. With no root, verify the original signature, attributes and presentation binding using a status-unchecked proof profile. Report statusAsOf = none and currentStatus = unknown. Do not rewrite the issuer-signed revocationEnabled flag to false to enable this route.

A verifier may grant an emergency exception even where normal policy would refuse service. It must retain the stale/unknown/confirmed-revoked state and record that business exception separately. Neither cached roots nor atomic online issuance guarantees immediate revocation or global uniqueness while offline.

13.7 Lean Model and Limits

verifyZKPWithRevocation returns an observation, and acceptByRevocationPolicy applies a separate policy. Signature and proof verification are supplied as explicit verifier callbacks; their soundness and binding to the supplied payload are implementation obligations. retainNewerSnapshot models monotonic authenticated state per series.

The membership types and proof-generation helpers are abstract models, not production Merkle algorithms or circuits. The theorem invalid_membership_cannot_generate_zkp assumes an invalid proof against its particular root. It does not state that an already revoked credential cannot prove membership in any historical root. Field checks and type-tag checks must not be described as a proof of protocol-wide cryptographic security.

13.8 Acceptance Criteria

Test authentic old roots, absent roots, stale downloads, modified signed times, wrong roots/versions, unknown clocks, future times, known newer roots and confirmed individual revocation. Test normal and emergency policies against the same immutable observations. Authenticate input before updating cached state, keep series separate and ensure old evidence cannot roll back known facts.