spark_rust/signer/traits/
ecies.rs

1//! # ECIES encryption operations for Spark wallet
2//!
3//! This module defines the ECIES (Elliptic Curve Integrated Encryption Scheme)
4//! capabilities required for the Spark wallet. ECIES is used for secure key exchange
5//! between wallet participants, particularly during transfer operations.
6//!
7//! ECIES provides a way to:
8//! - Securely encrypt a secret key using a recipient's public key
9//! - Decrypt an encrypted secret key using the recipient's private key
10//!
11//! In Spark, this is critical for transferring funds between users, where leaf private
12//! keys need to be securely transmitted from sender to receiver.
13
14use bitcoin::{
15    secp256k1::{PublicKey, SecretKey},
16    Network,
17};
18
19use crate::error::SparkSdkError;
20
21/// Trait for ECIES encryption operations in the Spark wallet.
22///
23/// This trait provides methods for encrypting and decrypting secret keys using
24/// the ECIES (Elliptic Curve Integrated Encryption Scheme) algorithm. ECIES enables
25/// secure key exchange between users in operations like transfers, where the sender
26/// needs to securely transmit leaf private keys to the receiver.
27///
28/// The implementation follows standard ECIES practices:
29/// - Generates an ephemeral key pair
30/// - Derives a shared secret using ECDH
31/// - Uses the shared secret to encrypt/decrypt the data
32/// - Provides authenticated encryption to prevent tampering
33pub trait SparkSignerEcies {
34    /// Encrypts a secret key using the ECIES algorithm.
35    ///
36    /// This method encrypts a secret key so that only the owner of the corresponding
37    /// private key for `receiver_public_key` can decrypt it. This is typically used
38    /// during transfers to securely send leaf private keys to another user.
39    ///
40    /// # Arguments
41    /// * `receiver_public_key` - The public key of the recipient who will be able
42    ///   to decrypt the secret key. This is typically the identity public key of
43    ///   the recipient's wallet.
44    /// * `pubkey_for_sk_to_encrypt` - The public key corresponding to the secret key
45    ///   that will be encrypted. The method will find the secret key in the wallet
46    ///   based on this public key.
47    ///
48    /// # Returns
49    /// * `Ok(Vec<u8>)` - The encrypted secret key as a vector of bytes
50    /// * `Err(SparkSdkError)` - If encryption fails, typically because the secret key
51    ///   corresponding to `pubkey_for_sk_to_encrypt` cannot be found
52    ///
53    /// # Security Considerations
54    /// The encrypted data contains all necessary information for decryption by the
55    /// intended recipient, including the ephemeral public key. No pre-shared secrets
56    /// are required beyond the recipient's public key.
57    ///
58    /// # Example
59    /// ```no_run
60    /// # use spark_rust::signer::traits::ecies::SparkSignerEcies;
61    /// # use spark_rust::signer::default_signer::DefaultSigner;
62    /// # use bitcoin::secp256k1::PublicKey;
63    /// # async fn example(signer: DefaultSigner, recipient_pubkey: PublicKey, leaf_pubkey: PublicKey) -> Result<(), Box<dyn std::error::Error>> {
64    /// // Encrypt a leaf secret key for transfer to another user
65    /// let encrypted_key = signer.encrypt_secret_key_with_ecies(
66    ///     &recipient_pubkey, // The recipient's identity public key
67    ///     &leaf_pubkey       // The public key for the leaf secret key to encrypt
68    /// )?;
69    ///
70    /// // The encrypted_key can now be safely transmitted to the recipient
71    /// # Ok(())
72    /// # }
73    /// ```
74    fn encrypt_secret_key_with_ecies(
75        &self,
76        receiver_public_key: &PublicKey,
77        pubkey_for_sk_to_encrypt: &PublicKey,
78    ) -> Result<Vec<u8>, SparkSdkError>;
79
80    /// Decrypts a secret key using the ECIES algorithm.
81    ///
82    /// This method decrypts a secret key that was encrypted with the wallet's identity
83    /// public key. This is typically used during transfer receipt to obtain leaf private
84    /// keys sent by another user.
85    ///
86    /// # Arguments
87    /// * `ciphertext` - The encrypted secret key data. Can be any type that implements
88    ///                  `AsRef<[u8]>`, such as `Vec<u8>` or `&[u8]`.
89    /// * `network` - The Bitcoin network to use, which affects the derivation path for
90    ///               the identity key used in decryption.
91    ///
92    /// # Returns
93    /// * `Ok(SecretKey)` - The decrypted secret key
94    /// * `Err(SparkSdkError)` - If decryption fails, typically due to invalid ciphertext
95    ///                         or if the wallet doesn't have the correct identity private key
96    ///
97    /// # Security Considerations
98    /// This method uses the wallet's identity private key for decryption. The implementation
99    /// must ensure that this key is securely managed and that decrypted secret keys are
100    /// properly protected after decryption.
101    ///
102    /// # Example
103    /// ```no_run
104    /// # use spark_rust::signer::traits::ecies::SparkSignerEcies;
105    /// # use spark_rust::signer::default_signer::DefaultSigner;
106    /// # use bitcoin::Network;
107    /// # async fn example(signer: DefaultSigner, encrypted_key: Vec<u8>) -> Result<(), Box<dyn std::error::Error>> {
108    /// // Decrypt a secret key received from another user
109    /// let decrypted_secret_key = signer.decrypt_secret_key_with_ecies(
110    ///     encrypted_key,
111    ///     Network::Bitcoin
112    /// )?;
113    ///
114    /// // The decrypted_secret_key can now be used (typically inserted into the wallet)
115    /// # Ok(())
116    /// # }
117    /// ```
118    fn decrypt_secret_key_with_ecies<T>(
119        &self,
120        ciphertext: T,
121        network: Network,
122    ) -> Result<SecretKey, SparkSdkError>
123    where
124        T: AsRef<[u8]>;
125}