Signed commitments are not zero-knowledge proofs (and why mine are actually stronger for my use case)
There is a specific framing error that I want to address directly, because it has come up in several conversations since we started talking about the substrate publicly and because it is the kind of error that costs you credibility with anyone who knows the di
There is a specific framing error that I want to address directly, because it has come up in several conversations since we started talking about the substrate publicly and because it is the kind of error that costs you credibility with anyone who knows the distinction.
The error is this: describing the substrate as a "zero-knowledge proof" or as "FHE and ZK-STARKs merged" or as "cryptographic proof that the computation happened correctly." Each of those phrasings is technically wrong in a way that a working cryptographer will spot in about four seconds, and each of those errors is correctable by understanding what the substrate actually is. The substrate is a signed commitment. It is not a zero-knowledge proof. These are two genuinely different cryptographic objects, with different security properties, different verification procedures, different cost profiles, and different use cases. Conflating them is a common mistake, and the substrate's actual design benefits from being precise about the distinction.
This post is the precision. I want to walk through what a signed commitment is, what a zero-knowledge proof is, how they differ, why I sometimes hear the two conflated, and why — for the specific attestation use case the substrate targets — being a signed commitment rather than a zero-knowledge proof is actually the stronger choice.
What each object is, precisely
A signed commitment is a cryptographic object consisting of: (1) a commitment to some data, typically a hash of the data under a collision-resistant hash function, and (2) a digital signature over the commitment, produced by a key holder whose public key is known to the verifier. The verifier of a signed commitment holds the signed object (the commitment plus the signature), the signer's public key, and the data whose commitment is being verified. The verifier then: (a) recomputes the commitment from the data, (b) verifies the signature against the recomputed commitment using the public key, and (c) accepts if both succeed.
The security property of a signed commitment is: a verifier who accepts a signed commitment has cryptographic evidence that the specific data was endorsed by the holder of the signing key, and that the endorsement has not been tampered with. The security argument reduces to the unforgeability of the signature scheme (under chosen-message attack) and the collision resistance of the hash function. A signed commitment does not tell the verifier anything about whether the data is "correct" in any semantic sense. It only tells the verifier that the signer vouched for this specific data. The signer could have vouched for incorrect data, and the signed commitment would still verify.
A zero-knowledge proof is a cryptographic object that allows a prover to demonstrate a statement about a computation to a verifier without revealing the witness that makes the statement true. In the typical formulation, the statement is something like "there exists some input x such that f(x) = y" where f is a public function and y is a public output. The prover produces a proof that they know an x that satisfies the relation, and the verifier checks the proof against (f, y) alone — without ever learning x. The security properties are soundness (a false statement cannot be proved) and zero-knowledge (the proof reveals nothing about x beyond the fact that x exists).
The security property of a zero-knowledge proof is: a verifier who accepts a zero-knowledge proof has cryptographic evidence that the statement is true — that there really does exist some witness x such that f(x) = y — regardless of who produced the proof. The prover cannot cheat, because if x did not exist, no valid proof could be produced (by soundness). The prover does not need to be trusted in the way a signer needs to be trusted, because the proof's validity is a property of the mathematical statement, not of the prover's identity.
These are, at a structural level, very different objects.
A signed commitment says: a specific known party vouched for this specific data. The evidence comes from the signer's key custody.
A zero-knowledge proof says: this mathematical statement is true, and I can demonstrate it without telling you the witness. The evidence comes from the mathematical structure of the proof system.
If you swap one for the other in a sentence, you get a sentence that is probably either nonsensical or wrong. "The substrate is a zero-knowledge proof that the computation happened correctly" is wrong because the substrate does not prove anything about the computation's correctness — it signs a hash of the computation's output. "The substrate is a signed commitment that reveals nothing about the computation's witness" is wrong because the substrate does not hide anything — the commitment is a hash of the output, and anyone with the output can compute the hash. The two security properties are orthogonal.
The family resemblance that causes confusion
People confuse signed commitments with zero-knowledge proofs because there is a family resemblance between them, in a few specific ways that I want to call out so you can pattern-match on them.
Both produce small outputs. A signed commitment is typically a few hundred bytes at most (the commitment plus the signature). A zero-knowledge proof, in modern SNARK constructions, is also typically a few hundred bytes to a few kilobytes. When you see a small cryptographic object that somehow "proves" or "attests" something about a much larger computation, it is natural to lump signed commitments and zero-knowledge proofs into the same mental category. The categories are different, but the resemblance in size is real.
Both are verifiable locally. A signed commitment can be verified by the recipient using only the signer's public key and the data. A zero-knowledge proof can be verified by the recipient using only the proof, the public function f, and the public output y. Both objects support verification that does not require interaction with the original producer. The locality of verification is a shared property.
Both provide protection against forgery. A signed commitment cannot be forged without the signer's private key (under the signature scheme's unforgeability assumption). A zero-knowledge proof cannot be forged without actually knowing a witness that satisfies the statement (under the proof system's soundness assumption). "Cannot be forged" is a shared property, but the mechanisms that prevent forgery are different: one relies on key custody, the other relies on mathematical structure.
Both have cryptographic security arguments. Both objects come with formal security arguments that reduce their security to standard cryptographic assumptions. The assumptions are different — signature schemes rely on signature-specific hardness, ZK proofs rely on proof-system-specific hardness — but the family of "object with a cryptographic security argument" is the same family.
These shared properties are why the conflation is common. They are not reasons to conflate the objects. The shared properties are surface-level; the structural differences are deep.
The differences that matter
Here is where the substrate's choice to be a signed commitment rather than a zero-knowledge proof actually matters, for the specific attestation use case.
Trust in the prover vs. trust in the system. A zero-knowledge proof does not require trust in the prover. The proof's validity is a mathematical property of the proof system, and any prover who produces a valid proof has, in fact, demonstrated the statement. A signed commitment does require trust in the signer. The commitment's validity is a property of the signer's key custody — if you do not trust the signer to have signed the right thing, the commitment is useless.
For the substrate's use case, this difference cuts in our favor. The substrate is being used to attest who produced a computation result, under what circumstances, at what time. The whole point of the attestation is that the signer's identity matters. A regulated financial institution is saying, "I, Acme Corp, computed this credit score on this encrypted input at this time, using my signing keys that are provisioned inside my Trusted Execution Environment and which nobody outside Acme Corp has access to." The verifier of this attestation wants to know that Acme Corp specifically signed the substrate. They do not want a proof that some generic prover computed the score correctly — they want to know that Acme Corp vouches for the score.
A zero-knowledge proof would actually be the wrong tool for this use case. A ZK proof that "the credit score was computed correctly on encrypted input" tells you that the computation was executed per some specification, but it does not tell you who executed it or whether that party vouches for the result. You would need an additional signed wrapper on top of the ZK proof to tie it to a specific prover's identity, and at that point you have built a signed-commitment-over-a-ZK-proof, which is strictly more complex than just signing the result directly.
For use cases where trust in the prover is not desired — say, a privacy-preserving election where the voter wants to prove their ballot is counted without revealing their identity — a zero-knowledge proof is the right tool because the prover's identity is explicitly what you are hiding. For use cases where the signer's identity is part of the value proposition, a signed commitment is correct.
Cost of producing the object. Signed commitments are cheap to produce. Even the substrate's three-family bundle, which signs with three post-quantum signature algorithms in parallel, takes approximately 5.5 milliseconds of CPU time per signing event. Zero-knowledge proofs are expensive to produce. A modern SNARK for a nontrivial circuit takes seconds to minutes of prover time, even on specialized hardware, and the time grows with the circuit size. For applications that need high-throughput attestation — millions of events per hour, or more — the prover cost of a ZK-based approach becomes the bottleneck.
The substrate's target applications include workloads where millions of attestations per hour is the baseline expectation. At that scale, a ZK-based approach is not viable without either very specialized hardware (TPUs, FPGAs, ASICs specifically for proving) or very aggressive batching. The signed-commitment approach runs on any commodity CPU with post-quantum signing libraries installed and hits the throughput target without specialized hardware.
Cost of verifying the object. ZK proofs have very cheap verification costs — a modern SNARK verifier is a few milliseconds regardless of the circuit size being proved. Signed commitments have slightly higher verification costs, dominated by the signature verification (for the substrate's three-family bundle, approximately 593 microseconds of wall-clock time for a full local verification including SHA3 recomputation and receipt structural checks). For use cases where verification happens many more times than production — say, every block of a blockchain has to re-verify every transaction — the less expensive verification of ZK proofs can be a real advantage.
For the substrate's use case, verification is expected to be occasional, not continuous. A substrate is produced once, verified once or a few times by parties that care (the customer, a regulator, an auditor), and retained indefinitely. The verification cost is amortized across the retention period, and 593 microseconds per verification is fine. If we were building a consensus system where every node has to re-verify every object on every block, we would probably want a proof with less expensive verification.
Post-quantum readiness. Modern zero-knowledge proof systems are mostly pairing-based (Groth16, KZG, Plonk) or hash-based (STARK). The pairing-based systems rely on elliptic-curve hardness assumptions that are broken by Shor's algorithm and are therefore not post-quantum secure. The hash-based systems (STARKs) are post-quantum secure under the pre-image resistance of their underlying hash function, but they produce significantly larger proofs than pairing-based systems (tens to hundreds of kilobytes instead of kilobytes) and have higher proving costs.
If you want a post-quantum zero-knowledge proof, you are choosing among STARK-family constructions or more experimental lattice-based proof systems. The substrate's choice to be a signed commitment rather than a ZK proof is, in part, a choice to avoid the cost and complexity of a post-quantum proof system in favor of the less expensive and simpler three-family signed commitment. This choice is not available to systems that actually need zero-knowledge properties; they have to pay the cost. But for the substrate's use case, we do not need zero-knowledge, and choosing to not need it gives us significant cost and simplicity advantages.
Size on the wire. Signed commitments have a known size — they are as large as the signature bundle requires. For the substrate, the ephemeral signature bundle is approximately 21 kilobytes (dominated by SLH-DSA-SHA2-128f at 17 KB), and the persistent committed form via the compact receipt is 42 bytes. Zero-knowledge proofs have a known size too, but the size depends on the proof system: a Groth16 proof is about 192 bytes, a Plonk proof is a few kilobytes, a STARK proof can be tens to hundreds of kilobytes depending on the circuit size.
For the substrate's target workloads, the 42-byte persistent footprint of the compact receipt is a key property, and it is achievable because we are compressing a signed commitment (specifically, hashing the signature bundle and storing only the hash). A ZK proof with an equivalent ~42-byte persistent footprint is possible but requires either a pairing-based system (not post-quantum) or significantly more proving-time infrastructure (recursive STARK composition to compress a proof-of-a-proof down to small size).
"But what about correctness?"
A legitimate objection at this point is: a signed commitment doesn't prove the computation happened correctly. A ZK proof does prove the computation happened correctly. Isn't that a strictly stronger property?
It is a stronger property for some use cases, yes, but for the attestation use case it is subtly the wrong property.
Here is the subtlety. "The computation happened correctly" is a statement about a specific mathematical relation between the input and the output. A ZK proof that "f(x) = y" tells you that some input x satisfies f(x) = y. It does not tell you which x. For a deterministic function f, knowing that x exists is enough; for the substrate's use case, we typically also want to know what x was. We want to say, "the institution produced this credit score for this specific customer's financial history," not "the institution produced some credit score for some financial history that satisfies the scoring function."
You can build a ZK proof that reveals x (that is, a ZK proof without the zero-knowledge property, which is just a non-interactive proof) and that would give you what you want. But at that point you have dropped the zero-knowledge property and are left with a proof-of-computation, which is a different object from a zero-knowledge proof. A proof-of-computation has its own cost profile (expensive proving, cheap verifying) and is still a fundamentally different object from a signed commitment.
A signed commitment tells you: "the signer vouches that this output corresponds to this input, and anyone who trusts the signer's key custody can rely on this." The vouching chain is: input → canonical encoding → SHA3-256 hash → substrate's fhe_commitment field → signing message → three-family signature bundle → verifier's trust in the signer. The integrity of the chain is what the verifier checks. If the signer's key custody is compromised, the chain is broken, but the specific chain-break is: an adversary got the signing keys, not an adversary got a way to compute the wrong output. This is a narrower attack surface than "an adversary can produce a different output from the same inputs," and it is the attack surface the substrate's three-family structure is specifically designed to harden against.
For the attestation use case, the right question is: do I trust the signer to have executed the computation correctly? If yes, a signed commitment is exactly what you need — it binds the signer's trust to the specific output. If no, a signed commitment is not what you need — you need a proof-of-computation, and the signed commitment adds no value.
Most of the substrate's real applications are in the "yes, I trust the signer" category. A regulated financial institution runs its own fraud model and signs the output; you trust the institution to execute its own model correctly, and you want cryptographic evidence that the output came from them and not from an adversary. A biometric authentication service runs its own matching algorithm and signs the result; you trust the service to execute correctly, and you want evidence that the result is theirs. A media capture device signs the raw sensor data in firmware; you trust the firmware (which is a trust assumption about the device manufacturer), and you want evidence that the capture came from this specific device.
In all of these cases, a signed commitment is the right object. You are not trying to eliminate trust in the signer — you are trying to make the signer's vouching legible and forge-resistant. A signed commitment does exactly that.
For the minority of cases where you need to eliminate trust in the signer, you need a proof-of-computation (ZK or otherwise). Those cases exist, and they are legitimate use cases, but they are not what the substrate is optimized for.
Why being a signed commitment is actually stronger for our use case
I titled this post "Signed commitments are not zero-knowledge proofs (and why mine are actually stronger for my use case)." The "actually stronger" part is the argument I want to land.
For the substrate's specific use case — attesting who produced a computation, under what circumstances, for what purpose, at what time — a signed commitment is not just different from a zero-knowledge proof. It is strictly better in several ways that matter for the use case:
1. The signer's identity is preserved, which is the whole point. A signed commitment ties the attestation to a specific signer whose public key set is known. A ZK proof abstracts away the prover's identity, which is the wrong tradeoff for an attestation that is specifically about who did the computation.
2. The cost structure matches the throughput target. Millions of attestations per hour is feasible on commodity CPUs with signed commitments. Proving a ZK proof for every attestation is not feasible at that throughput without specialized hardware.
3. The persistent footprint is smaller. A signed commitment with the substrate's compact-receipt distillation is 42 bytes persistent, plus 32 bytes for the content hash = 74 bytes total persistent footprint. Post-quantum ZK proofs are larger (STARK proofs are tens of kilobytes at best). For use cases that anchor to blockchains or storage-expensive environments, the smaller footprint is a direct cost advantage.
4. The security argument is simpler. A signed commitment's security reduces to the unforgeability of the signature scheme and the collision resistance of the hash function. A ZK proof's security reduces to whatever the underlying proof system's assumptions are (pairing-based, hash-based, lattice-based, each with its own set of assumptions). Simpler security arguments are easier to defend in front of skeptical reviewers, and the substrate's three-family-signed argument is about as simple as a post-quantum security argument can get.
5. The upgrade path is clearer. Rotating to a stronger signature family is a localized change in the signer's implementation. Rotating to a stronger ZK proof system is a much more disruptive change that affects the entire proof-producing and proof-verifying infrastructure.
6. The implementation is deployable today. Signed-commitment infrastructure with NIST-standardized post-quantum signatures is deployable on commodity hardware with commodity libraries. Post-quantum ZK proof systems are still in active research in several parts of the stack and have fewer battle-tested implementations.
For the attestation use case, all six of these properties favor the signed-commitment approach. This is why the substrate is a signed commitment and not a ZK proof, and why I push back firmly when anyone describes it as "a ZK proof of FHE computations" or similar phrasing. The description is wrong, and the correct description is not just technically accurate — it is the description that makes the substrate's actual strengths legible.
When you actually do want a ZK proof
To be fair to zero-knowledge proofs, here are the use cases where they are the right tool and the substrate is not.
Privacy-preserving identity. A user wants to prove they are over 18 without revealing their birthday. This requires zero-knowledge: the user must prove the statement (age > 18) without revealing the witness (the actual age). A signed commitment cannot do this, because signing the user's actual age and handing it to the verifier is exactly what the user is trying to avoid.
Trustless computation outsourcing. A cloud service is paid to run some computation, and the customer wants cryptographic evidence that the service actually ran the computation correctly without having to trust the service. This requires a proof-of-computation, which can be a ZK proof or a non-ZK proof depending on privacy requirements. A signed commitment by the service does not help because the whole point is to eliminate trust in the service.
Blockchain rollups. An L2 wants to commit a batch of L1 transactions via a single compressed proof that the verifier (the L1 smart contract) can check cheaply. ZK rollups use ZK proofs for this. Optimistic rollups use fraud proofs instead. A signed commitment by the rollup operator is not sufficient because the point of the rollup is to avoid trusting the operator.
Private set membership. A user wants to prove they are in some set (a voter roll, a membership list) without revealing which member they are. This requires zero-knowledge, and the substrate cannot do it.
Anonymous credentials. A user wants to prove they hold a credential issued by some authority, without revealing which specific credential or who the authority is. Same reason — zero-knowledge is required.
For all of these use cases, the substrate is not the right tool. We are not trying to cover them. The substrate is optimized for a different pattern, where the signer's identity is known and valuable, the computation is expensive, the throughput target is high, and the persistent footprint needs to be small. For that pattern, signed commitments win.
Closing
The substrate is a signed commitment. Not a ZK proof. Not "FHE and ZK-STARKs merged." Not "a cryptographic proof that the computation happened correctly." It is a signed commitment to a computation result, signed under a three-family post-quantum signature bundle, committed down to a 42-byte compact receipt for persistent storage.
This choice is deliberate. It is not a limitation we could not overcome; it is the right object for the use case we are targeting. Signed commitments are not weaker than ZK proofs — they are different objects with different properties, and for the specific attestation pattern we are optimizing, they are strictly stronger along the axes that matter: cost, throughput, persistent footprint, signer identity, deployability.
If you are building something where you genuinely need the ZK property — where you need to eliminate trust in the prover, where you need to hide the witness — the substrate is not the right tool, and no amount of reframing makes it the right tool. Use a ZK proof system for that. Plenty of good ones exist.
If you are building something where you have a specific signer whose identity matters, whose key custody you trust, whose computations you want to commit to in a forge-resistant way, and where you want the cryptographic object to be small and deployable at high throughput on commodity hardware — the substrate is for you. The fact that it's a signed commitment and not a ZK proof is the feature, not the limitation.
The next post in this series is about the 1,239× memory reduction we measured in the substrate's admission sketch cache, and why a Count-Min Sketch construction with constant memory footprint is the right structure for cache admission decisions at scale. See you there.
Build with the H33 Substrate
The substrate crate is available for integration. Every H33 API call now returns a substrate attestation.
Get API Key Read the Docs