Skip to main content

proof_cat_core/
error.rs

1//! Project-wide error type.
2
3/// All errors that can arise in proof-cat-core.
4#[derive(Debug)]
5pub enum Error {
6    /// An error propagated from field-cat (field arithmetic or byte encoding).
7    FieldCat(field_cat::Error),
8    /// Sumcheck round count does not match the number of variables.
9    RoundCountMismatch {
10        /// The expected number of rounds.
11        expected: usize,
12        /// The actual number of rounds in the proof.
13        actual: usize,
14    },
15    /// Sumcheck final evaluation check failed.
16    SumcheckFinalMismatch,
17    /// Merkle opening proof does not match the committed root.
18    MerkleVerificationFailed,
19    /// Polynomial evaluation point has wrong dimension.
20    DimensionMismatch {
21        /// The expected number of variables.
22        expected: usize,
23        /// The actual dimension of the point.
24        actual: usize,
25    },
26    /// A value is not a power of two where one was required.
27    NotPowerOfTwo {
28        /// The non-power-of-two value.
29        value: usize,
30    },
31    /// Leaf index out of bounds for the Merkle tree.
32    LeafIndexOutOfBounds {
33        /// The requested index.
34        index: usize,
35        /// The number of leaves.
36        leaf_count: usize,
37    },
38}
39
40impl core::fmt::Display for Error {
41    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
42        match self {
43            Self::FieldCat(e) => write!(f, "field-cat error: {e}"),
44            Self::RoundCountMismatch { expected, actual } => {
45                write!(
46                    f,
47                    "sumcheck round count mismatch: expected {expected}, got {actual}"
48                )
49            }
50            Self::SumcheckFinalMismatch => {
51                write!(f, "sumcheck final evaluation does not match claim")
52            }
53            Self::MerkleVerificationFailed => {
54                write!(f, "Merkle opening verification failed")
55            }
56            Self::DimensionMismatch { expected, actual } => {
57                write!(
58                    f,
59                    "dimension mismatch: expected {expected} variables, got {actual}"
60                )
61            }
62            Self::NotPowerOfTwo { value } => {
63                write!(f, "{value} is not a power of two")
64            }
65            Self::LeafIndexOutOfBounds { index, leaf_count } => {
66                write!(
67                    f,
68                    "leaf index {index} out of bounds (tree has {leaf_count} leaves)"
69                )
70            }
71        }
72    }
73}
74
75impl std::error::Error for Error {
76    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
77        match self {
78            Self::FieldCat(e) => Some(e),
79            Self::RoundCountMismatch { .. }
80            | Self::SumcheckFinalMismatch
81            | Self::MerkleVerificationFailed
82            | Self::DimensionMismatch { .. }
83            | Self::NotPowerOfTwo { .. }
84            | Self::LeafIndexOutOfBounds { .. } => None,
85        }
86    }
87}
88
89impl From<field_cat::Error> for Error {
90    fn from(e: field_cat::Error) -> Self {
91        Self::FieldCat(e)
92    }
93}