Skip to main content

p3_sumcheck/jagged/
error.rs

1//! Errors returned by the jagged sparse-to-dense reduction.
2
3use thiserror::Error;
4
5use crate::SumcheckError;
6
7/// A malformed sparse layout.
8#[derive(Clone, Debug, Error, PartialEq, Eq)]
9pub enum JaggedLayoutError {
10    /// The layout has no column to address.
11    #[error("a jagged layout needs at least one column")]
12    NoColumns,
13    /// The column count cannot be addressed by a Boolean point.
14    #[error("the jagged column count must be a power of two, got {columns}")]
15    ColumnCountNotPowerOfTwo {
16        /// Number of columns supplied by the caller.
17        columns: usize,
18    },
19    /// The row bound cannot be represented by a machine index.
20    #[error("the row-variable count {variables} does not fit in a machine index")]
21    RowVariablesOverflow {
22        /// Number of row variables supplied by the caller.
23        variables: usize,
24    },
25    /// A live column extends past the declared row space.
26    #[error("column {column} has height {height}, above the row bound {maximum}")]
27    HeightExceedsRowBound {
28        /// Index of the invalid column.
29        column: usize,
30        /// Number of live entries in the invalid column.
31        height: usize,
32        /// Maximum number of rows described by the row variables.
33        maximum: usize,
34    },
35    /// The sum of live column lengths overflowed a machine index.
36    #[error("the jagged trace area overflows a machine index at column {column}")]
37    AreaOverflow {
38        /// Column whose height made the running area overflow.
39        column: usize,
40    },
41    /// The padded dense area cannot be represented by a machine index.
42    #[error("the jagged trace area {area} has no representable power-of-two envelope")]
43    DenseAreaOverflow {
44        /// Sum of all live column lengths.
45        area: usize,
46    },
47    /// The requested envelope arity cannot be represented by a machine index.
48    #[error("an envelope of {variables} variables does not fit in a machine index")]
49    DenseVariablesOverflow {
50        /// Number of envelope variables the floor asks for.
51        variables: usize,
52    },
53}
54
55/// A malformed prover input or rejected jagged proof.
56#[derive(Debug, Error, PartialEq, Eq)]
57pub enum JaggedError {
58    /// The row point does not match the public row bound.
59    #[error("the row point has {actual} coordinates, expected {expected}")]
60    RowPointWidthMismatch {
61        /// Number of coordinates required by the layout.
62        expected: usize,
63        /// Number of coordinates supplied by the caller.
64        actual: usize,
65    },
66    /// The column point cannot address the public column count.
67    #[error("the column point has {actual} coordinates, expected {expected}")]
68    ColumnPointWidthMismatch {
69        /// Number of coordinates required by the layout.
70        expected: usize,
71        /// Number of coordinates supplied by the caller.
72        actual: usize,
73    },
74    /// The dense witness does not fill the power-of-two envelope exactly.
75    #[error("the dense witness has {actual} cells, expected {expected}")]
76    DenseLengthMismatch {
77        /// Envelope size fixed by the layout.
78        expected: usize,
79        /// Number of cells supplied by the prover.
80        actual: usize,
81    },
82    /// The witness does not take the value the caller asked to have proved.
83    #[error("the dense witness does not evaluate to the claimed sparse value")]
84    ClaimMismatch,
85    /// The delegated quadratic sumcheck rejected.
86    #[error(transparent)]
87    Sumcheck(#[from] SumcheckError),
88    /// The terminal product does not equal the sumcheck claim.
89    #[error("the terminal jagged relation is inconsistent")]
90    TerminalMismatch,
91}
92
93/// A trace a jagged geometry cannot read.
94#[derive(Clone, Debug, Error, PartialEq, Eq)]
95pub enum JaggedIngestError {
96    /// The producer supplies a different number of columns than the geometry has.
97    #[error("the trace has {actual} columns, expected {expected}")]
98    ColumnCountMismatch {
99        /// Number of columns the geometry reserves.
100        expected: usize,
101        /// Number of columns the producer supplies.
102        actual: usize,
103    },
104    /// One column supplies a different number of cells than the geometry reserves.
105    #[error("column {column} supplies {actual} cells, expected {expected}")]
106    ColumnHeightMismatch {
107        /// Index of the disagreeing column.
108        column: usize,
109        /// Number of cells the geometry reserves.
110        expected: usize,
111        /// Number of cells the producer supplies.
112        actual: usize,
113    },
114    /// An interleaved column would read past the block it is drawn from.
115    #[error("column {column} needs {required} cells of its block, which holds {available}")]
116    StrideOutOfRange {
117        /// Index of the invalid column.
118        column: usize,
119        /// Position one past the last cell the column reads.
120        required: usize,
121        /// Number of cells in the block.
122        available: usize,
123    },
124    /// An interleaved column declares a step of zero.
125    #[error("column {column} declares a step of zero between its cells")]
126    ZeroStride {
127        /// Index of the invalid column.
128        column: usize,
129    },
130    /// A packed column holds fewer words than its height needs.
131    #[error("column {column} needs {required} packed words and holds {available}")]
132    PackedWordsTooShort {
133        /// Index of the invalid column.
134        column: usize,
135        /// Number of words the height needs.
136        required: usize,
137        /// Number of words the producer supplies.
138        available: usize,
139    },
140    /// A pre-concatenated trace is shorter than the envelope the geometry commits.
141    #[error("the committed vector holds {available} cells and the envelope needs {required}")]
142    CommittedVectorTooShort {
143        /// Size of the envelope.
144        required: usize,
145        /// Number of cells the producer supplies.
146        available: usize,
147    },
148}
149
150/// A sparse claim the dense commitment did not authenticate.
151#[derive(Debug, Error, PartialEq, Eq)]
152pub enum JaggedOpeningError<E> {
153    /// The sparse-to-dense reduction failed.
154    #[error(transparent)]
155    Reduction(#[from] JaggedError),
156    /// The dense commitment scheme failed.
157    #[error("the dense commitment scheme reported {0:?}")]
158    Commitment(E),
159    /// No sparse claim was supplied to discharge.
160    #[error("a jagged opening must carry at least one sparse claim")]
161    NoClaims,
162    /// The proof carries a different number of reductions than there are claims.
163    #[error("the proof carries {actual} reductions for {expected} claims")]
164    ReductionCountMismatch {
165        /// Number of claims the caller stated.
166        expected: usize,
167        /// Number of reductions the proof carries.
168        actual: usize,
169    },
170    /// The dense opening returned a different number of readings than there are claims.
171    #[error("the dense opening returned {actual} readings for {expected} claims")]
172    OpeningCountMismatch {
173        /// Number of claims the caller stated.
174        expected: usize,
175        /// Number of readings the opening returned.
176        actual: usize,
177    },
178    /// One dense reading does not have the shape a claim asked for.
179    #[error("reading {reading} returned {direct} direct and {successor} successor values")]
180    OpeningShape {
181        /// Position of the malformed reading.
182        reading: usize,
183        /// Number of direct readings it returned.
184        direct: usize,
185        /// Number of successor readings it returned.
186        successor: usize,
187    },
188    /// The committed vector does not take a reduced value at its reduced point.
189    #[error("the dense commitment does not carry the value reduction {reading} produced")]
190    DenseMismatch {
191        /// Position of the claim the commitment refused.
192        reading: usize,
193    },
194}