spark_rust/signer/traits/frost.rs
1//! # FROST Nonce Management for Threshold Signatures
2//!
3//! This module defines the trait for managing cryptographic nonces in the FROST
4//! (Flexible Round-Optimized Schnorr Threshold) signature scheme. Proper nonce
5//! generation and management is absolutely critical to the security of threshold
6//! signatures in the Spark wallet.
7//!
8//! In FROST, each signing party generates nonce pairs that:
9//! - Must be unique and unpredictable for each signature
10//! - Must remain secret until the specific phases of the protocol
11//! - Must never be reused across different signing sessions
12//!
13//! This module works in conjunction with the `frost_signing.rs` module, which
14//! implements the actual threshold signing operations.
15
16use frost_secp256k1_tr_unofficial::round1::{SigningCommitments, SigningNonces};
17
18use crate::error::SparkSdkError;
19
20/// Trait for managing cryptographic nonces in FROST threshold signing.
21///
22/// This trait provides methods for generating, storing, and retrieving the nonce
23/// pairs required for FROST threshold signing. Nonce management is a security-critical
24/// component of the FROST protocol, as improper nonce generation or reuse can
25/// lead to private key compromise.
26///
27/// In the FROST protocol flow:
28/// 1. Each participant generates a nonce pair (secret nonces and public commitments)
29/// 2. Participants exchange commitments (not nonces) with each other
30/// 3. When signing occurs, participants reveal their nonces in a controlled manner
31///
32/// The implementation must ensure that:
33/// - Nonces are generated using a cryptographically secure random number generator
34/// - Nonces are never reused across different signing operations
35/// - Nonces are properly stored with their corresponding commitments
36/// - Access to secret nonces is strictly controlled
37pub trait SparkSignerFrost {
38 /// Generates a new (commitments, nonces) pair for a FROST signing round.
39 ///
40 /// This method creates a fresh nonce pair for use in FROST threshold signing
41 /// and stores it securely within the signer's state. The commitments (public part)
42 /// are returned and can be safely shared with other signing participants.
43 ///
44 /// # Returns
45 /// * `Ok(SigningCommitments)` - The public commitments corresponding to the generated nonces
46 /// * `Err(SparkSdkError)` - If nonce generation fails
47 ///
48 /// # Security Considerations
49 /// The implementation must use a secure random number generator to ensure nonces
50 /// are unpredictable. Predictable nonces can lead to private key compromise.
51 fn new_frost_signing_noncepair(&self) -> Result<SigningCommitments, SparkSdkError>;
52
53 /// Exposes the secret nonces corresponding to previously generated commitments.
54 ///
55 /// # Security Warning
56 /// This is a **highly sensitive** operation from a security perspective because
57 /// it reveals confidential material. Improper exposure of nonces can lead to
58 /// private key compromise. Use it **only** when absolutely necessary during the
59 /// FROST signing protocol, and handle the returned nonces with extreme caution.
60 ///
61 /// # Arguments
62 /// * `signing_commitments` - The commitments for which to retrieve the corresponding nonces
63 ///
64 /// # Returns
65 /// * `Ok(SigningNonces)` - The secret nonces corresponding to the provided commitments
66 /// * `Err(SparkSdkError)` - If the nonces cannot be found or another error occurs
67 ///
68 /// # Example
69 /// ```
70 /// # // This is example code and should not be used in production
71 /// # use frost_secp256k1_tr_unofficial::round1::SigningCommitments;
72 /// # fn example(signer: &impl SparkSignerFrost, commitments: SigningCommitments) -> Result<(), SparkSdkError> {
73 /// // This should only happen during the actual signing phase of FROST
74 /// let nonces = signer.sensitive_expose_nonces_from_commitments(&commitments)?;
75 /// // Use nonces immediately for signing and then ensure they're securely erased
76 /// # Ok(())
77 /// # }
78 /// ```
79 fn sensitive_expose_nonces_from_commitments<T>(
80 &self,
81 signing_commitments: &T,
82 ) -> Result<SigningNonces, SparkSdkError>
83 where
84 T: AsRef<[u8]>;
85
86 /// Retrieves or generates nonces for the given commitments.
87 ///
88 /// This method attempts to retrieve the nonces corresponding to the provided
89 /// commitments. If the commitments are not found or are None, it generates
90 /// a new nonce pair and returns the nonces.
91 ///
92 /// # Security Warning
93 /// This method exposes sensitive cryptographic material and should be used
94 /// with the same caution as `sensitive_expose_nonces_from_commitments`.
95 ///
96 /// # Arguments
97 /// * `signing_commitments` - Optional commitments for which to retrieve nonces
98 ///
99 /// # Returns
100 /// * `Ok(SigningNonces)` - The nonces corresponding to the commitments, or newly generated nonces
101 /// * `Err(SparkSdkError)` - If an error occurs during retrieval or generation
102 fn sensitive_create_if_not_found_expose_nonces_from_commitments(
103 &self,
104 signing_commitments: Option<&[u8]>,
105 ) -> Result<SigningNonces, SparkSdkError>;
106}