Skip to main content

proof_cat/sumcheck/
protocol.rs

1//! Sumcheck protocol types.
2//!
3//! Defines the claim, round messages, and proof structure for
4//! the sumcheck interactive proof.
5
6use plonkish_cat::Field;
7
8use crate::poly::MultilinearPoly;
9
10/// A sumcheck claim: the polynomial and its purported sum.
11///
12/// The claim asserts that
13/// `sum_{x in {0,1}^n} poly(x) = claimed_sum`.
14#[derive(Debug, Clone)]
15pub struct SumcheckClaim<F: Field> {
16    poly: MultilinearPoly<F>,
17    claimed_sum: F,
18}
19
20impl<F: Field> SumcheckClaim<F> {
21    /// Create a new sumcheck claim.
22    #[must_use]
23    pub fn new(poly: MultilinearPoly<F>, claimed_sum: F) -> Self {
24        Self { poly, claimed_sum }
25    }
26
27    /// The polynomial being summed.
28    #[must_use]
29    pub fn poly(&self) -> &MultilinearPoly<F> {
30        &self.poly
31    }
32
33    /// The claimed sum.
34    #[must_use]
35    pub fn claimed_sum(&self) -> &F {
36        &self.claimed_sum
37    }
38}
39
40/// A degree-1 univariate polynomial sent by the prover each round.
41///
42/// Represented by its evaluations at 0 and 1:
43/// `s(t) = eval_zero * (1 - t) + eval_one * t`.
44#[derive(Debug, Clone)]
45pub struct RoundPoly<F: Field> {
46    eval_zero: F,
47    eval_one: F,
48}
49
50impl<F: Field> RoundPoly<F> {
51    /// Create a round polynomial from its evaluations at 0 and 1.
52    #[must_use]
53    pub fn new(eval_zero: F, eval_one: F) -> Self {
54        Self {
55            eval_zero,
56            eval_one,
57        }
58    }
59
60    /// `s(0)`: evaluation at zero.
61    #[must_use]
62    pub fn eval_zero(&self) -> &F {
63        &self.eval_zero
64    }
65
66    /// `s(1)`: evaluation at one.
67    #[must_use]
68    pub fn eval_one(&self) -> &F {
69        &self.eval_one
70    }
71
72    /// Evaluate at an arbitrary point via linear interpolation:
73    /// `s(t) = eval_zero * (1 - t) + eval_one * t`.
74    #[must_use]
75    pub fn evaluate(&self, t: &F) -> F {
76        self.eval_zero.clone() * (F::one() - t.clone()) + self.eval_one.clone() * t.clone()
77    }
78}
79
80/// A complete sumcheck proof: one round polynomial per variable.
81#[derive(Debug, Clone)]
82pub struct SumcheckProof<F: Field> {
83    round_polys: Vec<RoundPoly<F>>,
84}
85
86impl<F: Field> SumcheckProof<F> {
87    /// Create a proof from the round polynomials.
88    #[must_use]
89    pub fn new(round_polys: Vec<RoundPoly<F>>) -> Self {
90        Self { round_polys }
91    }
92
93    /// The round polynomials (one per variable).
94    #[must_use]
95    pub fn round_polys(&self) -> &[RoundPoly<F>] {
96        &self.round_polys
97    }
98}