What ZecTime proves
ZecTime proves that a private artifact existed before a confirmed Zcash height. It does not store the file, does not publish the raw hash, and does not require the verifier to trust the server after the receipt exists.
Generate ZK Receipt
Generation is designed to feel like a simple stamper: choose file, anchor commitment, download receipt.
- 01
Local hash in the browser
The browser computes the file SHA-256 digest and splits it into two 128-bit halves. The file never needs to leave the client.
- 02
Blind commitment
The client samples a 128-bit nonce and computes Poseidon(domain, hash_lo, hash_hi, nonce). The server receives only the commitment.
- 03
Orchard anchor
The backend uses zallet to publish the commitment in an Orchard memo and waits for txid + confirmed height.
- 04
Local bundle
The holder downloads the public receipt and keeps the private opening with the original file.
Receipt model
The split between public receipt and private opening is the core privacy boundary. Share the public receipt; reveal the opening only when you need to prove the file.
| Field | Visibility | Purpose |
|---|---|---|
txid | Public | Locates the Zcash transaction that carries the Orchard memo. |
network | Public | Prevents verifying mainnet, testnet, or regtest in the wrong place. |
commitment | Public | Blind Poseidon value published on-chain. |
block_height | Public | Canonical timestamp: the artifact existed before this block. |
document_size_bytes | Private/local | Helps local audit and UX without proving content by itself. |
nonce + doc_hash_sha256 | Private | Opening used to recompute the commitment and bind the receipt to the file. |
Verify ZK Receipt
Verification separates the chain check from the document check. That keeps the server away from the file and private opening.
- 01
Load receipt
The verifier accepts a public receipt, private opening, or legacy bundle and extracts txid when present.
- 02
Fetch chain
The API fetches the transaction by txid, reads the Orchard memo, and compares commitment + height against the public receipt.
- 03
Optional local re-hash
If the original file is provided in the UI, the browser recalculates SHA-256 locally and recomputes the commitment with the opening.
- 04
Auditable result
The verifier shows whether the anchor exists, whether the receipt matches the chain, and whether the file matches the private opening.
API surface
The API publishes and fetches commitments. The document and opening stay in the browser by design.
| Endpoint | Input | Output |
|---|---|---|
POST /api/timestamps/stamp | { commitment } | { anchor: { txid, network, block_height, commitment } } |
POST /api/timestamps/fetch | { txid, receiptJson? } | { artifact, documentVerification: null } |
Browser verifier | file + private opening + public receipt | documentVerification computed locally |
When documentVerification is null in the API response, that is intentional: file verification runs client-side to preserve privacy.
Privacy model
ZecTime optimizes for proof of existence without reusable public fingerprints.
- The chain sees txid, height, and commitment; it does not see the file, raw SHA-256, or nonce.
- The server receives only the commitment during generation and txid/public receipt during verification.
- The document hash is computed in the browser and only appears in the holder's private opening.
- A verifier learns the opening only if the holder chooses to disclose it.
Comparison with Bitcoin/OpenTimestamps and dcrtime
The fair claim is not that ZecTime replaces every system in every dimension. The gain is default file-fingerprint privacy.
| Model | Anchor | Privacy | Verification |
|---|---|---|---|
| OpenTimestamps / Bitcoin | Calendars aggregate timestamps and anchor them into Bitcoin. | Hashing can happen in the browser; the proof revolves around digest/Bitcoin attestation. | Strong independent verification through OTS clients and Bitcoin. |
| Decred dcrtime | Hashes enter a Merkle root and are anchored into Decred. | Transparent hash/Merkle-path model, good for public audit trails. | Client checks Merkle path, txid, and chain timestamp. |
| ZecTime | Blind Poseidon commitment goes into a Zcash Orchard memo. | The raw hash never becomes public data; the opening stays with the holder. | Public chain check + local document check when the holder reveals the opening. |
Mainnet operations
The web service needs zallet configured to publish real anchors. Without it, the UI can still compute local commitments but cannot issue final receipts.
- ZALLET_RPC_URL and ZALLET_FROM_ADDRESS must be set in the web service environment.
- The server must be able to call z_sendmany and then fetch the confirmed transaction.
- RPC failures should show as clear operational errors, not invalid receipts.
- For high-value evidence, wait for more confirmations before treating the timestamp as final.
External references
These docs follow the practical shape of existing timestamp systems, while the privacy model is ZecTime-specific.