1- //! Example: ZK sumcheck using the public VEIL interface .
1+ //! Example: random-opening "protocol" for a committed MLE, run against two backends .
22//!
3- //! Demonstrates the full prove/verify flow:
4- //! 1. Generate a random MLE and compute its hypercube sum
5- //! 2. Prover sends sumcheck messages via `SendingCtx`
6- //! 3. Verifier reads and checks via `ReadingCtx` + compiler `SumcheckParam`
3+ //! This is the degenerate terminal case of a veil protocol: nothing is really being
4+ //! reduced — we just commit an MLE, sample a random point, open at that point, and
5+ //! discharge the resulting evaluation claim via the primitive `ctx.assert_mle_eval`.
6+ //! Effectively a PCS smoke test.
7+ //!
8+ //! The protocol is written once, generically over `SendingCtx` / `ReadingCtx`, then
9+ //! run first with the zero-knowledge backend (`ZkProverCtx` / `ZkVerifierCtx`) and
10+ //! afterwards with the transparent backend (`TransparentProverCtx` /
11+ //! `TransparentVerifierCtx`).
12+ //!
13+ //! Shape:
14+ //!
15+ //! - `mle_eval_read` / `mle_eval_prove`: mirror entry points — one reads the
16+ //! transcript on the verifier side, the other commits + samples + sends on the
17+ //! prover side. Both return an [`MleEvalView`].
18+ //! - `mle_eval_build_constraints`: the shared constraint-building pass used by both
19+ //! sides.
720
821use rand:: SeedableRng ;
922use rand_chacha:: ChaCha20Rng ;
@@ -12,77 +25,118 @@ use slop_koala_bear::KoalaBearDegree4Duplex;
1225use slop_merkle_tree:: Poseidon2KoalaBear16Prover ;
1326use slop_multilinear:: { Mle , Point } ;
1427use slop_veil:: compiler:: { ConstraintCtx , ReadingCtx , SendingCtx } ;
28+ use slop_veil:: transparent:: {
29+ initialize_transparent_prover_and_verifier, TransparentProverCtx , TransparentVerifierCtx ,
30+ } ;
1531use slop_veil:: zk:: stacked_pcs:: { initialize_zk_prover_and_verifier, StackedPcsZkProverCtx } ;
1632use slop_veil:: zk:: { compute_mask_length, ZkProverCtx , ZkVerifierCtx } ;
1733
1834type GC = KoalaBearDegree4Duplex ;
35+ type F = <GC as IopCtx >:: F ;
1936type MK = Poseidon2KoalaBear16Prover ;
2037
2138const LOG_NUM_POLYNOMIALS : u32 = 8 ;
2239const NUM_ENCODING_VARIABLES : u32 = 8 ;
2340const NUM_VARIABLES : u32 = LOG_NUM_POLYNOMIALS + NUM_ENCODING_VARIABLES ;
2441
25- fn read < C : ReadingCtx > ( ctx : & mut C ) -> ( C :: MleOracle , Point < C :: Challenge > , C :: Expr ) {
26- let p_oracle = ctx. read_oracle ( NUM_ENCODING_VARIABLES , LOG_NUM_POLYNOMIALS ) . unwrap ( ) ;
27- let point = ctx. sample_point ( NUM_VARIABLES ) ;
28- let eval = ctx. read_one ( ) . unwrap ( ) ;
29- ( p_oracle, point, eval)
30- }
42+ // ============================================================================
43+ // Generic protocol code
44+ // ============================================================================
3145
32- fn build_constraints < C : ConstraintCtx > (
33- ctx : & mut C ,
34- p_oracle : C :: MleOracle ,
46+ struct MleEvalView < C : ConstraintCtx > {
47+ oracle : C :: MleOracle ,
3548 point : Point < C :: Challenge > ,
36- eval : C :: Expr ,
37- ) {
38- ctx. assert_mle_eval ( p_oracle, point, eval) ;
49+ claimed_eval : C :: Expr ,
3950}
4051
41- fn main ( ) {
42- let mut rng = ChaCha20Rng :: from_entropy ( ) ;
52+ /// Verifier-side entry point: read the committed oracle, sample the opening point,
53+ /// and read the prover's claimed evaluation out of the transcript.
54+ fn mle_eval_read < C : ReadingCtx > ( ctx : & mut C ) -> MleEvalView < C > {
55+ let oracle = ctx. read_oracle ( NUM_ENCODING_VARIABLES , LOG_NUM_POLYNOMIALS ) . unwrap ( ) ;
56+ let point = ctx. sample_point ( NUM_VARIABLES ) ;
57+ let claimed_eval = ctx. read_one ( ) . unwrap ( ) ;
58+ MleEvalView { oracle, point, claimed_eval }
59+ }
4360
44- // Generate a random MLE
45- let p = Mle :: < <GC as IopCtx >:: F > :: rand ( & mut rng, 1 , NUM_VARIABLES ) ;
61+ /// Prover-side entry point: commit `mle`, sample the opening point, compute the
62+ /// evaluation, send it on the transcript, and return the matching [`MleEvalView`]
63+ /// for the caller to feed into [`mle_eval_build_constraints`].
64+ fn mle_eval_prove < C , RNG > ( ctx : & mut C , mle : Mle < C :: Field > , rng : & mut RNG ) -> MleEvalView < C >
65+ where
66+ C : SendingCtx ,
67+ RNG : rand:: CryptoRng + rand:: Rng ,
68+ rand:: distributions:: Standard : rand:: distributions:: Distribution < C :: Field > ,
69+ {
70+ let oracle =
71+ ctx. commit_mle ( mle. clone ( ) , LOG_NUM_POLYNOMIALS , rng) . expect ( "failed to commit mle" ) ;
72+ let point = ctx. sample_point ( NUM_VARIABLES ) ;
73+ let eval = mle. eval_at ( & point) . evaluations ( ) . as_slice ( ) [ 0 ] ;
74+ let claimed_eval = ctx. send_value ( eval. into ( ) ) ;
75+ MleEvalView { oracle, point, claimed_eval }
76+ }
4677
47- let mask_length = compute_mask_length :: < GC , _ > ( read , | ( p_o , point , eval ) , ctx| {
48- build_constraints ( ctx , p_o , point , eval )
49- } ) ;
50- eprintln ! ( "Mask length: {}" , mask_length ) ;
78+ /// Shared constraint-building pass used by both sides.
79+ fn mle_eval_build_constraints < C : ConstraintCtx > ( view : MleEvalView < C > , ctx : & mut C ) {
80+ ctx . assert_mle_eval ( view . oracle , view . point , view . claimed_eval ) ;
81+ }
5182
52- let ( pcs_prover, verifier) = initialize_zk_prover_and_verifier ( 1 , NUM_ENCODING_VARIABLES ) ;
83+ fn main ( ) {
84+ let mut rng = ChaCha20Rng :: from_entropy ( ) ;
5385
54- // === PROVER ===
55- eprintln ! ( "\n === PROVER ===" ) ;
56- let proof = {
57- eprintln ! ( "Proving..." ) ;
58- let mut ctx: StackedPcsZkProverCtx < GC , MK > =
59- ZkProverCtx :: initialize_with_pcs_only_lin ( mask_length, pcs_prover, & mut rng) ;
86+ let p = Mle :: < F > :: rand ( & mut rng, 1 , NUM_VARIABLES ) ;
6087
61- // Commit to p
62- let commit =
63- ctx. commit_mle ( p. clone ( ) , LOG_NUM_POLYNOMIALS , & mut rng) . expect ( "failed to commit" ) ;
64- // Get a random point
65- let point = ctx. sample_point ( NUM_VARIABLES ) ;
88+ // ZK backend.
89+ eprintln ! ( "\n === ZK BACKEND ===" ) ;
90+ let ( zk_pcs_prover, zk_pcs_verifier) =
91+ initialize_zk_prover_and_verifier ( 1 , NUM_ENCODING_VARIABLES ) ;
6692
67- let eval = p. eval_at ( & point) [ 0 ] ;
68- let eval = ctx. send_value ( eval) ;
93+ let zk_proof = {
94+ let now = std:: time:: Instant :: now ( ) ;
95+ let mask_length = compute_mask_length :: < GC , _ > ( mle_eval_read, mle_eval_build_constraints) ;
96+ eprintln ! ( "Mask length: {mask_length}" ) ;
6997
70- ctx. assert_mle_eval ( commit, point, eval) ;
98+ let mut pctx: StackedPcsZkProverCtx < GC , MK > =
99+ ZkProverCtx :: initialize_with_pcs_only_lin ( mask_length, zk_pcs_prover, & mut rng) ;
100+ let view = mle_eval_prove ( & mut pctx, p. clone ( ) , & mut rng) ;
101+ mle_eval_build_constraints ( view, & mut pctx) ;
102+ let proof = pctx. prove ( & mut rng) ;
71103
72- let proof = ctx. prove ( & mut rng) ;
73- eprintln ! ( "Proving complete" ) ;
104+ eprintln ! ( "Prover time: {:?}" , now. elapsed( ) ) ;
105+ proof
106+ } ;
107+ {
108+ let mut vctx = ZkVerifierCtx :: init ( zk_proof, Some ( zk_pcs_verifier) ) ;
109+ let view = mle_eval_read ( & mut vctx) ;
110+ mle_eval_build_constraints ( view, & mut vctx) ;
111+ vctx. verify ( ) . expect ( "zk verification failed" ) ;
112+ }
113+ eprintln ! ( "ZK backend: PASSED" ) ;
114+
115+ // Transparent backend.
116+ eprintln ! ( "\n === TRANSPARENT BACKEND ===" ) ;
117+ let ( stacked_prover, stacked_verifier) = initialize_transparent_prover_and_verifier :: < GC , MK > (
118+ 1 ,
119+ NUM_ENCODING_VARIABLES ,
120+ LOG_NUM_POLYNOMIALS ,
121+ ) ;
122+
123+ let transparent_proof = {
124+ let now = std:: time:: Instant :: now ( ) ;
125+ let mut pctx: TransparentProverCtx < GC , MK > =
126+ TransparentProverCtx :: initialize ( stacked_prover) ;
127+ let view = mle_eval_prove ( & mut pctx, p. clone ( ) , & mut rng) ;
128+ mle_eval_build_constraints ( view, & mut pctx) ;
129+ let proof = pctx. prove ( & mut rng) . expect ( "transparent prove failed" ) ;
130+ eprintln ! ( "Prover time: {:?}" , now. elapsed( ) ) ;
74131 proof
75132 } ;
76-
77- // === VERIFIER ===
78- eprintln ! ( "\n === VERIFIER ===" ) ;
79133 {
80- let mut ctx = ZkVerifierCtx :: init ( proof, Some ( verifier) ) ;
81- // Verifier reads from transcript and builds constraints
82- let ( p_oracle, point, eval) = read ( & mut ctx) ;
83- build_constraints ( & mut ctx, p_oracle, point, eval) ;
84- ctx. verify ( ) . expect ( "verification failed" ) ;
134+ let mut vctx = TransparentVerifierCtx :: < GC > :: new ( transparent_proof, Some ( stacked_verifier) ) ;
135+ let view = mle_eval_read ( & mut vctx) ;
136+ mle_eval_build_constraints ( view, & mut vctx) ;
137+ vctx. verify ( ) . expect ( "transparent verification failed" ) ;
85138 }
139+ eprintln ! ( "Transparent backend: PASSED" ) ;
86140
87- eprintln ! ( "\n === PASSED ===" ) ;
141+ eprintln ! ( "\n === ALL PASSED ===" ) ;
88142}
0 commit comments