mirror of
https://github.com/luxfi/p3q.git
synced 2026-10-30 15:22:47 +00:00
Replace the `not yet audit-gated` stub in verify_sha3/verify_keccak with
a real Fiat-Shamir-driven generic STARK / FRI low-degree verifier.
Wraps cleanly: AIR-specific Z-Chain circuit verifiers compose this
kernel and add their boundary/transition checks on top.
What lands
* wire.rs - canonical wire format v1 (10-byte header + public input +
trace root + FRI layer roots + final polynomial + per-query
openings). Every length/range/well-formedness check fires BEFORE
any crypto. Headers reject non-binary arities, out-of-range
log_blowup/log_degree_bound/num_queries/log_final_poly, reserved
bits, wrong version.
* transcript.rs - typed wrapper around p3q-challenger. Profile-keyed
customisation string (LUX-P3Q-V1-SHA3 / LUX-P3Q-V1-KECCAK) plus
per-observation tag prefixes (HEADER, PUBLIC-INPUT, TRACE-COMMIT,
FRI-COMMIT, FRI-FINAL, FRI-QUERY). Field-element squeezing uses
cSHAKE256 rejection sampling with a finite 32-iter cap.
* domain.rs - LDE-domain generator from Goldilocks 2-adicity (g=7),
binary FRI fold formula with two-test correctness proof, Horner
evaluation.
* verify.rs - the kernel: phase-1 transcript replay capturing per-
round fold challenges, phase-2 query-index re-derivation with echo
check, per-query trace+layer Merkle authentications, colinearity
check against folded carry, final-poly evaluation comparison. Every
failure mode maps to a precise P3qError variant - no unwrap, no
panic.
* prover.rs (feature `prover`) - minimal toy prover that produces
golden vectors. Used by in-crate roundtrip tests only; not in the
audited verifier compile graph.
* p3q-field: pow() and two_adic_generator() (g=7 quadratic non-
residue gives primitive 2^k-th roots up to k=32).
Verification properties tested
* sha3+keccak golden vectors verify (toy AIR: degree-16 poly, blowup
8, 16 queries, final poly of size 2)
* tampering rejected: profile byte swap, trace root bit-flip, FRI
layer root bit-flip, final-poly bit-flip, public-input bit-flip,
echoed query-index bit-flip (precise Transcript variant), arbitrary
per-query byte flip
* parsing rejects: short header, wrong version, non-binary arity,
log_final_poly >= log_degree_bound, reserved nonzero, truncated
body, trailing bytes, oversized Merkle path length
* never panics on random first-byte fuzz
* profiles do not cross-verify (cSHAKE customisation isolates them)
Golden vectors
vectors/p3q_v1_{sha3,keccak}_golden.{proof,public_input}.bin written
by the `write_golden_vectors` ignored test. `persisted_golden_vectors
_verify` reads them back and confirms acceptance - any wire-format
change forces a regen.
Verify wall-clock
Toy AIR (~30 KB proof): ~1 ms per verify in release on M2 Pro.
Workspace state
cargo fmt --check, cargo clippy --all-targets -- -D warnings, and
cargo test all clean. 87 tests passing (1 ignored vector writer).
scripts/lint_forbidden.sh clean (no bn254/kzg/groth16/blake3/poseidon
imports).
Out of scope for this commit
* AIR-specific Z-Chain circuits (boundary + transition constraints)
- p3q-zchain stays scaffolded, lands in v0.2.x
* recursive STARK composition - p3q-recursion stays scaffolded
* coset FRI / bit-reverse leaf permutation - dual-auth-path v1 wire
is intentionally simple; v2 can collapse to single path under
bit-rev