Skip to main content

proof_cat/
error.rs

1//! Project-wide error type.
2
3/// All errors that can arise in proof-cat.
4#[derive(Debug)]
5pub enum Error {
6    /// An error propagated from plonkish-cat.
7    Plonkish(plonkish_cat::Error),
8    /// An error propagated from field-cat (field arithmetic or byte encoding).
9    FieldCat(field_cat::Error),
10    /// Witness length does not match the wire count.
11    WitnessSizeMismatch {
12        /// The number of wires expected.
13        expected: usize,
14        /// The number of wire values provided.
15        actual: usize,
16    },
17    /// A constraint was not satisfied by the witness.
18    UnsatisfiedConstraint {
19        /// The zero-based index of the failing constraint.
20        index: usize,
21    },
22    /// Sumcheck round count does not match the number of variables.
23    RoundCountMismatch {
24        /// The expected number of rounds.
25        expected: usize,
26        /// The actual number of rounds in the proof.
27        actual: usize,
28    },
29    /// Sumcheck final evaluation check failed.
30    SumcheckFinalMismatch,
31    /// Merkle opening proof does not match the committed root.
32    MerkleVerificationFailed,
33    /// Polynomial evaluation point has wrong dimension.
34    DimensionMismatch {
35        /// The expected number of variables.
36        expected: usize,
37        /// The actual dimension of the point.
38        actual: usize,
39    },
40    /// Constraint set is empty; nothing to prove.
41    EmptyConstraintSet,
42    /// A value is not a power of two where one was required.
43    NotPowerOfTwo {
44        /// The non-power-of-two value.
45        value: usize,
46    },
47    /// Leaf index out of bounds for the Merkle tree.
48    LeafIndexOutOfBounds {
49        /// The requested index.
50        index: usize,
51        /// The number of leaves.
52        leaf_count: usize,
53    },
54}
55
56impl core::fmt::Display for Error {
57    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
58        match self {
59            Self::Plonkish(e) => write!(f, "plonkish-cat error: {e}"),
60            Self::FieldCat(e) => write!(f, "field-cat error: {e}"),
61            Self::WitnessSizeMismatch { expected, actual } => {
62                write!(
63                    f,
64                    "witness size mismatch: expected {expected}, got {actual}"
65                )
66            }
67            Self::UnsatisfiedConstraint { index } => {
68                write!(f, "constraint {index} not satisfied by witness")
69            }
70            Self::RoundCountMismatch { expected, actual } => {
71                write!(
72                    f,
73                    "sumcheck round count mismatch: expected {expected}, got {actual}"
74                )
75            }
76            Self::SumcheckFinalMismatch => {
77                write!(f, "sumcheck final evaluation does not match claim")
78            }
79            Self::MerkleVerificationFailed => {
80                write!(f, "Merkle opening verification failed")
81            }
82            Self::DimensionMismatch { expected, actual } => {
83                write!(
84                    f,
85                    "dimension mismatch: expected {expected} variables, got {actual}"
86                )
87            }
88            Self::EmptyConstraintSet => write!(f, "constraint set is empty"),
89            Self::NotPowerOfTwo { value } => {
90                write!(f, "{value} is not a power of two")
91            }
92            Self::LeafIndexOutOfBounds { index, leaf_count } => {
93                write!(
94                    f,
95                    "leaf index {index} out of bounds (tree has {leaf_count} leaves)"
96                )
97            }
98        }
99    }
100}
101
102impl std::error::Error for Error {
103    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
104        match self {
105            Self::Plonkish(e) => Some(e),
106            Self::FieldCat(e) => Some(e),
107            Self::WitnessSizeMismatch { .. }
108            | Self::UnsatisfiedConstraint { .. }
109            | Self::RoundCountMismatch { .. }
110            | Self::SumcheckFinalMismatch
111            | Self::MerkleVerificationFailed
112            | Self::DimensionMismatch { .. }
113            | Self::EmptyConstraintSet
114            | Self::NotPowerOfTwo { .. }
115            | Self::LeafIndexOutOfBounds { .. } => None,
116        }
117    }
118}
119
120impl From<plonkish_cat::Error> for Error {
121    fn from(e: plonkish_cat::Error) -> Self {
122        Self::Plonkish(e)
123    }
124}
125
126impl From<field_cat::Error> for Error {
127    fn from(e: field_cat::Error) -> Self {
128        Self::FieldCat(e)
129    }
130}