Skip to main content

p3_sumcheck/
error.rs

1use thiserror::Error;
2
3/// Errors from sumcheck protocol verification.
4#[derive(Error, Debug, PartialEq, Eq)]
5pub enum SumcheckError {
6    /// The proof contains a different number of rounds than expected.
7    #[error("Sumcheck round count mismatch: expected {expected}, got {actual}")]
8    RoundCountMismatch {
9        /// Round count the configuration fixes.
10        expected: usize,
11        /// Round count the proof carries.
12        actual: usize,
13    },
14
15    /// The proof is missing sumcheck data when rounds > 0.
16    #[error("Missing sumcheck data for {expected_rounds} expected rounds")]
17    MissingSumcheckData {
18        /// Round count the configuration fixes.
19        expected_rounds: usize,
20    },
21
22    /// Proof-of-work witness verification failed.
23    #[error("Sumcheck round {round}: pow witness does not meet {difficulty} bits")]
24    InvalidPowWitness {
25        /// Round whose challenge the rejected grinding step guards.
26        round: usize,
27        /// Difficulty in bits that the step requires.
28        difficulty: usize,
29    },
30
31    /// Grinding is enabled but a round carries no witness to replay its step with.
32    #[error("Sumcheck round {round}: missing the pow witness for {difficulty} bits")]
33    MissingPowWitness {
34        /// Round whose challenge the absent grinding step guards.
35        round: usize,
36        /// Difficulty in bits that the step requires.
37        difficulty: usize,
38    },
39
40    /// The witness count is not the one the difficulty fixes.
41    ///
42    /// Zero difficulty admits no witnesses, and a positive one admits exactly one per round.
43    #[error("Sumcheck PoW witness count mismatch: expected {expected}, got {actual}")]
44    PowWitnessCountMismatch {
45        /// Witness count the configuration fixes.
46        expected: usize,
47        /// Witness count the proof carries.
48        actual: usize,
49    },
50
51    /// HVZK sumcheck: a per-round wire payload had the wrong number of field elements.
52    ///
53    /// Each round carries `max(ell_zk, 3) - 1` of them.
54    ///
55    /// The linear coefficient is the one left off, per Lemma 6.4 and paper ยง6.
56    #[error("HVZK round {round}: wire size mismatch, expected {expected}, got {actual}")]
57    WireSizeMismatch {
58        /// Round index where the mismatch was found, counted from zero.
59        round: usize,
60        /// Element count the configuration fixes.
61        expected: usize,
62        /// Element count the proof carries.
63        actual: usize,
64    },
65
66    /// HVZK sumcheck: the base field has characteristic two.
67    ///
68    /// Lemma 6.4 inverts the endpoint identity, which divides by two.
69    #[error("HVZK sumcheck: Lemma 6.4 requires char(F) != 2")]
70    EvenCharacteristic,
71
72    /// HVZK sumcheck: the mask code message is too short to hide a round.
73    ///
74    /// A mask of degree `ell_zk - 1` must cover the degree-2 plain piece.
75    #[error("HVZK sumcheck: mask message length {ell_zk} is below the required 3")]
76    MaskTooShort {
77        /// Mask code message length the configuration fixes.
78        ell_zk: usize,
79    },
80
81    /// HVZK sumcheck: a masked batch was configured with no rounds.
82    ///
83    /// Such a batch commits no mask and reduces no claim.
84    #[error("HVZK sumcheck: a masked batch must run at least one round")]
85    NoRounds,
86
87    /// An opening claim's evaluations do not match the requested column shape.
88    ///
89    /// The evaluations come from the proof, so a malformed proof must be
90    /// rejected here rather than aborting the verifier.
91    #[error(
92        "Opening shape mismatch for table {table_idx}: requested {expected_current} current and {expected_next} next, got {actual_current} current and {actual_next} next"
93    )]
94    OpeningShapeMismatch {
95        /// Table whose opening claim was rejected.
96        table_idx: usize,
97        /// Current-column count the request fixes.
98        expected_current: usize,
99        /// Next-column count the request fixes.
100        expected_next: usize,
101        /// Current-column count the claim carries.
102        actual_current: usize,
103        /// Next-column count the claim carries.
104        actual_next: usize,
105    },
106}