{"id":341,"date":"2026-09-05T04:18:06","date_gmt":"2026-09-05T04:18:06","guid":{"rendered":"https:\/\/neodata.com.uy\/labs\/the-statement-must-enter-the-hash\/"},"modified":"2026-09-05T04:20:35","modified_gmt":"2026-09-05T04:20:35","slug":"the-statement-must-enter-the-hash","status":"publish","type":"post","link":"https:\/\/neodata.com.uy\/labs\/the-statement-must-enter-the-hash\/","title":{"rendered":"The statement must enter the hash."},"content":{"rendered":"<p><!--\nWORDPRESS CONTENT: editorial notes removed\n--><\/p>\n<p class=\"nlabs-kicker\">ZERO-KNOWLEDGE PROOFS<\/p>\n<h2 id=\"why-a-valid-proof-can-still-authorize-the-wrong-statement\">Why a valid proof can still authorize the wrong statement.<\/h2>\n<p>A zero-knowledge proof can be correct at the level of its algebra and wrong at the level of its application.<\/p>\n<p>The verifier may confirm that a prover knows a witness for a relation. If the relation omits a public value, accepts a non-canonical encoding or is bound to the wrong protocol context, the proof can establish something materially weaker than the application assumes.<\/p>\n<p>The difficult boundary is often not zero knowledge itself. It is the construction of the statement and the transcript that turns an interactive proof into a portable object.<\/p>\n<h2 id=\"commitment-challenge-response\">Commitment, challenge, response<\/h2>\n<p>A Sigma protocol commonly proceeds in three moves. The prover sends a commitment. The verifier returns a random challenge. The prover computes a response using the witness and the randomness used in the commitment.<\/p>\n<p>For suitable relations, this structure provides completeness, special soundness and honest-verifier zero knowledge. A verifier learns that the prover knows a witness without learning the witness itself.<\/p>\n<p>Interaction is inconvenient when a proof must be stored, forwarded or verified later. The Fiat-Shamir transformation replaces the verifier&#8217;s random challenge with the output of a cryptographic hash over the protocol transcript.<\/p>\n<h2 id=\"the-hash-becomes-the-verifier\">The hash becomes the verifier<\/h2>\n<p>Once the challenge is derived from a hash, the bytes absorbed by that hash define what the proof is bound to. This makes transcript construction a security boundary.<\/p>\n<p>A correct transcript normally includes the full public instance, every prover message in order, a protocol identifier and the contextual information required to separate this use from other uses of the same proof system.<\/p>\n<p>If an input is absent, the verifier&#8217;s challenge is independent of it. A malicious prover may then choose that input after learning the challenge and satisfy verification for a statement it never knew a witness for.<\/p>\n<h2 id=\"the-instance-is-not-the-witness\">The instance is not the witness<\/h2>\n<p>The witness is secret information whose knowledge is being demonstrated. The instance is the public description of the relation: public keys, commitments, group parameters, roots, limits or other values against which the witness is checked.<\/p>\n<p>Applications often pay close attention to hiding the witness and much less attention to constructing the instance. That asymmetry is dangerous. The proof system can only enforce the relation it receives.<\/p>\n<p>If a circuit proves that an amount lies in a range but the asset identifier is not bound into the statement, the proof may be reusable for another asset. If a proof of key possession omits the intended audience, it may be accepted in another protocol. Soundness does not repair missing semantics.<\/p>\n<h2 id=\"domain-separation-prevents-protocol-confusion\">Domain separation prevents protocol confusion<\/h2>\n<p>The same hash function, curve and proof machinery may be used by several applications. Without domain separation, a transcript created for one context can collide structurally with a transcript interpreted by another.<\/p>\n<p>A protocol tag should identify the construction and version. A session identifier can bind the proof to a deployment, role or interaction. These values need unambiguous length and encoding rules.<\/p>\n<p>Freshness is a separate requirement. A stable domain tag prevents cross-protocol confusion but does not prevent replay. A nonce, counter or session-specific challenge can make one proof unusable in a later ceremony.<\/p>\n<h2 id=\"serialization-is-part-of-the-proof-system\">Serialization is part of the proof system<\/h2>\n<p>The algebra operates on field elements and group points. Networks and storage operate on byte strings. The conversion between them must be canonical.<\/p>\n<p>A verifier should reject integers outside the permitted range, non-canonical field encodings, malformed points, wrong-subgroup elements, trailing bytes and inconsistent length prefixes. Accepting two encodings for one object can create transcript disagreement between components.<\/p>\n<p>This is the same general lesson explored in <a href=\"https:\/\/neodata.com.uy\/labs\/the-transcript-is-the-protocol\/\">The transcript is the protocol<\/a>: cryptography authenticates an exact representation, so representation rules belong inside the security argument.<\/p>\n<h2 id=\"randomness-reuse-can-reveal-the-witness\">Randomness reuse can reveal the witness<\/h2>\n<p>Zero knowledge depends on fresh prover randomness. In Schnorr-style proofs, reusing one commitment nonce across different challenges exposes enough linear information to recover the secret witness.<\/p>\n<p>Randomness failures can arise from snapshots, virtual-machine cloning, faulty deterministic derivation, concurrent access or restoration of an embedded device to an earlier state. The requirement is not merely a good random-number generator at manufacturing time. It is uniqueness and unpredictability across the complete lifecycle of the prover.<\/p>\n<p>The operational problem resembles <a href=\"https:\/\/neodata.com.uy\/labs\/a-nonce-is-not-a-footnote\/\">nonce management in authenticated encryption<\/a>, but the failure result is different: reuse can disclose the witness itself.<\/p>\n<h2 id=\"a-sequential-api-can-enforce-the-transcript\">A sequential API can enforce the transcript<\/h2>\n<p>An implementation that represents a proof as a freely mutable structure makes it easy to omit or reorder fields. A sequential transcript API can absorb and serialize each prover message in the same operation.<\/p>\n<p>This creates a useful invariant: if a value appears in the encoded proof, it has entered the hash in the prescribed position. End-of-input checks ensure that appended material is not ignored.<\/p>\n<p>Typed transcript methods can distinguish scalars, points, byte strings and length-delimited lists while still producing one canonical byte stream. The API becomes part of the implementation&#8217;s proof discipline.<\/p>\n<h2 id=\"the-circuit-can-be-underconstrained\">The circuit can be underconstrained<\/h2>\n<p>General proof systems add another boundary. A circuit or constraint system may fail to enforce that an internal value is Boolean, belongs to a range, corresponds to the public input or follows the intended state transition.<\/p>\n<p>The prover then supplies a witness that satisfies the written constraints but violates the intended computation. From the proof system&#8217;s perspective, nothing has failed. The wrong relation was proven correctly.<\/p>\n<p>Constraint review should therefore resemble protocol review. Each informal claim needs a traceable constraint, each public input needs an explicit binding and each conversion between native and foreign fields needs range analysis.<\/p>\n<h2 id=\"test-vectors-prove-only-the-honest-path\">Test vectors prove only the honest path<\/h2>\n<p>A positive test vector shows that one honestly generated proof verifies. It exercises completeness. It says little about rejection behaviour.<\/p>\n<p>A useful negative suite changes one element at a time:<\/p>\n<ul>\n<li>remove, repeat or reorder a prover message;<\/li>\n<li>alter each public input;<\/li>\n<li>change the protocol or session identifier;<\/li>\n<li>append and truncate encoded data;<\/li>\n<li>use non-canonical scalars and invalid points;<\/li>\n<li>reuse randomness across distinct statements;<\/li>\n<li>supply witnesses at every range boundary;<\/li>\n<li>prove against one version and verify against another.<\/li>\n<\/ul>\n<p>For a proof verifier, rejection tests are part of the conformance definition.<\/p>\n<h2 id=\"zero-knowledge-does-not-hide-the-statement\">Zero knowledge does not hide the statement<\/h2>\n<p>Zero knowledge means that the proof reveals nothing about the witness beyond what follows from the validity of the statement. The statement itself may reveal substantial information.<\/p>\n<p>A range proof reveals the range and usually the commitment being tested. A membership proof reveals the set or root. A proof bound to a stable public key can be linkable. A proof whose generation time depends on secret data can leak through side channels.<\/p>\n<p>Privacy analysis must therefore include public inputs, metadata, timing and repeated use. The adjective does not exempt the protocol from data minimization.<\/p>\n<h2 id=\"prove-the-intended-statement\">Prove the intended statement<\/h2>\n<p>The decisive question for an implemented proof is not whether the verifier returned true. It is what exact statement that result represents.<\/p>\n<p>The instance, protocol context, message order, canonical encoding and proof-system version must all enter the transcript. The prover&#8217;s randomness must remain fresh. The verifier must reject malformed inputs before evaluating the relation.<\/p>\n<p>A proof can reveal nothing about its witness and still authorize the wrong action. The statement must enter the hash because the statement is what the system intends to trust.<\/p>\n<hr \/>\n<h2 id=\"references\">References<\/h2>\n<ol type=\"1\">\n<li><a href=\"https:\/\/datatracker.ietf.org\/doc\/draft-irtf-cfrg-sigma-protocols\/\">CFRG: Sigma Proofs for Linear Relations<\/a><\/li>\n<li><a href=\"https:\/\/datatracker.ietf.org\/doc\/draft-irtf-cfrg-fiat-shamir\/\">CFRG: Fiat-Shamir Transformation<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/mmaker\/draft-irtf-cfrg-sigma-protocols\">Reference drafts and implementation material<\/a><\/li>\n<li><a href=\"https:\/\/solana.com\/news\/post-mortem-may-2-2025\">Solana: ZK ElGamal Proof Program post-mortem<\/a><\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>A zero-knowledge proof can verify correctly while authorizing the wrong statement. Fiat-Shamir security begins with the exact public instance, transcript order and domain separation absorbed by the hash.<\/p>\n","protected":false},"author":2,"featured_media":340,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[],"nlabs_article_type":[],"class_list":["post-341","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-research"],"_links":{"self":[{"href":"https:\/\/neodata.com.uy\/labs\/wp-json\/wp\/v2\/posts\/341","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/neodata.com.uy\/labs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/neodata.com.uy\/labs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/neodata.com.uy\/labs\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/neodata.com.uy\/labs\/wp-json\/wp\/v2\/comments?post=341"}],"version-history":[{"count":1,"href":"https:\/\/neodata.com.uy\/labs\/wp-json\/wp\/v2\/posts\/341\/revisions"}],"predecessor-version":[{"id":345,"href":"https:\/\/neodata.com.uy\/labs\/wp-json\/wp\/v2\/posts\/341\/revisions\/345"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/neodata.com.uy\/labs\/wp-json\/wp\/v2\/media\/340"}],"wp:attachment":[{"href":"https:\/\/neodata.com.uy\/labs\/wp-json\/wp\/v2\/media?parent=341"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/neodata.com.uy\/labs\/wp-json\/wp\/v2\/categories?post=341"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/neodata.com.uy\/labs\/wp-json\/wp\/v2\/tags?post=341"},{"taxonomy":"nlabs_article_type","embeddable":true,"href":"https:\/\/neodata.com.uy\/labs\/wp-json\/wp\/v2\/nlabs_article_type?post=341"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}