schnorrkel/
errors.rs

1// -*- mode: rust; -*-
2//
3// This file is part of schnorrkel.
4// Copyright (c) 2019 Isis Lovecruft and Web 3 Foundation
5// See LICENSE for licensing information.
6//
7// Authors:
8// - Isis Agora Lovecruft <isis@patternsinthevoid.net>
9// - Jeff Burdges <jeff@web3.foundation>
10
11//! ### Errors which may occur when parsing keys and/or signatures to or from wire formats.
12
13// rustc seems to think the typenames in match statements (e.g. in
14// Display) should be snake cased, for some reason.
15#![allow(non_snake_case)]
16
17use core::fmt;
18use core::fmt::Display;
19
20
21/// `Result` specialized to this crate for convenience.
22pub type SignatureResult<T> = Result<T, SignatureError>;
23
24/// Three-round trip multi-signature stage identifies used in error reporting
25#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
26pub enum MultiSignatureStage {
27    /// Initial commitment phase of a multi-signature
28    Commitment,
29    /// Reveal phase of a multi-signature
30    Reveal,
31    /// Actual cosigning phase of a multi-signature
32    Cosignature,
33}
34
35impl Display for MultiSignatureStage {
36    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37        use self::MultiSignatureStage::*;
38        match *self {
39            Commitment => write!(f, "commitment"),
40            Reveal => write!(f, "reveal"),
41            Cosignature => write!(f, "cosignature"),
42        }
43    }
44}
45
46/// Errors which may occur while processing signatures and keypairs.
47///
48/// All these errors represent a failed signature when they occur in
49/// the context of verifying a signature, including in deserializaing
50/// for verification.  We expose the distinction among them primarily
51/// for debugging purposes.
52///
53/// This error may arise due to:
54///
55/// * Being given bytes with a length different to what was expected.
56///
57/// * A problem decompressing `r`, a curve point, in the `Signature`, or the
58///   curve point for a `PublicKey`.
59///
60/// * A problem with the format of `s`, a scalar, in the `Signature`.  This
61///   is only raised if the high-bit of the scalar was set.  (Scalars must
62///   only be constructed from 255-bit integers.)
63///
64/// * Multi-signature protocol errors
65//
66// * Failure of a signature to satisfy the verification equation.
67#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
68pub enum SignatureError {
69    /// A signature verification equation failed.
70    ///
71    /// We emphasise that all variants represent a failed signature,
72    /// not only this one.
73    EquationFalse,
74    /// Invalid point provided, usually to `verify` methods.
75    PointDecompressionError,
76    /// Invalid scalar provided, usually to `Signature::from_bytes`.
77    ScalarFormatError,
78    /// The provided key is not valid.
79    InvalidKey,
80    /// An error in the length of bytes handed to a constructor.
81    ///
82    /// To use this, pass a string specifying the `name` of the type
83    /// which is returning the error, and the `length` in bytes which
84    /// its constructor expects.
85    BytesLengthError {
86        /// Identifies the type returning the error
87        name: &'static str,
88        /// Describes the type returning the error
89        description: &'static str,
90        /// Length expected by the constructor in bytes
91        length: usize
92    },
93    /// Signature not marked as schnorrkel, maybe try ed25519 instead.
94    NotMarkedSchnorrkel,
95    /// There is no record of the preceding multi-signautre protocol
96    /// stage for the specified public key.
97    MuSigAbsent {
98        /// Identifies the multi-signature protocol stage during which
99        /// the error occurred.
100        musig_stage: MultiSignatureStage,
101    },
102    /// For this public key, there are either conflicting records for
103    /// the preceding multi-signautre protocol stage or else duplicate
104    /// duplicate records for the current stage.
105    MuSigInconsistent {
106        /// Identifies the multi-signature protocol stage during which
107        /// the error occurred.
108        musig_stage: MultiSignatureStage,
109        /// Set true if the stage was reached correctly once but this
110        /// duplicate disagrees.
111        duplicate: bool,
112    },
113}
114
115impl Display for SignatureError {
116    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117        use self::SignatureError::*;
118        match *self {
119            EquationFalse =>
120                write!(f, "Verification equation failed"),
121            PointDecompressionError =>
122                write!(f, "Cannot decompress Ristretto point"),
123            ScalarFormatError =>
124                write!(f, "Cannot use scalar with high-bit set"),
125            InvalidKey =>
126                write!(f, "The provided key is not valid"),
127            BytesLengthError { name, length, .. } =>
128                write!(f, "{name} must be {length} bytes in length"),
129            NotMarkedSchnorrkel => 
130                write!(f, "Signature bytes not marked as a schnorrkel signature"),
131            MuSigAbsent { musig_stage, } =>
132                write!(f, "Absent {musig_stage} violated multi-signature protocol"),
133            MuSigInconsistent { musig_stage, duplicate, } =>
134                if duplicate {
135                    write!(f, "Inconsistent duplicate {musig_stage} in multi-signature")
136                } else {
137                    write!(f, "Inconsistent {musig_stage} violated multi-signature protocol")
138                },
139        }
140    }
141}
142
143#[cfg(feature = "failure")]
144impl failure::Fail for SignatureError {}
145
146/// Convert `SignatureError` into `::serde::de::Error` aka `SerdeError`
147///
148/// We should do this with `From` but right now the orphan rules prohibit
149/// `impl From<SignatureError> for E where E: serde::de::Error`.
150#[cfg(feature = "serde")]
151pub fn serde_error_from_signature_error<E>(err: SignatureError) -> E
152where E: serde_crate::de::Error
153{
154    E::custom(err)
155}