Quitanza

The transparency log

Every quitanza this deployment issues is hashed into an append-only Merkle log. The log's head, its size and root hash, is signed by the active issuer key and served publicly. Anyone can ask for proof that a particular quitanza is in the log, and proof that today's log is an extension of the log from any earlier day.

Why a log

A quitanza already verifies on its own: the signature either checks out against the issuer's published key or it does not. The log answers a harder question: what if the key itself comes into question later?

Key rotation does not revoke. A retired key stays published so its proofs keep verifying, which also means anyone who ever obtained that private key could mint proofs that verify against the old era. The log is the answer. A quitanza whose hash sits in a log head that was checkpointed at the time has a position in a history that cannot be rewritten: forging a proof afterwards would require either rewriting the log, which consistency proofs make evident, or appending a new leaf, which is visible. Possession of a proof plus its inclusion in a checkpointed log survives later questions about the key.

The same property serves audits. An enterprise that checkpoints the head once a day holds, in a few hundred bytes, a commitment to every settlement that existed by that day, and can later demand proof that nothing behind a checkpoint changed.

The endpoints

All three are public: no key, no account, rate limited per client.

Route Returns
GET /v1/log/head { logSize, rootHash, signedAt, signature }, signed by the active issuer key.
GET /v1/log/proof/{quitanzaId} { quitanzaId, leafIndex, leafHash, path }: the audit path to the root.
GET /v1/log/consistency/{first}/{second} { firstSize, secondSize, firstRoot, secondRoot, path }. Omit second for the current size.

Verifying

The SDK ships the offline helpers:

import { Quitanza, verifyQuitanzaInclusion, verifyLogConsistency } from "@quitanza/sdk";

const qz = new Quitanza({ baseUrl, apiKey });
const head = await qz.log.head();           // checkpoint this somewhere yours
const proof = await qz.log.inclusion(quitanza.id);
verifyQuitanzaInclusion(quitanza, proof, head);   // { valid: true }

// Later: did the log only grow?
const newer = await qz.log.head();
const consistency = await qz.log.consistency(head.logSize);
verifyLogConsistency(head, consistency, newer);   // { valid: true }

The CLI does the whole inclusion check in one command:

quitanza log verify <quitanzaId> --domain quitanza.com

--domain additionally checks the head's signing key against the issuer keys the domain publishes at /.well-known/quitanza-issuer.json.

The mechanics

The log follows RFC 6962 shapes. The leaf for a quitanza is SHA-256(0x00 || canonical JSON of the full document); interior nodes are SHA-256(0x01 || left || right). Domain separation between leaves and nodes means a leaf can never impersonate a subtree. The exact algorithms, with the signed head's body, are specified in the quitanza format.

A note on trust: the head is signed by the same issuer that signs quitanzas, so the log is the issuer's own account of its history, made tamper-evident. The strength comes from checkpoints held outside the log: once anyone holds yesterday's head, today's log must answer to it.

This page as markdown