miden-crypto/src/gkr/sumcheck/mod.rs
src/gkr/sumcheck/mod.rsRaw
1use super::{
2 multivariate::{ComposedMultiLinears, ComposedMultiLinearsOracle},
3 utils::{barycentric_weights, evaluate_barycentric},
4};
5use winter_math::FieldElement;
6
7mod prover;
8pub use prover::sum_check_prove;
9mod verifier;
10pub use verifier::{sum_check_verify, sum_check_verify_and_reduce};
11mod tests;
12
13#[derive(Debug, Clone)]
14pub struct RoundProof<E> {
15 pub poly_evals: Vec<E>,
16}
17
18impl<E: FieldElement> RoundProof<E> {
19 pub fn to_evals(&self, claim: E) -> Vec<E> {
20 let mut result = vec![];
21
22 // s(0) + s(1) = claim
23 let c0 = claim - self.poly_evals[0];
24
25 result.push(c0);
26 result.extend_from_slice(&self.poly_evals);
27 result
28 }
29
30 // TODO: refactor once we move to coefficient form
31 pub(crate) fn evaluate(&self, claim: E, r: E) -> E {
32 let poly_evals = self.to_evals(claim);
33
34 let points: Vec<E> = (0..poly_evals.len()).map(|i| E::from(i as u8)).collect();
35 let evalss: Vec<(E, E)> =
36 points.iter().zip(poly_evals.iter()).map(|(x, y)| (*x, *y)).collect();
37 let weights = barycentric_weights(&evalss);
38 let new_claim = evaluate_barycentric(&evalss, r, &weights);
39 new_claim
40 }
41}
42
43#[derive(Debug, Clone)]
44pub struct PartialProof<E> {
45 pub round_proofs: Vec<RoundProof<E>>,
46}
47
48#[derive(Clone)]
49pub struct FinalEvaluationClaim<E: FieldElement> {
50 pub evaluation_point: Vec<E>,
51 pub claimed_evaluation: E,
52 pub polynomial: ComposedMultiLinearsOracle<E>,
53}
54
55#[derive(Clone)]
56pub struct FullProof<E: FieldElement> {
57 pub sum_check_proof: PartialProof<E>,
58 pub final_evaluation_claim: FinalEvaluationClaim<E>,
59}
60
61pub struct Claim<E: FieldElement> {
62 pub sum_value: E,
63 pub polynomial: ComposedMultiLinearsOracle<E>,
64}
65
66#[derive(Debug)]
67pub struct RoundClaim<E: FieldElement> {
68 pub partial_eval_point: Vec<E>,
69 pub current_claim: E,
70}
71
72pub struct RoundOutput<E: FieldElement> {
73 proof: PartialProof<E>,
74 witness: Witness<E>,
75}
76
77impl<E: FieldElement> From<Claim<E>> for RoundClaim<E> {
78 fn from(value: Claim<E>) -> Self {
79 Self {
80 partial_eval_point: vec![],
81 current_claim: value.sum_value,
82 }
83 }
84}
85
86pub struct Witness<E: FieldElement> {
87 pub(crate) polynomial: ComposedMultiLinears<E>,
88}
89
90pub fn reduce_claim<E: FieldElement>(
91 current_poly: RoundProof<E>,
92 current_round_claim: RoundClaim<E>,
93 round_challenge: E,
94) -> RoundClaim<E> {
95 let poly_evals = current_poly.to_evals(current_round_claim.current_claim);
96 let points: Vec<E> = (0..poly_evals.len()).map(|i| E::from(i as u8)).collect();
97 let evalss: Vec<(E, E)> = points.iter().zip(poly_evals.iter()).map(|(x, y)| (*x, *y)).collect();
98 let weights = barycentric_weights(&evalss);
99 let new_claim = evaluate_barycentric(&evalss, round_challenge, &weights);
100
101 let mut new_partial_eval_point = current_round_claim.partial_eval_point;
102 new_partial_eval_point.push(round_challenge);
103
104 RoundClaim {
105 partial_eval_point: new_partial_eval_point,
106 current_claim: new_claim,
107 }
108}