breez_sdk_spark/signer/
breez.rs1use crate::error::SdkError;
2use bitcoin::bip32::{DerivationPath, Xpriv};
3use bitcoin::hashes::{Hash, HashEngine, Hmac, HmacEngine, sha256};
4use bitcoin::secp256k1::{self, Message, Secp256k1, rand::thread_rng};
5
6use super::{BreezSigner, EciesSigner, HmacSigner};
7
8pub struct BreezSignerImpl {
12 master: Xpriv,
13 secp: Secp256k1<secp256k1::All>,
14}
15
16impl BreezSignerImpl {
17 pub fn new(master: Xpriv) -> Self {
18 Self {
19 master,
20 secp: Secp256k1::new(),
21 }
22 }
23}
24
25#[macros::async_trait]
26impl BreezSigner for BreezSignerImpl {
27 async fn derive_public_key(
28 &self,
29 path: &DerivationPath,
30 ) -> Result<secp256k1::PublicKey, SdkError> {
31 let derived = self
32 .master
33 .derive_priv(&self.secp, path)
34 .map_err(|e| SdkError::Generic(e.to_string()))?;
35 Ok(derived.private_key.public_key(&self.secp))
36 }
37
38 async fn sign_ecdsa(
39 &self,
40 message: Message,
41 path: &DerivationPath,
42 ) -> Result<secp256k1::ecdsa::Signature, SdkError> {
43 let derived = self
44 .master
45 .derive_priv(&self.secp, path)
46 .map_err(|e| SdkError::Generic(e.to_string()))?;
47 Ok(self.secp.sign_ecdsa_low_r(&message, &derived.private_key))
48 }
49
50 async fn sign_ecdsa_recoverable(
51 &self,
52 message: Message,
53 path: &DerivationPath,
54 ) -> Result<secp256k1::ecdsa::RecoverableSignature, SdkError> {
55 let derived = self
56 .master
57 .derive_priv(&self.secp, path)
58 .map_err(|e| SdkError::Generic(e.to_string()))?;
59 Ok(self
60 .secp
61 .sign_ecdsa_recoverable(&message, &derived.private_key))
62 }
63
64 async fn sign_hash_schnorr(
65 &self,
66 hash: &[u8],
67 path: &DerivationPath,
68 ) -> Result<secp256k1::schnorr::Signature, SdkError> {
69 let derived = self
70 .master
71 .derive_priv(&self.secp, path)
72 .map_err(|e| SdkError::Generic(e.to_string()))?;
73 let message =
74 Message::from_digest_slice(hash).map_err(|e| SdkError::Generic(e.to_string()))?;
75 let keypair = derived.private_key.keypair(&self.secp);
76
77 let mut rng = thread_rng();
79 Ok(self
80 .secp
81 .sign_schnorr_with_rng(&message, &keypair, &mut rng))
82 }
83}
84
85#[macros::async_trait]
86impl EciesSigner for BreezSignerImpl {
87 async fn encrypt_ecies(
88 &self,
89 message: &[u8],
90 path: &DerivationPath,
91 ) -> Result<Vec<u8>, SdkError> {
92 let derived = self
93 .master
94 .derive_priv(&self.secp, path)
95 .map_err(|e| SdkError::Generic(e.to_string()))?;
96 let rc_pub = derived.private_key.public_key(&self.secp).serialize();
97 utils::ecies::encrypt(&rc_pub, message)
98 .map_err(|err| SdkError::Generic(format!("Could not encrypt data: {err}")))
99 }
100
101 async fn decrypt_ecies(
102 &self,
103 message: &[u8],
104 path: &DerivationPath,
105 ) -> Result<Vec<u8>, SdkError> {
106 let derived = self
107 .master
108 .derive_priv(&self.secp, path)
109 .map_err(|e| SdkError::Generic(e.to_string()))?;
110 let rc_prv = derived.private_key.secret_bytes();
111 utils::ecies::decrypt(&rc_prv, message)
112 .map_err(|err| SdkError::Generic(format!("Could not decrypt data: {err}")))
113 }
114}
115
116#[macros::async_trait]
117impl HmacSigner for BreezSignerImpl {
118 async fn hmac_sha256(
119 &self,
120 key_path: &DerivationPath,
121 input: &[u8],
122 ) -> Result<Hmac<sha256::Hash>, SdkError> {
123 let derived = self
124 .master
125 .derive_priv(&self.secp, key_path)
126 .map_err(|e| SdkError::Generic(e.to_string()))?;
127
128 let mut engine = HmacEngine::<sha256::Hash>::new(&derived.private_key.secret_bytes());
129 engine.input(input);
130 Ok(Hmac::<sha256::Hash>::from_engine(engine))
131 }
132}