Skip to content

Commit 29e38a4

Browse files
committed
back to the verifier
1 parent 8fcd809 commit 29e38a4

File tree

15 files changed

+137
-53
lines changed

15 files changed

+137
-53
lines changed

Cargo.lock

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ rand_core = "0.6"
6161
rand_xorshift = "0.3"
6262
rayon = "1.10"
6363
secp = "0.4.1"
64-
serde = { version = "1.0", features = ["derive"] }
64+
serde = { version = "1.0", features = ["derive", "rc"] }
6565
serde_json = "1.0"
6666
strum = "0.26"
6767
strum_macros = "0.26"

ceno_zkvm/src/instructions.rs

+5
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@ where
9999
unimplemented!();
100100
}
101101

102+
// Returns index of `i-th` GKR-IOP output-eval in PCS
103+
fn output_map(i: usize) -> usize {
104+
unimplemented!();
105+
}
106+
102107
fn phase1_witness_from_steps(
103108
layout: &Self::Layout,
104109
steps: &[StepRecord],

ceno_zkvm/src/instructions/riscv/dummy/dummy_ecall.rs

+15
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ impl<E: ExtensionField, S: SyscallSpec> Instruction<E> for LargeEcallDummy<E, S>
112112

113113
// Assign memory.
114114
for ((addr, value, writer), op) in config.mem_writes.iter().zip_eq(&ops.mem_ops) {
115+
dbg!(&op.value.before);
115116
set_val!(instance, value.before, op.value.before as u64);
116117
set_val!(instance, value.after, op.value.after as u64);
117118
set_val!(instance, addr, u64::from(op.addr));
@@ -173,9 +174,23 @@ impl<E: ExtensionField> GKRIOPInstruction<E> for LargeEcallDummy<E, KeccakSpec>
173174
partial_config.lookups = lookups;
174175
partial_config.aux_wits = aux_wits;
175176

177+
dbg!(&partial_config.mem_writes[0].1.after);
178+
dbg!(&partial_config.mem_writes[1].1.before);
179+
dbg!(&partial_config.lookups[0]);
180+
176181
Ok(partial_config)
177182
}
178183

184+
fn output_map(i: usize) -> usize {
185+
if i < 50 {
186+
27 + 6 * i
187+
} else if i < 100 {
188+
26 + 6 * (i - 50)
189+
} else {
190+
326 + i - 100
191+
}
192+
}
193+
179194
fn phase1_witness_from_steps(
180195
layout: &Self::Layout,
181196
steps: &[StepRecord],

ceno_zkvm/src/scheme.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
use ff_ext::ExtensionField;
2+
use gkr_iop::gkr::{Evaluation, GKRCircuit, GKRProverOutput};
23
use itertools::Itertools;
34
use mpcs::PolynomialCommitmentScheme;
45
use p3::field::PrimeCharacteristicRing;
56
use serde::{Deserialize, Serialize, de::DeserializeOwned};
67
use std::{
78
collections::BTreeMap,
89
fmt::{self, Debug},
10+
marker::PhantomData,
911
ops::Div,
1012
};
1113
use sumcheck::structs::IOPProverMessage;
@@ -51,7 +53,15 @@ pub struct ZKVMOpcodeProof<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>
5153
pub wits_opening_proof: PCS::Proof,
5254
pub wits_in_evals: Vec<E>,
5355

54-
pub gkr_out_evals: Option<Vec<E>>,
56+
pub gkr_opcode_proof: Option<GKROpcodeProof<E, PCS>>,
57+
}
58+
59+
#[derive(Clone, Serialize)]
60+
pub struct GKROpcodeProof<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> {
61+
output_evals: Vec<E>,
62+
prover_output: GKRProverOutput<E, Evaluation<E>>,
63+
circuit: GKRCircuit,
64+
_marker: PhantomData<PCS>,
5565
}
5666

5767
#[derive(Clone, Serialize, Deserialize)]

ceno_zkvm/src/scheme/prover.rs

+16-20
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use ff_ext::ExtensionField;
33
use gkr_iop::{evaluation::PointAndEval, gkr::GKRCircuitWitness};
44
use std::{
55
collections::{BTreeMap, BTreeSet, HashMap},
6+
marker::PhantomData,
67
sync::Arc,
78
};
89

@@ -31,6 +32,7 @@ use crate::{
3132
riscv::{dummy::LargeEcallDummy, ecall::EcallDummy},
3233
},
3334
scheme::{
35+
GKROpcodeProof,
3436
constants::{MAINCONSTRAIN_SUMCHECK_BATCH_SIZE, NUM_FANIN, NUM_FANIN_LOGUP},
3537
utils::{
3638
infer_tower_logup_witness, infer_tower_product_witness, interleaving_mles_to_mles,
@@ -481,9 +483,6 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMProver<E, PCS> {
481483
);
482484
}
483485

484-
// dbg!(sel_r);
485-
// panic!();
486-
487486
let mut sel_w = build_eq_x_r_vec(&rt_w[log2_w_count..]);
488487
if num_instances < sel_w.len() {
489488
sel_w.splice(
@@ -703,23 +702,11 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMProver<E, PCS> {
703702
exit_span!(pcs_open_span);
704703
let wits_commit = PCS::get_pure_commitment(&wits_commit);
705704

706-
let gkr_out_evals = if let Some((gkr_iop_pk, gkr_wit)) = gkr_iop_pk {
707-
let mut gkr_iop_pk = gkr_iop_pk.clone();
705+
let gkr_opcode_proof = if let Some((gkr_iop_pk, gkr_wit)) = gkr_iop_pk {
706+
let gkr_iop_pk = gkr_iop_pk.clone();
708707
let gkr_circuit = gkr_iop_pk.vk.get_state().chip.gkr_circuit();
709708

710709
let point = Arc::new(input_open_point);
711-
dbg!(&point);
712-
// // let mut prover_transcript = transcript::BasicTranscript::<E>::new(b"protocol");
713-
// let out_evals = chain!(
714-
// r_records_in_evals.clone(),
715-
// w_records_in_evals.clone(),
716-
// lk_records_in_evals.clone()
717-
// )
718-
// .map(|record| PointAndEval {
719-
// point: point.clone(),
720-
// eval: record,
721-
// })
722-
// .collect_vec();
723710

724711
let out_evals = gkr_wit
725712
.layers
@@ -735,11 +722,20 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMProver<E, PCS> {
735722

736723
// out_evals from point and output polynomials instead of *_records which is combined
737724

738-
let gkr_iop::gkr::GKRProverOutput { gkr_proof, .. } = gkr_circuit
725+
let prover_output = gkr_circuit
739726
.prove(gkr_wit, &out_evals, &vec![], transcript)
740727
.expect("Failed to prove phase");
741728
// unimplemented!("cannot fully handle GKRIOP component yet")
742-
Some(out_evals.into_iter().map(|pae| pae.eval).collect_vec())
729+
730+
dbg!(&prover_output.opening_evaluations.len());
731+
let output_evals = out_evals.into_iter().map(|pae| pae.eval).collect_vec();
732+
733+
Some(GKROpcodeProof {
734+
output_evals,
735+
prover_output,
736+
circuit: gkr_circuit,
737+
_marker: PhantomData::default(),
738+
})
743739
} else {
744740
None
745741
};
@@ -761,7 +757,7 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMProver<E, PCS> {
761757
wits_commit,
762758
wits_opening_proof,
763759
wits_in_evals,
764-
gkr_out_evals,
760+
gkr_opcode_proof,
765761
})
766762
}
767763

ceno_zkvm/src/scheme/verifier.rs

+46-18
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
use std::marker::PhantomData;
1+
use std::{marker::PhantomData, sync::Arc};
22

33
use ark_std::iterable::Iterable;
4+
use ceno_emul::{KeccakSpec, SyscallSpec};
45
use ff_ext::ExtensionField;
56

67
use itertools::{Itertools, chain, interleave, izip};
@@ -17,6 +18,7 @@ use witness::next_pow2_instance_padding;
1718
use crate::{
1819
error::ZKVMError,
1920
expression::{Instance, StructuralWitIn},
21+
instructions::{GKRIOPInstruction, riscv::dummy::LargeEcallDummy},
2022
scheme::{
2123
constants::{NUM_FANIN, NUM_FANIN_LOGUP, SEL_DEGREE},
2224
utils::eval_by_expr_with_instance,
@@ -408,25 +410,51 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMVerifier<E, PCS>
408410
)
409411
};
410412

411-
if let Some(evals) = &proof.gkr_out_evals {
412-
dbg!(&sel_r);
413-
// let gkr_reads = evals.iter().take(50).collect_vec();
414-
let intersection_size = evals
415-
.iter()
416-
.counts()
413+
if name == KeccakSpec::NAME {
414+
// TODO: remove clone
415+
let gkr_iop = proof
416+
.gkr_opcode_proof
417+
.clone()
418+
.expect("Keccak syscall should contain GKR-IOP proof");
419+
420+
// Match output_evals with EcallDummy polynomials
421+
let mut matches = 0;
422+
for (i, gkr_out_eval) in gkr_iop.output_evals.iter().enumerate() {
423+
// assert_eq!(
424+
// *gkr_out_eval,
425+
// proof.wits_in_evals[LargeEcallDummy::<E, KeccakSpec>::output_map(i)],
426+
// "{i}"
427+
// );
428+
if *gkr_out_eval
429+
== proof.wits_in_evals[LargeEcallDummy::<E, KeccakSpec>::output_map(i)]
430+
{
431+
matches += 1;
432+
} else {
433+
dbg!(i);
434+
}
435+
}
436+
dbg!(matches);
437+
panic!();
438+
// Verify GKR proof
439+
let point = Arc::new(input_opening_point.clone());
440+
let out_evals = gkr_iop
441+
.output_evals
417442
.iter()
418-
.map(|(val, count)| {
419-
let proof_count = proof
420-
.r_records_in_evals
421-
.iter()
422-
.enumerate()
423-
.filter(|(i, x)| *alpha_read * **val == **x)
424-
.count();
425-
*count.min(&proof_count)
443+
.map(|eval| gkr_iop::evaluation::PointAndEval {
444+
point: point.clone(),
445+
eval: eval.clone(),
426446
})
427-
.sum::<usize>();
428-
dbg!(&intersection_size);
429-
// panic!();
447+
.collect_vec();
448+
449+
gkr_iop
450+
.circuit
451+
.verify(
452+
gkr_iop.prover_output.gkr_proof.clone(),
453+
&out_evals,
454+
&vec![],
455+
transcript,
456+
)
457+
.expect("GKR IOP verify failure");
430458
}
431459

432460
let computed_evals = [

gkr_iop/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ p3-field.workspace = true
2020
p3-goldilocks.workspace = true
2121
rand.workspace = true
2222
rayon.workspace = true
23+
serde.workspace = true
2324
subprotocols = { path = "../subprotocols" }
2425
thiserror = "1"
2526
tiny-keccak.workspace = true

gkr_iop/src/evaluation.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,25 @@
11
use std::sync::Arc;
22

33
use ff_ext::ExtensionField;
4-
use itertools::{Itertools, izip};
4+
use itertools::{izip, Itertools};
55
use multilinear_extensions::virtual_poly::build_eq_x_r_vec_sequential;
6+
use serde::Serialize;
67
use subprotocols::expression::{Constant, Point};
78

8-
/// Evaluation expression for the gkr layer reduction and PCS opening preparation.
9-
#[derive(Clone, Debug)]
9+
/// Evaluation expression for the gkr layer reduction and PCS opening
10+
/// preparation.
11+
#[derive(Clone, Debug, Serialize)]
1012
pub enum EvalExpression {
1113
/// Single entry in the evaluation vector.
1214
Single(usize),
1315
/// Linear expression of an entry with the scalar and offset.
1416
Linear(usize, Constant, Constant),
1517
/// Merging multiple evaluations which denotes a partition of the original
1618
/// polynomial. `(usize, Constant)` denote the modification of the point.
17-
/// For example, when it receive a point `(p0, p1, p2, p3)` from a succeeding
18-
/// layer, `vec![(2, c0), (4, c1)]` will modify the point to `(p0, p1, c0, p2, c1, p3)`.
19-
/// where the indices specify how the partition applied to the original polynomial.
19+
/// For example, when it receive a point `(p0, p1, p2, p3)` from a
20+
/// succeeding layer, `vec![(2, c0), (4, c1)]` will modify the point to
21+
/// `(p0, p1, c0, p2, c1, p3)`. where the indices specify how the
22+
/// partition applied to the original polynomial.
2023
Partition(Vec<Box<EvalExpression>>, Vec<(usize, Constant)>),
2124
}
2225

gkr_iop/src/gkr.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use ff_ext::ExtensionField;
22
use itertools::{chain, izip, Itertools};
33
use layer::{Layer, LayerWitness};
4+
use serde::Serialize;
45
use subprotocols::{expression::Point, sumcheck::SumcheckProof};
56
use transcript::Transcript;
67

@@ -12,7 +13,7 @@ use crate::{
1213
pub mod layer;
1314
pub mod mock;
1415

15-
#[derive(Clone, Debug)]
16+
#[derive(Clone, Debug, Serialize)]
1617
pub struct GKRCircuit {
1718
pub layers: Vec<Layer>,
1819

@@ -27,13 +28,16 @@ pub struct GKRCircuitWitness<E: ExtensionField> {
2728
pub layers: Vec<LayerWitness<E>>,
2829
}
2930

31+
#[derive(Clone, Serialize)]
3032
pub struct GKRProverOutput<E: ExtensionField, Evaluation> {
3133
pub gkr_proof: GKRProof<E>,
3234
pub opening_evaluations: Vec<Evaluation>,
3335
}
3436

37+
#[derive(Clone, Serialize)]
3538
pub struct GKRProof<E: ExtensionField>(pub Vec<SumcheckProof<E>>);
3639

40+
#[derive(Clone, Debug, Serialize)]
3741
pub struct Evaluation<E: ExtensionField> {
3842
pub value: E,
3943
pub point: Point<E>,

gkr_iop/src/gkr/layer.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use ark_std::log2;
22
use ff_ext::ExtensionField;
33
use itertools::{chain, izip};
44
use linear_layer::LinearLayer;
5+
use serde::Serialize;
56
use subprotocols::{
67
expression::{Constant, Expression, Point},
78
sumcheck::{SumcheckClaims, SumcheckProof, SumcheckProverOutput},
@@ -20,14 +21,14 @@ pub mod linear_layer;
2021
pub mod sumcheck_layer;
2122
pub mod zerocheck_layer;
2223

23-
#[derive(Clone, Debug)]
24+
#[derive(Clone, Debug, Serialize)]
2425
pub enum LayerType {
2526
Sumcheck,
2627
Zerocheck,
2728
Linear,
2829
}
2930

30-
#[derive(Clone, Debug)]
31+
#[derive(Clone, Debug, Serialize)]
3132
pub struct Layer {
3233
pub name: String,
3334
pub ty: LayerType,

0 commit comments

Comments
 (0)