diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4920d97f..1493361a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -91,6 +91,4 @@ jobs: - name: Cargo test run: cargo test --workspace --all-features env: - # To avoid stack overflows - RUST_MIN_STACK: 100000000 MONERO_ADDITIONAL_SLEEP_PERIOD: 60000 diff --git a/xmr-btc/Cargo.toml b/xmr-btc/Cargo.toml index 40373456..e95bc5a7 100644 --- a/xmr-btc/Cargo.toml +++ b/xmr-btc/Cargo.toml @@ -10,7 +10,7 @@ edition = "2018" anyhow = "1" async-trait = "0.1" bitcoin = { version = "0.23", features = ["rand", "serde"] } -cross-curve-dleq = { git = "https://github.com/comit-network/cross-curve-dleq", rev = "1931c0436f259e1a1f53a4ec8acbbaaf614bd1e4", features = ["serde"] } +cross-curve-dleq = { git = "https://github.com/comit-network/cross-curve-dleq", rev = "a19608734da1e8803cb4c806022483df4e7d5588", features = ["serde"] } curve25519-dalek = "2" ecdsa_fun = { git = "https://github.com/LLFourn/secp256kfun", rev = "510d48ef6a2b19805f7f5c70c598e5b03f668e7a", features = ["libsecp_compat", "serde", "serialization"] } ed25519-dalek = { version = "1.0.0-pre.4", features = ["serde"] }# Cannot be 1 because they depend on curve25519-dalek version 3 diff --git a/xmr-btc/src/alice.rs b/xmr-btc/src/alice.rs index b6392b04..99859e8d 100644 --- a/xmr-btc/src/alice.rs +++ b/xmr-btc/src/alice.rs @@ -300,9 +300,7 @@ where let s_b = bitcoin::recover(S_b_bitcoin, tx_refund_sig, tx_refund_encsig) .map_err(|_| RefundFailed::SecretRecovery)?; - let s_b = monero::PrivateKey::from_scalar(monero::Scalar::from_bytes_mod_order( - s_b.to_bytes(), - )); + let s_b = monero::private_key_from_secp256k1_scalar(s_b.into()); co.yield_(Action::CreateMoneroWalletForOutput { spend_key: s_a + s_b, @@ -923,8 +921,7 @@ impl State5 { tx_refund.extract_signature_by_key(tx_refund_candidate, self.a.public())?; let s_b = bitcoin::recover(self.S_b_bitcoin, tx_refund_sig, tx_refund_encsig)?; - let s_b = - monero::PrivateKey::from_scalar(monero::Scalar::from_bytes_mod_order(s_b.to_bytes())); + let s_b = monero::private_key_from_secp256k1_scalar(s_b.into()); let s = s_b.scalar + self.s_a.into_ed25519(); diff --git a/xmr-btc/src/bitcoin.rs b/xmr-btc/src/bitcoin.rs index da75fd6f..e5e6ca6b 100644 --- a/xmr-btc/src/bitcoin.rs +++ b/xmr-btc/src/bitcoin.rs @@ -8,12 +8,7 @@ use bitcoin::{ util::psbt::PartiallySignedTransaction, SigHash, }; -use ecdsa_fun::{ - adaptor::Adaptor, - fun::{Point, Scalar}, - nonce::Deterministic, - ECDSA, -}; +use ecdsa_fun::{adaptor::Adaptor, fun::Point, nonce::Deterministic, ECDSA}; use miniscript::{Descriptor, Segwitv0}; use rand::{CryptoRng, RngCore}; use serde::{Deserialize, Serialize}; @@ -22,7 +17,7 @@ use std::str::FromStr; pub use crate::bitcoin::transactions::{TxCancel, TxLock, TxPunish, TxRedeem, TxRefund}; pub use bitcoin::{Address, Amount, OutPoint, Transaction, Txid}; -pub use ecdsa_fun::{adaptor::EncryptedSignature, Signature}; +pub use ecdsa_fun::{adaptor::EncryptedSignature, fun::Scalar, Signature}; pub const TX_FEE: u64 = 10_000; @@ -102,6 +97,12 @@ impl From for SecretKey { } } +impl From for Scalar { + fn from(sk: SecretKey) -> Self { + sk.inner + } +} + impl From for PublicKey { fn from(scalar: Scalar) -> Self { let ecdsa = ECDSA::<()>::default(); diff --git a/xmr-btc/src/bob.rs b/xmr-btc/src/bob.rs index 8039a250..89cb6492 100644 --- a/xmr-btc/src/bob.rs +++ b/xmr-btc/src/bob.rs @@ -196,9 +196,7 @@ where .map_err(|_| SwapFailed::AfterBtcRedeem(Reason::BtcRedeemSignature))?; let s_a = bitcoin::recover(S_a_bitcoin, tx_redeem_sig, tx_redeem_encsig) .map_err(|_| SwapFailed::AfterBtcRedeem(Reason::SecretRecovery))?; - let s_a = monero::PrivateKey::from_scalar(monero::Scalar::from_bytes_mod_order( - s_a.to_bytes(), - )); + let s_a = monero::private_key_from_secp256k1_scalar(s_a.into()); let s_b = monero::PrivateKey { scalar: s_b.into_ed25519(), @@ -724,8 +722,7 @@ impl State4 { let tx_redeem_sig = tx_redeem.extract_signature_by_key(tx_redeem_candidate, self.b.public())?; let s_a = bitcoin::recover(self.S_a_bitcoin.clone(), tx_redeem_sig, tx_redeem_encsig)?; - let s_a = - monero::PrivateKey::from_scalar(monero::Scalar::from_bytes_mod_order(s_a.to_bytes())); + let s_a = monero::private_key_from_secp256k1_scalar(s_a.into()); Ok(State5 { A: self.A, diff --git a/xmr-btc/src/monero.rs b/xmr-btc/src/monero.rs index 3a57b9d4..ca55b904 100644 --- a/xmr-btc/src/monero.rs +++ b/xmr-btc/src/monero.rs @@ -15,6 +15,16 @@ pub fn random_private_key(rng: &mut R) -> PrivateKey { PrivateKey::from_scalar(scalar) } +pub fn private_key_from_secp256k1_scalar(scalar: crate::bitcoin::Scalar) -> PrivateKey { + let mut bytes = scalar.to_bytes(); + + // we must reverse the bytes because a secp256k1 scalar is big endian, whereas a + // ed25519 scalar is little endian + bytes.reverse(); + + PrivateKey::from_scalar(Scalar::from_bytes_mod_order(bytes)) +} + #[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq)] pub struct PrivateViewKey(#[serde(with = "monero_private_key")] PrivateKey); diff --git a/xmr-btc/tests/e2e.rs b/xmr-btc/tests/e2e.rs index c20655b2..4c93bd47 100644 --- a/xmr-btc/tests/e2e.rs +++ b/xmr-btc/tests/e2e.rs @@ -1,11 +1,6 @@ pub mod harness; mod tests { - // NOTE: For some reason running these tests overflows the stack. In order to - // mitigate this run them with: - // - // RUST_MIN_STACK=100000000 cargo test - use crate::{ harness, harness::{ diff --git a/xmr-btc/tests/on_chain.rs b/xmr-btc/tests/on_chain.rs index 7bec0e9e..aa8adc61 100644 --- a/xmr-btc/tests/on_chain.rs +++ b/xmr-btc/tests/on_chain.rs @@ -230,11 +230,6 @@ async fn swap_as_bob( } } -// NOTE: For some reason running these tests overflows the stack. In order to -// mitigate this run them with: -// -// RUST_MIN_STACK=100000000 cargo test - #[tokio::test] async fn on_chain_happy_path() { let cli = Cli::default();