§ 02.01
Wire format.
Every entry is a tuple (header, payload). The header is a 131-byte canonical record (RFC-EPH-003); the payload is opaque bytes addressed by BLAKE3-256.
pub type EntryHeader = {
payload_cid: bytes32, // blake3(payload)
prev_hash: bytes32, // blake3(prior header)
seq: uint64,
ts_ms: uint64,
tier: Tier, // T0..T4
sig_scheme: Scheme, // Ed25519 | Falcon1024
signer_id: bytes32, // HATP host key id
reserved: bytes[14], // zero
} § 02.02
Hash chain.
Each header references the BLAKE3 hash of its predecessor via prev_hash. The chain is therefore tamper-evident: any modification of entry n invalidates the hash of every subsequent entry. Verification walks the chain in O(N).
Periodic Merkle checkpoints (RFC-EPH-004) produce an O(log N) inclusion proof: a verifier can prove entry x is at position y in epoch z with a path of roughly ⌈log₂ N⌉ hashes.
§ 02.03
Tier parameters.
A tier is a triple (retention, anchoring, signature). Promotion is non-destructive: it adds a checkpoint and re-anchors. Demotion crypto-shreds while preserving the integrity path.
pub type TierSpec = {
retention_ms: uint64, // 0 = unbounded
anchor_policy: AnchorPolicy,
sig_scheme: Scheme,
store_class: StoreClass,
}
pub const T0 = TierSpec {
retention_ms = 60_000,
anchor_policy = NoAnchor,
sig_scheme = Ed25519,
store_class = InMemoryOnly,
}
pub const T3 = TierSpec {
retention_ms = 189_345_600_000, // ~6 years
anchor_policy = MerklePeriodic { every_ms = 3_600_000 },
sig_scheme = Falcon1024,
store_class = Durable,
} § 02.04
Anchoring — for timestamps, not settlement.
Batched Merkle roots are committed to a chosen public chain solely for tamper-proof timestamping. Ephernity issues no token; transfers no value on-chain; settles nothing. The anchor is a notary, not a settlement layer.
The default anchor is Bitcoin via OpenTimestamps (max neutrality, low cost, high latency); operators may select a low-cost L2 or an EU-public option (e.g. EBSI) per tier (RFC-EPH-007).
§ 02.05
HATP attestation.
The Hardware-Attested Trust Protocol is a three-level key delegation: root → tenant → host. The root key is rotated on a slow schedule and protected in an HSM. The tenant key is issued per customer/jurisdiction. The host key is bound to a measured-boot attestation of the KVM guest that performs signing.
A verifier with the root public key alone can validate any entry's signature chain offline (RFC-EPH-005).
§ 02.06
Verification.
fn verify_range(entries: [Entry], root_pk: HATPRoot) -> Result[(), Error] {
let mut prev = ZERO_HASH;
for e in entries {
// 1. hash chain
if e.header.prev_hash != prev { return Err(ChainBroken); }
let h = blake3_header(e.header);
// 2. content address
if blake3(e.payload) != e.header.payload_cid { return Err(CidMismatch); }
// 3. signature
let pk = hatp_verify_chain(e.header.signer_id, root_pk)?;
verify_sig(e.header.sig_scheme, pk, h, e.signature)?;
prev = h;
}
Ok(())
} The verifier needs only the entries (or a checkpoint plus an inclusion proof) and the root public key. No network access. No trusted middlebox. No tokens.
§ 02.07
Contract dialect — the compute pillar.
Sections 02.01–02.06 specify the storage pillar — what an entry is, how a ledger holds them, and how a verifier checks them. The compute pillar specifies what runs on top: a deterministic contract dialect whose every step reads from and writes to the same kind of ledger.
A contract is an actor: a piece of code with persistent state and message handlers. The dialect interface restricts the runtime so that replay reproduces every result exactly. Three constraints define it:
- No ambient inputs. A handler reads only the prior state and the inbound message; the wall-clock, the network, and the host environment are not visible.
- Seeded randomness. Any randomness is derived deterministically from the inbound message and a per-contract seed committed at instantiation.
- Total commitment. Inputs, prior-state hash, code revision, and outputs are all committed to a ledger entry. Replay re-executes against the committed inputs and compares the output hash.
pub interface Contract {
// The whole environment of a step. No wall-clock, no network,
// no unsanctioned randomness. Same input → same output.
fn step(
prior_state: State, // commit on the state-ledger
message: Message, // commit on the input-ledger
env: DeterministicEnv,
) -> Result[StepOutput, Error]
}
pub type StepOutput = {
next_state: State,
response: Response,
receipts: list[LedgerReceipt], // every emit is a ledger entry
} Per-call accounting (the unit of work, its inputs, its outputs) is part of the protocol; the price attached to a unit is a deployment concern and lives outside the spec. The reference contract surface is written in Borz; other dialects can conform if they preserve the interface and the ledger commitments. The relevant RFCs are RFC-EPH-CMP-000 (overview), CMP-001 (dialect), CMP-002 (ledger-backed state), and CMP-003 (per-call accounting).
§ 02.08
Non-goals.
- ─ Not a blockchain. No global consensus, no native currency, no on-chain "smart contract" VM. The anchor is a clock, not a settlement layer.
- ─ Not a storage market. No node-reward economics, no instrument at the wire. Operators run the substrate; users pay operators for hosting, or self-host.
- ─ Not a custodial trust anchor. The protocol is verifiable offline against the root public key; trust in the operator is required for availability, not for integrity.
- ─ Not a retention loophole. Per-entry crypto-shred is structural; deletion of personal data is a first-class operation at every tier.
- ─ Not an execution monopoly. The contract dialect is an interface; any runtime that preserves the interface and the ledger commitments can host conforming contracts.