Skip to main content

pqc_sig/
error.rs

1//! Unified error type for the `pqc-sig` crate.
2//!
3//! All signature operations return `Result<T, SigError>`. This type is designed to be
4//! `no_std`-compatible (with `alloc`) and serializable for WASM boundary crossing.
5
6extern crate alloc;
7use alloc::string::{String, ToString};
8
9use thiserror::Error;
10
11/// Errors that can occur during signature operations.
12#[derive(Debug, Error, Clone, PartialEq)]
13pub enum SigError {
14    /// Key generation failed (e.g., RNG failure).
15    #[error("key generation failed: {0}")]
16    KeyGeneration(String),
17
18    /// Signing operation failed.
19    #[error("signing failed: {0}")]
20    Signing(String),
21
22    /// Signature verification failed (signature is invalid for the given message/key).
23    #[error("signature verification failed")]
24    VerificationFailed,
25
26    /// Invalid public key (wrong size, wrong algorithm tag, or malformed).
27    #[error("invalid public key: {0}")]
28    InvalidPublicKey(String),
29
30    /// Invalid secret key (wrong size, wrong algorithm tag, or malformed).
31    #[error("invalid secret key: {0}")]
32    InvalidSecretKey(String),
33
34    /// Invalid signature (wrong size, wrong algorithm tag, or malformed).
35    #[error("invalid signature: {0}")]
36    InvalidSignature(String),
37
38    /// Base64 decoding error.
39    #[error("base64 decode error: {0}")]
40    Base64Decode(String),
41
42    /// JSON serialization/deserialization error.
43    #[error("serialization error: {0}")]
44    Serialization(String),
45
46    /// The requested algorithm is not available (feature not enabled).
47    #[error("algorithm '{name}' not available; enable feature '{feature}'")]
48    AlgorithmNotAvailable { name: String, feature: String },
49
50    /// Hybrid signature verification failed on the classical (Ed25519) side.
51    #[error("hybrid verification failed: classical (Ed25519) signature invalid")]
52    HybridClassicalFailed,
53
54    /// Hybrid signature verification failed on the post-quantum (ML-DSA) side.
55    #[error("hybrid verification failed: post-quantum (ML-DSA) signature invalid")]
56    HybridPqcFailed,
57
58    /// Generic internal error.
59    #[error("internal error: {0}")]
60    Internal(String),
61
62    /// Domain-separation context string exceeds the FIPS 204/205/206 255-byte maximum.
63    ///
64    /// FIPS 204 §5.2, FIPS 205 §10.2, and the FIPS 206 (draft) `DomainContext` construction
65    /// all encode the context length in a single byte, capping it at 255 bytes. Returned by
66    /// every `sign_ctx`/`sign_ctx_deterministic`/`verify_ctx` method before it would
67    /// otherwise hit an opaque error from the underlying `ml-dsa`/`slh-dsa`/`fn-dsa` crate.
68    #[error("context string too long: {len} bytes (max 255)")]
69    ContextTooLong { len: usize },
70
71    /// Pre-hash digest length does not match the expected output size of the named
72    /// hash function (FIPS 204 §5.4.1 / FIPS 205 §10.2.2).
73    ///
74    /// Returned by every `sign_prehash`/`sign_prehash_deterministic`/`verify_prehash`
75    /// method before it would otherwise sign/verify a malformed digest.
76    #[error("digest length for {hash} must be {expected} bytes, got {got}")]
77    InvalidDigestLength { hash: &'static str, expected: usize, got: usize },
78
79    /// Pre-hash collision strength is weaker than the signature algorithm's required
80    /// security strength (FIPS 204 §5.4 / FIPS 205 §10.2.2).
81    ///
82    /// For example, `PreHash::Sha256` (128-bit collision strength) is rejected for
83    /// `MlDsa65Keypair`/`MlDsa87Keypair` (192/256-bit security strength).
84    #[error("pre-hash {hash} ({strength}-bit collision strength) is too weak for {algorithm} (requires >= {required} bits)")]
85    PreHashTooWeak { hash: &'static str, strength: u32, algorithm: &'static str, required: u32 },
86}
87
88impl SigError {
89    /// Convert to a string suitable for crossing the WASM boundary.
90    pub fn to_wasm_string(&self) -> String {
91        self.to_string()
92    }
93}
94
95/// Convenience type alias for signature results.
96pub type SigResult<T> = Result<T, SigError>;