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