--- id: CryptoBulletproofsRangeInterpolation language: en section: cryptography source: Verification/CryptoBulletproofsRangeInterpolation.lean source_sha256: 7e8e0bf03238d916c1a7eda2eeefec0b217e386909a993bd660268f2d091a8ac novelty: not-assessed status: reviewed --- # Bulletproofs range constraints from a finite interpolation grid [Section](../cryptography/README.md) · [Lean](../../Verification/CryptoBulletproofsRangeInterpolation.lean) ## Contract For prime q, n ≥ 1, FIXED a,b : Fin n → ZMod q and v : ZMod q, let y : Fin n → ZMod q and z : Fin 3 → ZMod q both be injective. Pointwise t0 a b (y i) (z j) = (z j)^2 * v + delta_fn (y i) (z j) n at every grid node implies formal_t0 a b = formal_rhs v n. The witness vectors do not vary between nodes; consistency of independently extracted vectors is not assumed to follow from interpolation. The residual is exactly F(Y,Z) = sum_i a_i*b_i*Y^i + Z*sum_i (a_i-b_i-1)*Y^i + Z^2*(sum_i 2^i*a_i-v). The module reuses t0_residual and formal_residual. Cubic Z terms cancel; the quadratic term remains. residual_poly_eval connects the nested polynomial with its scalar evaluation. residual_poly_degree_Z bounds the outer Z degree by two; residual_poly_degree_Y bounds the Y degree of every Z coefficient by n-1. NatDegree treats the zero polynomial as degree zero. These bounds imply the stated bidegree bounds for n ≥ 1. poly_coeff_zero_of_injective_grid uses the deterministic bound on the number of roots. quadratic_zero_of_three_points applies it to three coefficients. No Schwartz–Zippel probability or generator assumption is used. grid_card_bounds shows n ≤ q and 3 ≤ q from the injective grids. Zero nodes are allowed; distinct squares are not required (unlike the separate IPA extractor). grid_equalities_imply_formal_identity proves the main implication. grid_equalities_imply_field_range reuses formal_coefficients_imply_range to obtain a_i*b_i=0, a_i-b_i=1, a_i*(a_i-1)=0 and sum_i 2^i*a_i=v. The field has no zero divisors, so these imply each a_i is 0 or 1. grid_equalities_imply_natural_range reuses formal_identity_natural_range: for a natural v with v