mithril_stm/
error.rs

1//! Crate specific errors
2use blake2::digest::{Digest, FixedOutput};
3use blst::BLST_ERROR;
4
5use crate::bls_multi_signature::{
6    BlsSignature, BlsVerificationKey, BlsVerificationKeyProofOfPossession,
7};
8use crate::merkle_tree::{MerkleBatchPath, MerklePath};
9
10/// Error types for multi signatures.
11#[derive(Debug, thiserror::Error, Eq, PartialEq)]
12pub enum MultiSignatureError {
13    /// Invalid Single signature
14    #[error("Invalid single signature")]
15    SignatureInvalid(BlsSignature),
16
17    /// Invalid aggregate signature
18    #[error("Invalid aggregated signature")]
19    AggregateSignatureInvalid,
20
21    /// This error occurs when the the serialization of the raw bytes failed
22    #[error("Invalid bytes")]
23    SerializationError,
24
25    /// Incorrect proof of possession
26    #[error("Key with invalid PoP")]
27    KeyInvalid(Box<BlsVerificationKeyProofOfPossession>),
28
29    /// At least one signature in the batch is invalid
30    #[error("One signature in the batch is invalid")]
31    BatchInvalid,
32
33    /// Single signature is the infinity
34    #[error("Single signature is the infinity")]
35    SignatureInfinity(BlsSignature),
36
37    /// Verification key is the infinity
38    #[error("Verification key is the infinity")]
39    VerificationKeyInfinity(Box<BlsVerificationKey>),
40}
41
42/// Error types related to merkle trees.
43#[derive(Debug, Clone, thiserror::Error)]
44pub enum MerkleTreeError<D: Digest + FixedOutput> {
45    /// Serialization error
46    #[error("Serialization of a merkle tree failed")]
47    SerializationError,
48
49    /// Invalid merkle path
50    #[error("Path does not verify against root")]
51    PathInvalid(MerklePath<D>),
52
53    /// Invalid merkle batch path
54    #[error("Batch path does not verify against root")]
55    BatchPathInvalid(MerkleBatchPath<D>),
56}
57
58/// Errors which can be output by Mithril single signature verification.
59#[derive(Debug, Clone, thiserror::Error)]
60pub enum StmSignatureError {
61    /// There is an index out of bounds
62    #[error("Received index, {0}, is higher than what the security parameter allows, {1}.")]
63    IndexBoundFailed(u64, u64),
64
65    /// MSP.Eval was computed incorrectly
66    #[error("The claimed evaluation of function phi is incorrect.")]
67    EvalInvalid([u8; 64]),
68
69    /// The lottery was actually lost for the signature
70    #[error("Lottery for this epoch was lost.")]
71    LotteryLost,
72
73    /// A party submitted an invalid signature
74    #[error("A provided signature is invalid")]
75    SignatureInvalid(BlsSignature),
76
77    /// Batch verification of STM signatures failed
78    #[error("Batch verification of STM signatures failed")]
79    BatchInvalid,
80
81    /// This error occurs when the the serialization of the raw bytes failed
82    #[error("Invalid bytes")]
83    SerializationError,
84}
85
86impl From<MultiSignatureError> for StmSignatureError {
87    fn from(e: MultiSignatureError) -> Self {
88        match e {
89            MultiSignatureError::SerializationError => Self::SerializationError,
90            MultiSignatureError::SignatureInvalid(e) => Self::SignatureInvalid(e),
91            MultiSignatureError::BatchInvalid => unreachable!(),
92            MultiSignatureError::KeyInvalid(_) => unreachable!(),
93            MultiSignatureError::AggregateSignatureInvalid => unreachable!(),
94            MultiSignatureError::SignatureInfinity(_) => unreachable!(),
95            MultiSignatureError::VerificationKeyInfinity(_) => unreachable!(),
96        }
97    }
98}
99
100impl<D: Digest + FixedOutput> From<MerkleTreeError<D>> for StmSignatureError {
101    fn from(e: MerkleTreeError<D>) -> Self {
102        match e {
103            MerkleTreeError::SerializationError => Self::SerializationError,
104            _ => unreachable!(),
105        }
106    }
107}
108
109/// Error types for aggregation.
110#[derive(Debug, Clone, thiserror::Error)]
111pub enum AggregationError {
112    /// Not enough signatures were collected, got this many instead.
113    #[error("Not enough signatures. Got only {0} out of {1}.")]
114    NotEnoughSignatures(u64, u64),
115
116    /// This error happens when we try to convert a u64 to a usize and it does not fit
117    #[error("Invalid usize conversion")]
118    UsizeConversionInvalid,
119}
120
121/// Errors which can be output by `CoreVerifier`.
122#[derive(Debug, Clone, thiserror::Error)]
123pub enum CoreVerifierError {
124    /// No quorum was found
125    #[error("No Quorum was found. Expected {0} signatures but got {1}")]
126    NoQuorum(u64, u64),
127
128    /// There is a duplicate index
129    #[error("Indices are not unique.")]
130    IndexNotUnique,
131
132    /// The aggregated signature is invalid
133    #[error("Aggregate signature is invalid")]
134    AggregateSignatureInvalid,
135
136    /// One of the aggregated signatures is invalid
137    #[error("Individual signature is invalid: {0}")]
138    IndividualSignatureInvalid(#[source] StmSignatureError),
139}
140
141impl From<AggregationError> for CoreVerifierError {
142    fn from(e: AggregationError) -> Self {
143        match e {
144            AggregationError::NotEnoughSignatures(e, _e) => Self::NoQuorum(e, e),
145            AggregationError::UsizeConversionInvalid => unreachable!(),
146        }
147    }
148}
149
150impl From<MultiSignatureError> for CoreVerifierError {
151    fn from(e: MultiSignatureError) -> Self {
152        match e {
153            MultiSignatureError::AggregateSignatureInvalid => Self::AggregateSignatureInvalid,
154            MultiSignatureError::BatchInvalid => unreachable!(),
155            MultiSignatureError::SerializationError => unreachable!(),
156            MultiSignatureError::KeyInvalid(_) => unreachable!(),
157            MultiSignatureError::SignatureInvalid(_e) => unreachable!(),
158            MultiSignatureError::SignatureInfinity(_) => unreachable!(),
159            MultiSignatureError::VerificationKeyInfinity(_) => unreachable!(),
160        }
161    }
162}
163
164impl From<StmSignatureError> for CoreVerifierError {
165    fn from(e: StmSignatureError) -> Self {
166        CoreVerifierError::IndividualSignatureInvalid(e)
167    }
168}
169
170/// Errors which can be output by Mithril aggregate verification.
171#[derive(Debug, Clone, thiserror::Error)]
172pub enum StmAggregateSignatureError<D: Digest + FixedOutput> {
173    /// The IVK is invalid after aggregating the keys
174    #[error("Aggregated key does not correspond to the expected key.")]
175    IvkInvalid(Box<BlsVerificationKey>),
176
177    /// This error occurs when the the serialization of the raw bytes failed
178    #[error("Invalid bytes")]
179    SerializationError,
180
181    /// Invalid merkle batch path
182    #[error("Batch path does not verify against root")]
183    PathInvalid(MerkleBatchPath<D>),
184
185    /// Batch verification of STM aggregate signatures failed
186    #[error("Batch verification of STM aggregate signatures failed")]
187    BatchInvalid,
188
189    /// `CoreVerifier` check failed
190    #[error("Core verification error: {0}")]
191    CoreVerificationError(#[source] CoreVerifierError),
192}
193
194impl<D: Digest + FixedOutput> From<MerkleTreeError<D>> for StmAggregateSignatureError<D> {
195    fn from(e: MerkleTreeError<D>) -> Self {
196        match e {
197            MerkleTreeError::BatchPathInvalid(e) => Self::PathInvalid(e),
198            MerkleTreeError::SerializationError => Self::SerializationError,
199            MerkleTreeError::PathInvalid(_e) => unreachable!(),
200        }
201    }
202}
203
204impl<D: Digest + FixedOutput> From<MultiSignatureError> for StmAggregateSignatureError<D> {
205    fn from(e: MultiSignatureError) -> Self {
206        match e {
207            MultiSignatureError::AggregateSignatureInvalid => {
208                Self::from(CoreVerifierError::from(e))
209            }
210            MultiSignatureError::BatchInvalid => Self::BatchInvalid,
211            MultiSignatureError::SerializationError => unreachable!(),
212            MultiSignatureError::KeyInvalid(_) => unreachable!(),
213            MultiSignatureError::SignatureInvalid(_) => {
214                Self::CoreVerificationError(CoreVerifierError::from(e))
215            }
216            MultiSignatureError::SignatureInfinity(_) => {
217                Self::CoreVerificationError(CoreVerifierError::from(e))
218            }
219            MultiSignatureError::VerificationKeyInfinity(_) => {
220                Self::CoreVerificationError(CoreVerifierError::from(e))
221            }
222        }
223    }
224}
225
226impl<D: Digest + FixedOutput> From<CoreVerifierError> for StmAggregateSignatureError<D> {
227    fn from(e: CoreVerifierError) -> Self {
228        Self::CoreVerificationError(e)
229    }
230}
231
232impl<D: Digest + FixedOutput> From<StmSignatureError> for StmAggregateSignatureError<D> {
233    fn from(e: StmSignatureError) -> Self {
234        match e {
235            StmSignatureError::SerializationError => Self::SerializationError,
236            _ => unreachable!(),
237        }
238    }
239}
240
241/// Errors which can be outputted by key registration.
242#[derive(Debug, Clone, thiserror::Error, PartialEq, Eq)]
243pub enum RegisterError {
244    /// This key has already been registered by a participant
245    #[error("This key has already been registered.")]
246    KeyRegistered(Box<BlsVerificationKey>),
247
248    /// Verification key is the infinity
249    #[error("Verification key is the infinity")]
250    VerificationKeyInfinity(Box<BlsVerificationKey>),
251
252    /// The supplied key is not valid
253    #[error("The verification of correctness of the supplied key is invalid.")]
254    KeyInvalid(Box<BlsVerificationKeyProofOfPossession>),
255
256    /// Serialization error
257    #[error("Serialization error")]
258    SerializationError,
259
260    /// UnregisteredInitializer error
261    #[error("Initializer not registered. Cannot participate as a signer.")]
262    UnregisteredInitializer,
263}
264
265impl From<MultiSignatureError> for RegisterError {
266    fn from(e: MultiSignatureError) -> Self {
267        match e {
268            MultiSignatureError::SerializationError => Self::SerializationError,
269            MultiSignatureError::KeyInvalid(e) => Self::KeyInvalid(e),
270            MultiSignatureError::VerificationKeyInfinity(e) => Self::VerificationKeyInfinity(e),
271            _ => unreachable!(),
272        }
273    }
274}
275
276/// If verifying a single signature, the signature should be provided. If verifying a multi-sig,
277/// no need to provide the signature
278pub(crate) fn blst_err_to_mithril(
279    e: BLST_ERROR,
280    sig: Option<BlsSignature>,
281    key: Option<BlsVerificationKey>,
282) -> Result<(), MultiSignatureError> {
283    match e {
284        BLST_ERROR::BLST_SUCCESS => Ok(()),
285        BLST_ERROR::BLST_PK_IS_INFINITY => {
286            if let Some(s) = sig {
287                return Err(MultiSignatureError::SignatureInfinity(s));
288            }
289            if let Some(vk) = key {
290                return Err(MultiSignatureError::VerificationKeyInfinity(Box::new(vk)));
291            }
292            Err(MultiSignatureError::SerializationError)
293        }
294        BLST_ERROR::BLST_VERIFY_FAIL => {
295            if let Some(s) = sig {
296                Err(MultiSignatureError::SignatureInvalid(s))
297            } else {
298                Err(MultiSignatureError::AggregateSignatureInvalid)
299            }
300        }
301        _ => Err(MultiSignatureError::SerializationError),
302    }
303}