Signing once a day instead of 700,000 times
The obvious version of our signing design needed around 700,000 hardware signatures a month. Batching them into a daily Merkle root brought it to roughly 100, with the customer-side guarantee unchanged.
Every operation Lethra performs produces a receipt. A store, an event bound to a deposit, a retrieval, a forget. Each receipt has to be signed by hardware that a customer can verify independently, because a receipt signed by software we control is a receipt that establishes nothing to anyone who does not already trust us.
The obvious implementation signs each receipt as it happens. We costed that first, because it is the design you reach for before you think about it, and the number is instructive.
The number that forced a redesign
At the volume we expect across a modest partner base, the four operation types generate on the order of 700,000 signing operations a month.
Hardware security modules are not priced for that pattern. A dedicated pair — you want a pair, because a single one is a single point of failure for the thing your entire evidence story rests on — runs to roughly €2,400 a month at the cloud providers. Call it €28,800 a year before any other infrastructure is switched on, for a pre-revenue company, to sign receipts most of which nobody will ever look at.
The cost was not the only problem. Per-operation hardware signing puts a network round trip to a security appliance in the critical path of every write. It makes the appliance a availability dependency for the entire API. And it scales linearly with traffic in a way that makes growth a cost conversation rather than a good thing.
So the design question became: can we get the same guarantee to the customer while touching the hardware far less often. The answer is yes, it is well established outside our corner of the market, and it took most of the design effort in this area.
What the customer actually needs
It helps to be precise about the guarantee, because the naive design over-delivers on it in a way that costs money without adding value.
What a customer needs to be able to demonstrate is: this receipt, for this specific document, is genuine, was issued at the time it claims, and has not been altered since.
Note what that does not require. It does not require that a hardware module performed a cryptographic operation at the exact moment the receipt was issued. It requires that the receipt is bound, by mathematics rather than by assertion, to something a hardware module did vouch for — and that the binding cannot be forged or retroactively adjusted.
That distinction is the entire opening.
The batched design
Through the day, operations are signed in software with a short-lived key. The key exists only in locked memory, is never written to disk, and is destroyed when the day ends. A customer gets their receipt immediately, with no hardware round trip in the request path.
At 02:00 UTC, every operation from that day is assembled into a Merkle tree.
A Merkle tree is a hash tree: the leaves are hashes of individual items, each internal node is the hash of its two children, and the root is a single value that depends on every leaf. Change any leaf and the root changes. The useful property is that you can prove a specific leaf is included in the tree by revealing only the sibling hashes along the path from that leaf to the root — a handful of values, regardless of how many leaves the tree has.
The hardware key store signs that root. Once.
It also issues one certificate stating that the day's software key was valid for that day, and that everything the software key signed is anchored to that root. Two hardware operations for a full day of traffic.
Add key rotation and the per-forget operations that genuinely cannot be batched — destroying a key has to happen when it happens — and the monthly total lands around 100 hardware operations instead of 700,000.
Why the guarantee survives
Walk the verification path from the customer's side and nothing is weaker than in the naive design.
They hold a receipt, signed by the day key. They check that signature against the day certificate. The day certificate is signed by the hardware key store, whose public key is published. They obtain an inclusion proof showing that their receipt's hash, combined with the sibling hashes, produces the published root for that day. That root is signed by the same hardware key.
Every link is cryptographic. At no point does the customer have to trust an assertion from us, and at no point does the fact that the immediate signature came from software rather than hardware create an opening — because the software key is itself scoped and vouched for by hardware, for one calendar day, and everything it signed is committed to a root that hardware attested.
Two further properties close the remaining gaps. The roots are hash-chained: each day's root incorporates the previous day's, so a fabricated historical entry would break every root after it rather than just one. And the root is anchored to a timestamp from an independent authority, which means we cannot backdate a root even if we wanted to — the anchoring establishes that the root existed no later than a particular moment, and it establishes it to a party with no relationship to us.
Where the pattern comes from
None of this is our invention, and saying so is a feature rather than modesty.
Certificate Transparency has used exactly this structure since the mid-2010s to keep public certificate authorities honest — append-only logs, Merkle roots, inclusion proofs, published for anyone to check. Sigsum applies the pattern to signed artefacts with a deliberately minimal trust model. Rekor, in the software supply chain world, does the same for build provenance.
Borrowing a pattern auditors already recognise is worth considerably more to us than novelty would be. When someone's security reviewer asks what our tamper-evidence design is, the useful answer is the same one as Certificate Transparency, applied to documents — because that answer terminates the conversation in a way that a clever original design never would, however good it was.
The trade-off, stated rather than buried
The hard anchor arrives up to twenty-four hours after the receipt does.
A customer who stores a document at 09:00 has a verifiable receipt immediately, signed by that day's key. What they do not have until the following morning is the inclusion proof tying it to a hardware-signed root. For that window, the receipt's strength rests on the day key certificate and on the audit log, rather than on the full chain.
We document this rather than bury it, for two reasons. The first is that a vendor who volunteers their design's weakest property is easier to believe about its strongest ones. The second is that the window genuinely does not matter for the use case: court-ready bundles are assembled deliberately and slowly, and nobody who needs one needs it within a day of the document arriving. If your use case does require sub-daily anchoring, this design is the wrong one and we would rather establish that early.
What it cost to get here
Roughly €28,800 a year, avoided, for the same customer-side guarantee. For a company at our stage that is not a rounding error, and the alternative use of that money is the external security testing and the legal work that the product will need before anyone's real documents are in it.
The upgrade path stays open. If a compliance review later demands a specific hardware assurance level that our current key store does not meet, the signing interface is deliberately narrow — one function that takes bytes and returns a signature — so the backend can be swapped without touching anything above it. Key rotation already happens daily as a matter of course, which turns that migration into one more iteration of a procedure that runs constantly, rather than a project.