diff --git a/swap/src/bitcoin/refund.rs b/swap/src/bitcoin/refund.rs index 3d282c99..34057c79 100644 --- a/swap/src/bitcoin/refund.rs +++ b/swap/src/bitcoin/refund.rs @@ -3,10 +3,10 @@ use crate::bitcoin::{ verify_sig, Address, EmptyWitnessStack, NoInputs, NotThreeWitnesses, PublicKey, TooManyInputs, Transaction, TxCancel, }; +use crate::{bitcoin, monero}; use ::bitcoin::util::bip143::SigHashCache; -use ::bitcoin::{SigHash, SigHashType, Txid}; +use ::bitcoin::{Script, SigHash, SigHashType, Txid}; use anyhow::{bail, Context, Result}; -use bitcoin::Script; use ecdsa_fun::Signature; use miniscript::{Descriptor, DescriptorTrait}; use std::collections::HashMap; @@ -77,7 +77,31 @@ impl TxRefund { Ok(tx_refund) } - pub fn extract_signature_by_key( + pub fn extract_monero_private_key( + &self, + published_refund_tx: bitcoin::Transaction, + s_a: monero::Scalar, + a: bitcoin::SecretKey, + S_b_bitcoin: bitcoin::PublicKey, + ) -> Result { + let s_a = monero::PrivateKey { scalar: s_a }; + + let tx_refund_sig = self + .extract_signature_by_key(published_refund_tx, a.public()) + .context("Failed to extract signature from Bitcoin refund tx")?; + let tx_refund_encsig = a.encsign(S_b_bitcoin, self.digest()); + + let s_b = bitcoin::recover(S_b_bitcoin, tx_refund_sig, tx_refund_encsig) + .context("Failed to recover Monero secret key from Bitcoin signature")?; + + let s_b = monero::private_key_from_secp256k1_scalar(s_b.into()); + + let spend_key = s_a + s_b; + + Ok(spend_key) + } + + fn extract_signature_by_key( &self, candidate_transaction: Transaction, B: PublicKey, diff --git a/swap/src/protocol/alice/steps.rs b/swap/src/protocol/alice/steps.rs index a48590ae..e6d900f4 100644 --- a/swap/src/protocol/alice/steps.rs +++ b/swap/src/protocol/alice/steps.rs @@ -2,7 +2,7 @@ use crate::bitcoin::{CancelTimelock, PunishTimelock, TxCancel, TxLock, TxRefund} use crate::protocol::alice; use crate::protocol::alice::event_loop::EventLoopHandle; use crate::{bitcoin, monero}; -use anyhow::{bail, Context, Result}; +use anyhow::{bail, Result}; pub async fn lock_xmr( state3: alice::State3, @@ -102,26 +102,3 @@ pub async fn wait_for_bitcoin_refund( } } } - -pub fn extract_monero_private_key( - published_refund_tx: bitcoin::Transaction, - tx_refund: &TxRefund, - s_a: monero::Scalar, - a: bitcoin::SecretKey, - S_b_bitcoin: bitcoin::PublicKey, -) -> Result { - let s_a = monero::PrivateKey { scalar: s_a }; - - let tx_refund_sig = tx_refund - .extract_signature_by_key(published_refund_tx, a.public()) - .context("Failed to extract signature from Bitcoin refund tx")?; - let tx_refund_encsig = a.encsign(S_b_bitcoin, tx_refund.digest()); - - let s_b = bitcoin::recover(S_b_bitcoin, tx_refund_sig, tx_refund_encsig) - .context("Failed to recover Monero secret key from Bitcoin signature")?; - let s_b = monero::private_key_from_secp256k1_scalar(s_b.into()); - - let spend_key = s_a + s_b; - - Ok(spend_key) -} diff --git a/swap/src/protocol/alice/swap.rs b/swap/src/protocol/alice/swap.rs index b7ddd77b..fcd5885f 100644 --- a/swap/src/protocol/alice/swap.rs +++ b/swap/src/protocol/alice/swap.rs @@ -7,7 +7,7 @@ use crate::monero_ext::ScalarExt; use crate::protocol::alice; use crate::protocol::alice::event_loop::EventLoopHandle; use crate::protocol::alice::steps::{ - extract_monero_private_key, lock_xmr, publish_cancel_transaction, wait_for_bitcoin_refund, + lock_xmr, publish_cancel_transaction, wait_for_bitcoin_refund, }; use crate::protocol::alice::AliceState; use crate::{bitcoin, database, monero}; @@ -315,9 +315,8 @@ async fn run_until_internal( .await } Some(published_refund_tx) => { - let spend_key = extract_monero_private_key( + let spend_key = state3.tx_refund().extract_monero_private_key( published_refund_tx, - &state3.tx_refund(), state3.s_a, state3.a.clone(), state3.S_b_bitcoin, @@ -393,9 +392,8 @@ async fn run_until_internal( let published_refund_tx = bitcoin_wallet.get_raw_transaction(tx_refund.txid()).await?; - let spend_key = extract_monero_private_key( + let spend_key = tx_refund.extract_monero_private_key( published_refund_tx, - &tx_refund, state3.s_a, state3.a.clone(), state3.S_b_bitcoin,