From 9ea708b2a5eaad468f67bceb439cf6c78138a19c Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Thu, 22 Oct 2020 15:06:05 +1100 Subject: [PATCH 1/5] Remove custom implementation of bitcoin amount serde This is unnecessary as rust-bitcoin provides it. --- swap/src/storage.rs | 7 ++----- xmr-btc/src/alice.rs | 15 +++++++-------- xmr-btc/src/bob.rs | 16 ++++++++-------- xmr-btc/src/serde.rs | 32 -------------------------------- 4 files changed, 17 insertions(+), 53 deletions(-) diff --git a/swap/src/storage.rs b/swap/src/storage.rs index 86581fc0..0cf2f6b5 100644 --- a/swap/src/storage.rs +++ b/swap/src/storage.rs @@ -81,10 +81,7 @@ mod tests { use rand::rngs::OsRng; use serde::{Deserialize, Serialize}; use std::str::FromStr; - use xmr_btc::{ - serde::{bitcoin_amount, monero_private_key}, - CrossCurveScalar, Curve25519Scalar, - }; + use xmr_btc::serde::monero_private_key; #[derive(Debug, Serialize, Deserialize, PartialEq)] pub struct TestState { @@ -96,7 +93,7 @@ mod tests { S_a_monero: ::monero::PublicKey, S_a_bitcoin: xmr_btc::bitcoin::PublicKey, v: xmr_btc::monero::PrivateViewKey, - #[serde(with = "bitcoin_amount")] + #[serde(with = "::bitcoin::util::amount::serde::as_sat")] btc: ::bitcoin::Amount, xmr: xmr_btc::monero::Amount, refund_timelock: u32, diff --git a/xmr-btc/src/alice.rs b/xmr-btc/src/alice.rs index e94062f1..938b455e 100644 --- a/xmr-btc/src/alice.rs +++ b/xmr-btc/src/alice.rs @@ -3,7 +3,6 @@ use crate::{ bitcoin::{BroadcastSignedTransaction, WatchForRawTransaction}, bob, monero, monero::{CreateWalletForOutput, Transfer}, - serde::bitcoin_amount, transport::{ReceiveMessage, SendMessage}, }; use anyhow::{anyhow, Result}; @@ -137,7 +136,7 @@ pub struct State0 { //#[serde(with = "cross_curve_dleq_scalar")] s_a: cross_curve_dleq::Scalar, v_a: monero::PrivateViewKey, - #[serde(with = "bitcoin_amount")] + #[serde(with = "::bitcoin::util::amount::serde::as_sat")] btc: bitcoin::Amount, xmr: monero::Amount, refund_timelock: u32, @@ -227,7 +226,7 @@ pub struct State1 { S_b_monero: monero::PublicKey, S_b_bitcoin: bitcoin::PublicKey, v: monero::PrivateViewKey, - #[serde(with = "bitcoin_amount")] + #[serde(with = "::bitcoin::util::amount::serde::as_sat")] btc: bitcoin::Amount, xmr: monero::Amount, refund_timelock: u32, @@ -266,7 +265,7 @@ pub struct State2 { S_b_monero: monero::PublicKey, S_b_bitcoin: bitcoin::PublicKey, v: monero::PrivateViewKey, - #[serde(with = "bitcoin_amount")] + #[serde(with = "::bitcoin::util::amount::serde::as_sat")] btc: bitcoin::Amount, xmr: monero::Amount, refund_timelock: u32, @@ -342,7 +341,7 @@ pub struct State3 { pub S_b_monero: monero::PublicKey, pub S_b_bitcoin: bitcoin::PublicKey, pub v: monero::PrivateViewKey, - #[serde(with = "bitcoin_amount")] + #[serde(with = "::bitcoin::util::amount::serde::as_sat")] pub btc: bitcoin::Amount, pub xmr: monero::Amount, pub refund_timelock: u32, @@ -396,7 +395,7 @@ pub struct State4 { S_b_monero: monero::PublicKey, S_b_bitcoin: bitcoin::PublicKey, v: monero::PrivateViewKey, - #[serde(with = "bitcoin_amount")] + #[serde(with = "::bitcoin::util::amount::serde::as_sat")] btc: bitcoin::Amount, xmr: monero::Amount, refund_timelock: u32, @@ -500,7 +499,7 @@ pub struct State5 { S_b_monero: monero::PublicKey, S_b_bitcoin: bitcoin::PublicKey, v: monero::PrivateViewKey, - #[serde(with = "bitcoin_amount")] + #[serde(with = "::bitcoin::util::amount::serde::as_sat")] btc: bitcoin::Amount, xmr: monero::Amount, refund_timelock: u32, @@ -594,7 +593,7 @@ pub struct State6 { S_b_monero: monero::PublicKey, S_b_bitcoin: bitcoin::PublicKey, v: monero::PrivateViewKey, - #[serde(with = "bitcoin_amount")] + #[serde(with = "::bitcoin::util::amount::serde::as_sat")] btc: bitcoin::Amount, xmr: monero::Amount, refund_timelock: u32, diff --git a/xmr-btc/src/bob.rs b/xmr-btc/src/bob.rs index d2df8558..5f4f0f44 100644 --- a/xmr-btc/src/bob.rs +++ b/xmr-btc/src/bob.rs @@ -5,8 +5,7 @@ use crate::{ WatchForRawTransaction, }, monero, - monero::{CreateWalletForOutput, WatchForTransfer}, - serde::{bitcoin_amount, monero_private_key}, + serde::monero_private_key, transport::{ReceiveMessage, SendMessage}, }; use anyhow::{anyhow, Result}; @@ -21,6 +20,7 @@ use sha2::Sha256; use std::convert::{TryFrom, TryInto}; pub mod message; +use crate::monero::{CreateWalletForOutput, WatchForTransfer}; pub use message::{Message, Message0, Message1, Message2, Message3}; // There are no guarantees that send_message and receive_massage do not block @@ -111,7 +111,7 @@ pub struct State0 { b: bitcoin::SecretKey, s_b: cross_curve_dleq::Scalar, v_b: monero::PrivateViewKey, - #[serde(with = "bitcoin_amount")] + #[serde(with = "::bitcoin::util::amount::serde::as_sat")] btc: bitcoin::Amount, xmr: monero::Amount, refund_timelock: u32, @@ -203,7 +203,7 @@ pub struct State1 { S_a_monero: monero::PublicKey, S_a_bitcoin: bitcoin::PublicKey, v: monero::PrivateViewKey, - #[serde(with = "bitcoin_amount")] + #[serde(with = "::bitcoin::util::amount::serde::as_sat")] btc: bitcoin::Amount, xmr: monero::Amount, refund_timelock: u32, @@ -267,7 +267,7 @@ pub struct State2 { pub S_a_monero: monero::PublicKey, pub S_a_bitcoin: bitcoin::PublicKey, pub v: monero::PrivateViewKey, - #[serde(with = "bitcoin_amount")] + #[serde(with = "::bitcoin::util::amount::serde::as_sat")] btc: bitcoin::Amount, pub xmr: monero::Amount, pub refund_timelock: u32, @@ -339,7 +339,7 @@ pub struct State3 { S_a_monero: monero::PublicKey, S_a_bitcoin: bitcoin::PublicKey, v: monero::PrivateViewKey, - #[serde(with = "bitcoin_amount")] + #[serde(with = "::bitcoin::util::amount::serde::as_sat")] btc: bitcoin::Amount, xmr: monero::Amount, refund_timelock: u32, @@ -451,7 +451,7 @@ pub struct State4 { S_a_monero: monero::PublicKey, S_a_bitcoin: bitcoin::PublicKey, v: monero::PrivateViewKey, - #[serde(with = "bitcoin_amount")] + #[serde(with = "::bitcoin::util::amount::serde::as_sat")] btc: bitcoin::Amount, xmr: monero::Amount, refund_timelock: u32, @@ -521,7 +521,7 @@ pub struct State5 { S_a_monero: monero::PublicKey, S_a_bitcoin: bitcoin::PublicKey, v: monero::PrivateViewKey, - #[serde(with = "bitcoin_amount")] + #[serde(with = "::bitcoin::util::amount::serde::as_sat")] btc: bitcoin::Amount, xmr: monero::Amount, refund_timelock: u32, diff --git a/xmr-btc/src/serde.rs b/xmr-btc/src/serde.rs index a9b5a595..c35894a5 100644 --- a/xmr-btc/src/serde.rs +++ b/xmr-btc/src/serde.rs @@ -41,28 +41,6 @@ pub mod monero_private_key { } } -pub mod bitcoin_amount { - use bitcoin::Amount; - use serde::{Deserialize, Deserializer, Serializer}; - - pub fn serialize(x: &Amount, s: S) -> Result - where - S: Serializer, - { - s.serialize_u64(x.as_sat()) - } - - pub fn deserialize<'de, D>(deserializer: D) -> Result>::Error> - where - D: Deserializer<'de>, - { - let sats = u64::deserialize(deserializer)?; - let amount = Amount::from_sat(sats); - - Ok(amount) - } -} - pub mod monero_amount { use crate::monero::Amount; use serde::{Deserialize, Deserializer, Serializer}; @@ -95,9 +73,6 @@ mod tests { #[derive(Debug, Serialize, Deserialize, PartialEq)] pub struct MoneroPrivateKey(#[serde(with = "monero_private_key")] crate::monero::PrivateKey); - #[derive(Debug, Serialize, Deserialize, PartialEq)] - pub struct BitcoinAmount(#[serde(with = "bitcoin_amount")] ::bitcoin::Amount); - #[test] fn serde_monero_private_key() { let key = MoneroPrivateKey(monero::PrivateKey::from_scalar(Scalar::random(&mut OsRng))); @@ -105,11 +80,4 @@ mod tests { let decoded: MoneroPrivateKey = serde_cbor::from_slice(&encoded).unwrap(); assert_eq!(key, decoded); } - #[test] - fn serde_bitcoin_amount() { - let amount = BitcoinAmount(::bitcoin::Amount::from_sat(100)); - let encoded = serde_cbor::to_vec(&amount).unwrap(); - let decoded: BitcoinAmount = serde_cbor::from_slice(&encoded).unwrap(); - assert_eq!(amount, decoded); - } } From 82b092d86e5585289ea944b62e5284baffad4a98 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Thu, 22 Oct 2020 15:33:57 +1100 Subject: [PATCH 2/5] Use consensus encoding for monero private key Using consensus encoding future proof the library by using a commonly accepted de/serialization format. --- xmr-btc/src/serde.rs | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/xmr-btc/src/serde.rs b/xmr-btc/src/serde.rs index c35894a5..d8ede708 100644 --- a/xmr-btc/src/serde.rs +++ b/xmr-btc/src/serde.rs @@ -1,38 +1,42 @@ pub mod monero_private_key { - use serde::{de, de::Visitor, Deserializer, Serializer}; - use std::fmt; + use monero::{ + consensus::{Decodable, Encodable}, + PrivateKey, + }; + use serde::{de, de::Visitor, ser::Error, Deserializer, Serializer}; + use std::{fmt, io::Cursor}; struct BytesVisitor; impl<'de> Visitor<'de> for BytesVisitor { - type Value = monero::PrivateKey; + type Value = PrivateKey; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(formatter, "a string containing 32 bytes") + write!(formatter, "a byte array representing a Monero private key") } fn visit_bytes(self, s: &[u8]) -> Result where E: de::Error, { - if let Ok(key) = monero::PrivateKey::from_slice(s) { - Ok(key) - } else { - Err(de::Error::invalid_length(s.len(), &self)) - } + let mut s = s; + PrivateKey::consensus_decode(&mut s).map_err(|err| E::custom(format!("{:?}", err))) } } - pub fn serialize(x: &monero::PrivateKey, s: S) -> Result + pub fn serialize(x: &PrivateKey, s: S) -> Result where S: Serializer, { - s.serialize_bytes(x.as_bytes()) + let mut bytes = Cursor::new(vec![]); + x.consensus_encode(&mut bytes) + .map_err(|err| S::Error::custom(format!("{:?}", err)))?; + s.serialize_bytes(bytes.into_inner().as_ref()) } pub fn deserialize<'de, D>( deserializer: D, - ) -> Result>::Error> + ) -> Result>::Error> where D: Deserializer<'de>, { From 28ffe063b771adebc0d075a82c1872961f9e49d3 Mon Sep 17 00:00:00 2001 From: rishflab Date: Mon, 26 Oct 2020 11:11:00 +1100 Subject: [PATCH 3/5] Remove stale comment --- xmr-btc/src/alice.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/xmr-btc/src/alice.rs b/xmr-btc/src/alice.rs index 938b455e..73d83976 100644 --- a/xmr-btc/src/alice.rs +++ b/xmr-btc/src/alice.rs @@ -133,7 +133,6 @@ impl State { #[derive(Clone, Debug, Deserialize, Serialize)] pub struct State0 { a: bitcoin::SecretKey, - //#[serde(with = "cross_curve_dleq_scalar")] s_a: cross_curve_dleq::Scalar, v_a: monero::PrivateViewKey, #[serde(with = "::bitcoin::util::amount::serde::as_sat")] From fea6b29da922553ca672cef5ca640bc8565ca935 Mon Sep 17 00:00:00 2001 From: rishflab Date: Mon, 26 Oct 2020 11:14:03 +1100 Subject: [PATCH 4/5] Test monero amount serialisation --- swap/src/storage.rs | 1 + xmr-btc/src/serde.rs | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/swap/src/storage.rs b/swap/src/storage.rs index 0cf2f6b5..0f6f2517 100644 --- a/swap/src/storage.rs +++ b/swap/src/storage.rs @@ -82,6 +82,7 @@ mod tests { use serde::{Deserialize, Serialize}; use std::str::FromStr; use xmr_btc::serde::monero_private_key; + use xmr_btc::{CrossCurveScalar, Curve25519Scalar}; #[derive(Debug, Serialize, Deserialize, PartialEq)] pub struct TestState { diff --git a/xmr-btc/src/serde.rs b/xmr-btc/src/serde.rs index d8ede708..d1772ae7 100644 --- a/xmr-btc/src/serde.rs +++ b/xmr-btc/src/serde.rs @@ -77,6 +77,9 @@ mod tests { #[derive(Debug, Serialize, Deserialize, PartialEq)] pub struct MoneroPrivateKey(#[serde(with = "monero_private_key")] crate::monero::PrivateKey); + #[derive(Debug, Serialize, Deserialize, PartialEq)] + pub struct MoneroAmount(#[serde(with = "monero_amount")] crate::monero::Amount); + #[test] fn serde_monero_private_key() { let key = MoneroPrivateKey(monero::PrivateKey::from_scalar(Scalar::random(&mut OsRng))); @@ -84,4 +87,12 @@ mod tests { let decoded: MoneroPrivateKey = serde_cbor::from_slice(&encoded).unwrap(); assert_eq!(key, decoded); } + + #[test] + fn serde_monero_amount() { + let amount = MoneroAmount(crate::monero::Amount::from_piconero(1000)); + let encoded = serde_cbor::to_vec(&amount).unwrap(); + let decoded: MoneroAmount = serde_cbor::from_slice(&encoded).unwrap(); + assert_eq!(amount, decoded); + } } From ec71f98252bff34b7310e10a65bd463d8014fe3a Mon Sep 17 00:00:00 2001 From: rishflab Date: Mon, 26 Oct 2020 11:45:27 +1100 Subject: [PATCH 5/5] Revert re-imports to qualified paths --- swap/src/storage.rs | 10 +++++----- xmr-btc/src/lib.rs | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/swap/src/storage.rs b/swap/src/storage.rs index 0f6f2517..b6bfca3c 100644 --- a/swap/src/storage.rs +++ b/swap/src/storage.rs @@ -81,14 +81,13 @@ mod tests { use rand::rngs::OsRng; use serde::{Deserialize, Serialize}; use std::str::FromStr; - use xmr_btc::serde::monero_private_key; - use xmr_btc::{CrossCurveScalar, Curve25519Scalar}; + use xmr_btc::{cross_curve_dleq, curve25519_dalek, serde::monero_private_key}; #[derive(Debug, Serialize, Deserialize, PartialEq)] pub struct TestState { A: xmr_btc::bitcoin::PublicKey, a: xmr_btc::bitcoin::SecretKey, - s_a: CrossCurveScalar, + s_a: cross_curve_dleq::Scalar, #[serde(with = "monero_private_key")] s_b: monero::PrivateKey, S_a_monero: ::monero::PublicKey, @@ -109,8 +108,9 @@ mod tests { let db = Database::open(db_dir.path()).unwrap(); let a = xmr_btc::bitcoin::SecretKey::new_random(&mut OsRng); - let s_a = CrossCurveScalar::random(&mut OsRng); - let s_b = monero::PrivateKey::from_scalar(Curve25519Scalar::random(&mut OsRng)); + let s_a = cross_curve_dleq::Scalar::random(&mut OsRng); + let s_b = + monero::PrivateKey::from_scalar(curve25519_dalek::scalar::Scalar::random(&mut OsRng)); let v_a = xmr_btc::monero::PrivateViewKey::new_random(&mut OsRng); let S_a_monero = monero::PublicKey::from_private_key(&monero::PrivateKey { scalar: s_a.into_ed25519(), diff --git a/xmr-btc/src/lib.rs b/xmr-btc/src/lib.rs index 6a14fce6..f2effbb5 100644 --- a/xmr-btc/src/lib.rs +++ b/xmr-btc/src/lib.rs @@ -52,8 +52,8 @@ pub mod monero; pub mod serde; pub mod transport; -pub use cross_curve_dleq::Scalar as CrossCurveScalar; -pub use curve25519_dalek::scalar::Scalar as Curve25519Scalar; +pub use cross_curve_dleq; +pub use curve25519_dalek; use async_trait::async_trait; use ecdsa_fun::{adaptor::Adaptor, nonce::Deterministic};