Skip to main content

Module zk_predicates

Module zk_predicates 

Source
Expand description

Zero-Knowledge predicate (threshold / range) proofs for the disclosure model’s PropertyProof modality.

This module lets a holder prove that a private value satisfies a public bound WITHOUT revealing the value — e.g. “age ≥ 18”, “balance ≥ min”, “score ∈ [lo, hi]”. The proofs are real Groth16 over BLS12-381 (arkworks 0.6), built on genuine R1CS constraints (bit-decomposition range checks), not a hash commitment. It is a sibling of crate::crypto::zk_proofs and reuses the same curve, RNG ([crate::zk_proofs::zk_secure_rng]), and serialization conventions (CanonicalSerialize / compressed bytes).

§How soundness is enforced (bit-decomposition)

To prove value >= threshold for value, threshold in a fixed bit-width N = 64, the circuit introduces a private witness diff = value - threshold and enforces, over the BLS12-381 scalar field Fr:

  1. value == threshold + diff (the definition of diff);
  2. diff == Σ_{i<N} b_i · 2^i, where each b_i is a boolean witness (b_i · (b_i − 1) == 0).

Constraint (2) proves diff is a non-negative N-bit integer, i.e. 0 <= diff < 2^N. Combined with (1) that gives value = threshold + diff >= threshold. If instead value < threshold, then over the field diff evaluates to value − threshold ≡ p − (threshold − value) (a number of order the field modulus p ≈ 2^255), which cannot be written as an N-bit sum for N = 64 — no boolean assignment b_i satisfies (2). Hence there is no satisfying witness and the honest prover simply cannot produce a proof: the < threshold case is unprovable, not merely rejected at verify time.

The range predicate lo <= value <= hi composes two such checks in one circuit: value − lo is a non-negative N-bit integer AND hi − value is a non-negative N-bit integer.

§Trusted setup model (honest limitation)

Groth16 requires a per-circuit trusted setup (a structured reference string). Like crate::crypto::zk_proofs and crate::crypto::deontic_circuit, this module performs a per-statement circuit_specific_setup: prove_threshold / prove_range run setup, prove, and bundle the verifying key with the proof (PredicateProof) so a verifier can check it standalone. The circuit shape is fixed (it depends only on N, never on the secret value), so the toxic-waste randomness of setup is the only trust assumption; the setup is not specialised to the secret. For a production deployment the VK for each predicate width would be generated once by a ceremony and pinned — factoring that ceremony out is a deployment concern, not a soundness gap in the circuit. The verify_* entry points take the public bound plus the PredicateProof (which carries the VK produced by that statement’s setup); they deserialize that bundled VK and check the proof against the supplied public input. Pinning a single ceremony-generated VK per predicate width, and rejecting proofs that ship any other VK, is the production hardening on top of this milestone.

Structs§

PredicateProof
A self-contained predicate proof: the compressed Groth16 proof plus the verifying key it was produced under (per-statement setup, see module docs). A verifier with only this struct and the public statement can check validity.
RangeStatement
Public statement for a range predicate: the prover asserts knowledge of a private value with lo <= value <= hi. lo and hi are the public inputs.
ThresholdStatement
Public statement for a threshold predicate: the prover asserts knowledge of a private value with value >= threshold. threshold is the sole public input.

Constants§

PREDICATE_BITS
Fixed bit-width for the range / threshold checks. Values and bounds must fit in u64; the bit-decomposition proves 0 <= diff < 2^64.

Functions§

prove_range
Prove, in zero knowledge, that a private value satisfies lo <= value <= hi.
prove_threshold
Prove, in zero knowledge, that a private value satisfies value >= threshold.
verify_range
Verify a PredicateProof produced by prove_range against public bounds lo and hi. Returns true iff valid for that exact [lo, hi] pair. Public inputs are supplied in the circuit’s allocation order [lo, hi].
verify_threshold
Verify a PredicateProof produced by prove_threshold against a public threshold. Returns true iff the proof is valid for that exact threshold — a proof made for one threshold does not verify against a different one.