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}