From 84bc2c82b7348bd2c7c7a4fb73773e0ab85ebdd3 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 18 Feb 2021 13:33:50 +1100 Subject: [PATCH 1/3] Upgrade to bdk 4.0 To achieve this we also: - upgrade rust-bitcoin to 0.26 - upgrade bitcoin-harness to latest version (which also depends bitcoin 0.26) - upgrade to latest edcsa-fun - replace cross_curve_dleq proof with sigma_fun (to avoid an upgrade dance over there) --- Cargo.lock | 248 +++++++++------------ swap/Cargo.toml | 17 +- swap/src/bitcoin.rs | 26 ++- swap/src/bitcoin/cancel.rs | 8 +- swap/src/bitcoin/lock.rs | 8 +- swap/src/bitcoin/punish.rs | 6 +- swap/src/bitcoin/redeem.rs | 6 +- swap/src/bitcoin/refund.rs | 6 +- swap/src/bitcoin/wallet.rs | 14 +- swap/src/lib.rs | 1 + swap/src/monero_ext.rs | 20 ++ swap/src/protocol/alice/execution_setup.rs | 3 +- swap/src/protocol/alice/state.rs | 90 +++++--- swap/src/protocol/alice/steps.rs | 23 +- swap/src/protocol/alice/swap.rs | 3 +- swap/src/protocol/bob/execution_setup.rs | 3 +- swap/src/protocol/bob/state.rs | 90 +++++--- swap/tests/testutils/electrs.rs | 1 + 18 files changed, 310 insertions(+), 263 deletions(-) create mode 100644 swap/src/monero_ext.rs diff --git a/Cargo.lock b/Cargo.lock index 3249c494..4148fd36 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -163,11 +163,11 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb4401f0a3622dad2e0763fa79e0eb328bc70fb7dccfdd645341f00d671247d6" dependencies = [ - "bytes 1.0.1", + "bytes", "futures-sink", "futures-util", "memchr", - "pin-project-lite 0.2.4", + "pin-project-lite", ] [[package]] @@ -212,7 +212,7 @@ dependencies = [ "instant", "pin-project 1.0.4", "rand 0.8.2", - "tokio 1.0.2", + "tokio", ] [[package]] @@ -253,9 +253,9 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] name = "bdk" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2fd4c84e2baef750794e7c3f317e37c0c611ef7b29c9a9f18c7e51940dbfdb5" +checksum = "daeccaea73c9fc27e218e2a4402070707fb8354afd30fecd4a1c9a0bea8b79c4" dependencies = [ "async-trait", "bdk-macros", @@ -268,14 +268,14 @@ dependencies = [ "serde", "serde_json", "sled", - "tokio 0.2.25", + "tokio", ] [[package]] name = "bdk-macros" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f62874901df222eb0fc3bad6e425bc2a935287b8110be0d1ad6d729af86cf6e1" +checksum = "b96757dbe9c7e0a8f0635c5366464d9c713528e111f47490e96385f70d6a67a6" dependencies = [ "proc-macro2", "quote", @@ -289,16 +289,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdcf67bb7ba7797a081cd19009948ab533af7c355d5caf1d08c777582d351e9c" [[package]] -name = "bit-vec" -version = "0.6.3" +name = "bincode" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +checksum = "f30d3a39baa26f9651f17b375061f3233dde33424a8b72b0dbe93a68a0bc896d" +dependencies = [ + "byteorder", + "serde", +] [[package]] name = "bitcoin" -version = "0.25.2" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aefc9be9f17185f4ebccae6575d342063f775924d57df0000edb1880c0fb7095" +checksum = "1ec5f88a446d66e7474a3b8fa2e348320b574463fb78d799d90ba68f79f48e0e" dependencies = [ "bech32", "bitcoin_hashes", @@ -309,7 +313,7 @@ dependencies = [ [[package]] name = "bitcoin-harness" version = "0.2.0" -source = "git+https://github.com/coblox/bitcoin-harness-rs?rev=ae2f6cd547496e680941c0910018bbe884128799#ae2f6cd547496e680941c0910018bbe884128799" +source = "git+https://github.com/coblox/bitcoin-harness-rs#640acbf079c728231866b59cd830770b64871cc0" dependencies = [ "async-trait", "base64 0.12.3", @@ -323,7 +327,7 @@ dependencies = [ "serde_json", "testcontainers 0.11.0", "thiserror", - "tokio 1.0.2", + "tokio", "tracing", "url", ] @@ -339,9 +343,9 @@ dependencies = [ [[package]] name = "bitcoincore-rpc-json" -version = "0.12.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d488ec31e9cb6726c361be5160f7d2aaace89a0681acf1f476b8fada770b6e" +checksum = "977e55a945ab1e3c446dea93267876703c15e07c7d6eeb1dfa1766b3190c560f" dependencies = [ "bitcoin", "hex 0.3.2", @@ -468,12 +472,6 @@ version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b" -[[package]] -name = "bytes" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" - [[package]] name = "bytes" version = "1.0.1" @@ -652,23 +650,6 @@ dependencies = [ "cfg-if 1.0.0", ] -[[package]] -name = "cross-curve-dleq" -version = "0.1.0" -source = "git+https://github.com/comit-network/cross-curve-dleq?rev=eddcdea1d1f16fa33ef581d1744014ece535c920#eddcdea1d1f16fa33ef581d1744014ece535c920" -dependencies = [ - "bit-vec", - "curve25519-dalek 2.1.2", - "ecdsa_fun", - "generic-array 0.14.4", - "hex-literal", - "lazy_static", - "rand 0.7.3", - "serde", - "sha2 0.9.2", - "thiserror", -] - [[package]] name = "crossbeam-epoch" version = "0.9.1" @@ -758,20 +739,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "curve25519-dalek" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "434e1720189a637d44fe464f4df1e6eb900b4835255b14354497c78af37d9bb8" -dependencies = [ - "byteorder", - "digest 0.8.1", - "rand_core 0.5.1", - "serde", - "subtle 2.4.0", - "zeroize 1.2.0", -] - [[package]] name = "curve25519-dalek" version = "3.0.2" @@ -781,6 +748,7 @@ dependencies = [ "byteorder", "digest 0.9.0", "rand_core 0.5.1", + "serde", "subtle 2.4.0", "zeroize 1.2.0", ] @@ -885,11 +853,14 @@ checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" [[package]] name = "ecdsa_fun" -version = "0.3.2-alpha.0" -source = "git+https://github.com/LLFourn/secp256kfun?rev=cdfbc766045ea678a41780919d6228dd5acee3be#cdfbc766045ea678a41780919d6228dd5acee3be" +version = "0.4.2-alpha.0" +source = "git+https://github.com/LLFourn/secp256kfun#8538ef22498170960a9769df2700c1986cc540fd" dependencies = [ + "bincode", + "rand_chacha 0.2.2", "secp256kfun", "serde", + "sigma_fun", ] [[package]] @@ -908,7 +879,7 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" dependencies = [ - "curve25519-dalek 3.0.2", + "curve25519-dalek", "ed25519", "rand 0.7.3", "serde", @@ -925,9 +896,9 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "electrum-client" -version = "0.5.0-beta.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aedfb48f66ab17ba3b2c69f8ff32f68d8b5dbc7839c0ca4e94237b835ca608dd" +checksum = "21453800c95bb1aaa57490458c42d60c6277cb8a3e386030ec2381d5c2d4fa77" dependencies = [ "bitcoin", "log", @@ -1154,7 +1125,7 @@ dependencies = [ "futures-io", "memchr", "parking", - "pin-project-lite 0.2.4", + "pin-project-lite", "waker-fn", ] @@ -1204,7 +1175,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project-lite 0.2.4", + "pin-project-lite", "pin-utils", "proc-macro-hack", "proc-macro-nested", @@ -1235,6 +1206,7 @@ version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" dependencies = [ + "serde", "typenum", "version_check", ] @@ -1285,7 +1257,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b67e66362108efccd8ac053abafc8b7a8d86a37e6e48fc4f6f7485eb5e9e6a5" dependencies = [ - "bytes 1.0.1", + "bytes", "fnv", "futures-core", "futures-sink", @@ -1293,7 +1265,7 @@ dependencies = [ "http", "indexmap", "slab", - "tokio 1.0.2", + "tokio", "tokio-util", "tracing", "tracing-futures", @@ -1353,25 +1325,6 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35" -[[package]] -name = "hex-literal" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "961de220ec9a91af2e1e5bd80d02109155695e516771762381ef8581317066e0" -dependencies = [ - "hex-literal-impl", - "proc-macro-hack", -] - -[[package]] -name = "hex-literal-impl" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "853f769599eb31de176303197b7ba4973299c38c7a7604a6bc88c3eef05b9b46" -dependencies = [ - "proc-macro-hack", -] - [[package]] name = "hmac" version = "0.7.1" @@ -1419,7 +1372,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7245cd7449cc792608c3c8a9eaf69bd4eabbabf802713748fd739c98b82f0747" dependencies = [ - "bytes 1.0.1", + "bytes", "fnv", "itoa", ] @@ -1430,7 +1383,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2861bd27ee074e5ee891e8b539837a9430012e249d7f0ca2d795650f579c1994" dependencies = [ - "bytes 1.0.1", + "bytes", "http", ] @@ -1452,7 +1405,7 @@ version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12219dc884514cb4a6a03737f4413c0e01c23a1b059b0156004b23f1e19dccbe" dependencies = [ - "bytes 1.0.1", + "bytes", "futures-channel", "futures-core", "futures-util", @@ -1464,7 +1417,7 @@ dependencies = [ "itoa", "pin-project 1.0.4", "socket2", - "tokio 1.0.2", + "tokio", "tower-service", "tracing", "want", @@ -1476,10 +1429,10 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ - "bytes 1.0.1", + "bytes", "hyper", "native-tls", - "tokio 1.0.2", + "tokio", "tokio-native-tls", ] @@ -1592,7 +1545,8 @@ dependencies = [ [[package]] name = "jsonrpc_client" version = "0.5.0" -source = "git+https://github.com/thomaseizinger/rust-jsonrpc-client?rev=f60c839481c1ac68909ada0141a3a3bf085bb1af#f60c839481c1ac68909ada0141a3a3bf085bb1af" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb8fc4b9e0b44f34346238c1e39e59067747ae7913b2e3d903b56e6c2c8062" dependencies = [ "async-trait", "jsonrpc_client_macro", @@ -1605,7 +1559,8 @@ dependencies = [ [[package]] name = "jsonrpc_client_macro" version = "0.2.0" -source = "git+https://github.com/thomaseizinger/rust-jsonrpc-client?rev=f60c839481c1ac68909ada0141a3a3bf085bb1af#f60c839481c1ac68909ada0141a3a3bf085bb1af" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f3d1e50fefe4252d2e44c805663e73a8c0b2002b73f834ea055c8ed7fc46a8" dependencies = [ "quote", "syn", @@ -1663,7 +1618,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5133112ce42be9482f6a87be92a605dd6bbc9e93c297aee77d172ff06908f3a" dependencies = [ "atomic", - "bytes 1.0.1", + "bytes", "futures", "lazy_static", "libp2p-core", @@ -1753,7 +1708,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2705dc94b01ab9e3779b42a09bbf3712e637ed213e875c30face247291a85af0" dependencies = [ "asynchronous-codec", - "bytes 1.0.1", + "bytes", "futures", "libp2p-core", "log", @@ -1770,8 +1725,8 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4aca322b52a0c5136142a7c3971446fb1e9964923a526c9cc6ef3b7c94e57778" dependencies = [ - "bytes 1.0.1", - "curve25519-dalek 3.0.2", + "bytes", + "curve25519-dalek", "futures", "lazy_static", "libp2p-core", @@ -1793,7 +1748,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d37637a4b33b5390322ccc068a33897d0aa541daf4fec99f6a7efbf37295346e" dependencies = [ "async-trait", - "bytes 1.0.1", + "bytes", "futures", "libp2p-core", "libp2p-swarm", @@ -1838,7 +1793,7 @@ dependencies = [ "libp2p-core", "log", "socket2", - "tokio 1.0.2", + "tokio", ] [[package]] @@ -1967,9 +1922,9 @@ dependencies = [ [[package]] name = "miniscript" -version = "4.0.3" +version = "5.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74ff4ece4ff5498718a232e92d53273903609c739052f5edf2a1a42c59586348" +checksum = "71f455be59a359d50370c4f587afbc5739c862e684c5afecae80ab93e7474b4e" dependencies = [ "bitcoin", "serde", @@ -2000,13 +1955,13 @@ dependencies = [ [[package]] name = "monero" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53d4207d0bd4d1eb3323e33a64f9ea99e5e3d257d5cd7a659fad5be48c8b9af" +checksum = "f1bcc1c3dcf247dbbad3aa6497c7393d860c7e89de1f0d05438b63feb0cea9a0" dependencies = [ "base58-monero", "byteorder", - "curve25519-dalek 2.1.2", + "curve25519-dalek", "fixed-hash 0.3.2", "hex 0.4.2", "keccak-hash 0.3.0", @@ -2029,7 +1984,7 @@ dependencies = [ "serde_json", "spectral", "testcontainers 0.12.0", - "tokio 1.0.2", + "tokio", "tracing", "tracing-log", "tracing-subscriber", @@ -2075,7 +2030,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10ddc0eb0117736f19d556355464fc87efc8ad98b29e3fd84f02531eb6e90840" dependencies = [ - "bytes 1.0.1", + "bytes", "futures", "log", "pin-project 1.0.4", @@ -2404,12 +2359,6 @@ dependencies = [ "syn", ] -[[package]] -name = "pin-project-lite" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c917123afa01924fc84bb20c4c03f004d9c38e5127e3c039bbf7f4b9c76a2f6b" - [[package]] name = "pin-project-lite" version = "0.2.4" @@ -2559,7 +2508,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e6984d2f1a23009bd270b8bb56d0926810a3d483f59c987d77969e9d8e840b2" dependencies = [ - "bytes 1.0.1", + "bytes", "prost-derive", ] @@ -2569,7 +2518,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32d3ebd75ac2679c2af3a92246639f9fcc8a442ee420719cc4fe195b98dd5fa3" dependencies = [ - "bytes 1.0.1", + "bytes", "heck", "itertools", "log", @@ -2600,7 +2549,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b518d7cdd93dab1d1122cf07fa9a60771836c668dde9d9e2a139f957f0d9f1bb" dependencies = [ - "bytes 1.0.1", + "bytes", "prost", ] @@ -2918,7 +2867,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd281b1030aa675fb90aa994d07187645bb3c8fc756ca766e7c3070b439de9de" dependencies = [ "base64 0.13.0", - "bytes 1.0.1", + "bytes", "encoding_rs", "futures-core", "futures-util", @@ -2933,11 +2882,11 @@ dependencies = [ "mime", "native-tls", "percent-encoding", - "pin-project-lite 0.2.4", + "pin-project-lite", "serde", "serde_json", "serde_urlencoded", - "tokio 1.0.2", + "tokio", "tokio-native-tls", "url", "wasm-bindgen", @@ -3063,9 +3012,9 @@ dependencies = [ [[package]] name = "secp256k1" -version = "0.19.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6179428c22c73ac0fbb7b5579a56353ce78ba29759b3b8575183336ea74cdfb" +checksum = "733b114f058f260c0af7591434eef4272ae1a8ec2751766d3cb89c6df8d5e450" dependencies = [ "rand 0.6.5", "secp256k1-sys", @@ -3074,17 +3023,17 @@ dependencies = [ [[package]] name = "secp256k1-sys" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11553d210db090930f4432bea123b31f70bbf693ace14504ea2a35e796c28dd2" +checksum = "67e4b6455ee49f5901c8985b88f98fb0a0e1d90a6661f5a03f4888bd987dad29" dependencies = [ "cc", ] [[package]] name = "secp256kfun" -version = "0.3.2-alpha.0" -source = "git+https://github.com/LLFourn/secp256kfun?rev=cdfbc766045ea678a41780919d6228dd5acee3be#cdfbc766045ea678a41780919d6228dd5acee3be" +version = "0.4.2-alpha.0" +source = "git+https://github.com/LLFourn/secp256kfun#8538ef22498170960a9769df2700c1986cc540fd" dependencies = [ "digest 0.9.0", "rand_core 0.5.1", @@ -3096,8 +3045,8 @@ dependencies = [ [[package]] name = "secp256kfun_parity_backend" -version = "0.1.3-alpha.0" -source = "git+https://github.com/LLFourn/secp256kfun?rev=cdfbc766045ea678a41780919d6228dd5acee3be#cdfbc766045ea678a41780919d6228dd5acee3be" +version = "0.1.4-alpha.0" +source = "git+https://github.com/LLFourn/secp256kfun#8538ef22498170960a9769df2700c1986cc540fd" dependencies = [ "crunchy 0.2.2", "subtle 2.4.0", @@ -3253,6 +3202,19 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "sigma_fun" +version = "0.1.3-alpha.0" +source = "git+https://github.com/LLFourn/secp256kfun#8538ef22498170960a9769df2700c1986cc540fd" +dependencies = [ + "curve25519-dalek", + "digest 0.9.0", + "generic-array 0.14.4", + "rand_core 0.5.1", + "secp256kfun", + "serde", +] + [[package]] name = "signature" version = "1.3.0" @@ -3501,8 +3463,7 @@ dependencies = [ "bitcoin-harness", "config", "conquer-once", - "cross-curve-dleq", - "curve25519-dalek 2.1.2", + "curve25519-dalek", "derivative", "dialoguer", "directories-next", @@ -3521,6 +3482,7 @@ dependencies = [ "port_check", "prettytable-rs", "rand 0.7.3", + "rand_chacha 0.2.2", "reqwest", "rust_decimal", "serde", @@ -3528,6 +3490,7 @@ dependencies = [ "serde_derive", "serde_json", "sha2 0.9.2", + "sigma_fun", "sled", "spectral", "structopt", @@ -3536,7 +3499,7 @@ dependencies = [ "testcontainers 0.12.0", "thiserror", "time", - "tokio 1.0.2", + "tokio", "toml", "tracing", "tracing-core", @@ -3737,17 +3700,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" -[[package]] -name = "tokio" -version = "0.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6703a273949a90131b290be1fe7b039d0fc884aa1935860dfcbe056f28cd8092" -dependencies = [ - "bytes 0.5.6", - "pin-project-lite 0.1.11", - "slab", -] - [[package]] name = "tokio" version = "1.0.2" @@ -3755,12 +3707,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ca04cec6ff2474c638057b65798f60ac183e5e79d3448bb7163d36a39cff6ec" dependencies = [ "autocfg 1.0.1", - "bytes 1.0.1", + "bytes", "libc", "memchr", "mio", "num_cpus", - "pin-project-lite 0.2.4", + "pin-project-lite", "tokio-macros", ] @@ -3782,7 +3734,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" dependencies = [ "native-tls", - "tokio 1.0.2", + "tokio", ] [[package]] @@ -3792,8 +3744,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76066865172052eb8796c686f0b441a93df8b08d40a950b062ffb9a426f00edd" dependencies = [ "futures-core", - "pin-project-lite 0.2.4", - "tokio 1.0.2", + "pin-project-lite", + "tokio", ] [[package]] @@ -3802,12 +3754,12 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12ae4751faa60b9f96dd8344d74592e5a17c0c9a220413dbc6942d14139bbfcc" dependencies = [ - "bytes 1.0.1", + "bytes", "futures-core", "futures-sink", "log", - "pin-project-lite 0.2.4", - "tokio 1.0.2", + "pin-project-lite", + "tokio", "tokio-stream", ] @@ -3833,7 +3785,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f47026cdc4080c07e49b37087de021820269d996f581aac150ef9e5583eefe3" dependencies = [ "cfg-if 1.0.0", - "pin-project-lite 0.2.4", + "pin-project-lite", "tracing-attributes", "tracing-core", ] @@ -3992,7 +3944,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35581ff83d4101e58b582e607120c7f5ffb17e632a980b1f38334d76b36908b2" dependencies = [ "asynchronous-codec", - "bytes 1.0.1", + "bytes", "futures-io", "futures-util", ] @@ -4283,7 +4235,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc614d95359fd7afc321b66d2107ede58b246b844cf5d8a0adcca413e439f088" dependencies = [ - "curve25519-dalek 3.0.2", + "curve25519-dalek", "rand_core 0.5.1", "zeroize 1.2.0", ] diff --git a/swap/Cargo.toml b/swap/Cargo.toml index faeee257..cbec0f10 100644 --- a/swap/Cargo.toml +++ b/swap/Cargo.toml @@ -18,28 +18,28 @@ async-trait = "0.1" atty = "0.2" backoff = { git = "https://github.com/ihrwein/backoff", rev = "9d03992a83dfdc596be26276d4e5c5254a4b11a2", features = ["tokio"] } base64 = "0.12" -bdk = { version = "0.3" } -bitcoin = { version = "0.25", features = ["rand", "use-serde"] } -bitcoin-harness = { git = "https://github.com/coblox/bitcoin-harness-rs", rev = "ae2f6cd547496e680941c0910018bbe884128799" } +bdk = { version = "0.4" } +bitcoin = { version = "0.26", features = ["rand", "use-serde"] } +bitcoin-harness = { git = "https://github.com/coblox/bitcoin-harness-rs" } config = { version = "0.10", default-features = false, features = ["toml"] } conquer-once = "0.3" -cross-curve-dleq = { git = "https://github.com/comit-network/cross-curve-dleq", rev = "eddcdea1d1f16fa33ef581d1744014ece535c920", features = ["serde"] } -curve25519-dalek = "2" +curve25519-dalek = "3" derivative = "2" dialoguer = "0.7" directories-next = "2" -ecdsa_fun = { git = "https://github.com/LLFourn/secp256kfun", rev = "cdfbc766045ea678a41780919d6228dd5acee3be", features = ["libsecp_compat", "serde"] } +ecdsa_fun = { git = "https://github.com/LLFourn/secp256kfun", features = ["libsecp_compat", "serde"] } ed25519-dalek = { version = "1.0.0-pre.4", features = ["serde"] }# Cannot be 1 because they depend on curve25519-dalek version 3 futures = { version = "0.3", default-features = false } libp2p = { version = "0.34", default-features = false, features = ["tcp-tokio", "yamux", "mplex", "dns", "noise", "request-response"] } libp2p-async-await = { git = "https://github.com/comit-network/rust-libp2p-async-await", rev = "1429cd780204624b4d244e7d8179fe6ff77988c3" } log = { version = "0.4", features = ["serde"] } -miniscript = { version = "4", features = ["serde"] } -monero = { version = "0.9", features = ["serde_support"] } +miniscript = { version = "5", features = ["serde"] } +monero = { version = "0.10", features = ["serde_support"] } monero-harness = { path = "../monero-harness" } pem = "0.8" prettytable-rs = "0.8" rand = "0.7" +rand_chacha = "0.2.0" reqwest = { version = "0.11", default-features = false } rust_decimal = "1.10" serde = { version = "1", features = ["derive"] } @@ -47,6 +47,7 @@ serde_cbor = "0.11" serde_derive = "1.0" serde_json = "1" sha2 = "0.9" +sigma_fun = { git = "https://github.com/LLFourn/secp256kfun", features = ["ed25519", "serde"] } sled = "0.34" structopt = "0.3" strum = { version = "0.20", features = ["derive"] } diff --git a/swap/src/bitcoin.rs b/swap/src/bitcoin.rs index ad5f4fc0..f308574a 100644 --- a/swap/src/bitcoin.rs +++ b/swap/src/bitcoin.rs @@ -28,8 +28,13 @@ use ::bitcoin::{ }; use anyhow::{anyhow, bail, Result}; use async_trait::async_trait; -use ecdsa_fun::{adaptor::Adaptor, fun::Point, nonce::Deterministic, ECDSA}; -use miniscript::{Descriptor, Segwitv0}; +use ecdsa_fun::{ + adaptor::{Adaptor, HashTranscript}, + fun::Point, + nonce::Deterministic, + ECDSA, +}; +use miniscript::{descriptor::Wsh, Descriptor, Segwitv0}; use rand::{CryptoRng, RngCore}; use serde::{Deserialize, Serialize}; use sha2::Sha256; @@ -93,7 +98,10 @@ impl SecretKey { // self = a, Y = S_b, digest = tx_refund pub fn encsign(&self, Y: PublicKey, digest: SigHash) -> EncryptedSignature { - let adaptor = Adaptor::>::default(); + let adaptor = Adaptor::< + HashTranscript, + Deterministic, + >::default(); adaptor.encrypted_sign(&self.inner, &Y.0, &digest.into_inner()) } @@ -108,6 +116,12 @@ impl From for Point { } } +impl From for PublicKey { + fn from(p: Point) -> Self { + Self(p) + } +} + impl From for SecretKey { fn from(scalar: Scalar) -> Self { let ecdsa = ECDSA::<()>::default(); @@ -157,7 +171,7 @@ pub fn verify_encsig( digest: &SigHash, encsig: &EncryptedSignature, ) -> Result<()> { - let adaptor = Adaptor::>::default(); + let adaptor = Adaptor::, Deterministic>::default(); if adaptor.verify_encrypted_signature( &verification_key.0, @@ -187,7 +201,7 @@ pub fn build_shared_output_descriptor(A: Point, B: Point) -> Descriptor::from_str(&miniscript) .expect("a valid miniscript"); - Descriptor::Wsh(miniscript) + Descriptor::Wsh(Wsh::new(miniscript).expect("a valid descriptor")) } #[async_trait] @@ -244,7 +258,7 @@ pub trait GetNetwork { } pub fn recover(S: PublicKey, sig: Signature, encsig: EncryptedSignature) -> Result { - let adaptor = Adaptor::>::default(); + let adaptor = Adaptor::, Deterministic>::default(); let s = adaptor .recover_decryption_key(&S.0, &sig, &encsig) diff --git a/swap/src/bitcoin/cancel.rs b/swap/src/bitcoin/cancel.rs index 72b719ad..1fd31777 100644 --- a/swap/src/bitcoin/cancel.rs +++ b/swap/src/bitcoin/cancel.rs @@ -5,7 +5,7 @@ use crate::bitcoin::{ use ::bitcoin::{util::bip143::SigHashCache, OutPoint, SigHash, SigHashType, TxIn, TxOut, Txid}; use anyhow::Result; use ecdsa_fun::Signature; -use miniscript::{Descriptor, NullCtx}; +use miniscript::{Descriptor, DescriptorTrait}; use serde::{Deserialize, Serialize}; use std::{collections::HashMap, ops::Add}; @@ -78,7 +78,7 @@ impl TxCancel { let tx_out = TxOut { value: tx_lock.lock_amount().as_sat() - TX_FEE, - script_pubkey: cancel_output_descriptor.script_pubkey(NullCtx), + script_pubkey: cancel_output_descriptor.script_pubkey(), }; let transaction = Transaction { @@ -90,7 +90,7 @@ impl TxCancel { let digest = SigHashCache::new(&transaction).signature_hash( 0, // Only one input: lock_input (lock transaction) - &tx_lock.output_descriptor.witness_script(NullCtx), + &tx_lock.output_descriptor.script_code(), tx_lock.lock_amount().as_sat(), SigHashType::All, ); @@ -146,7 +146,7 @@ impl TxCancel { let mut tx_cancel = self.inner; tx_lock .output_descriptor - .satisfy(&mut tx_cancel.input[0], satisfier, NullCtx)?; + .satisfy(&mut tx_cancel.input[0], satisfier)?; Ok(tx_cancel) } diff --git a/swap/src/bitcoin/lock.rs b/swap/src/bitcoin/lock.rs index 2bc6eb14..d817f007 100644 --- a/swap/src/bitcoin/lock.rs +++ b/swap/src/bitcoin/lock.rs @@ -4,7 +4,7 @@ use crate::bitcoin::{ }; use ::bitcoin::{util::psbt::PartiallySignedTransaction, OutPoint, TxIn, TxOut, Txid}; use anyhow::Result; -use miniscript::{Descriptor, NullCtx}; +use miniscript::{Descriptor, DescriptorTrait}; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] @@ -20,7 +20,7 @@ impl TxLock { { let lock_output_descriptor = build_shared_output_descriptor(A.0, B.0); let address = lock_output_descriptor - .address(wallet.get_network().await, NullCtx) + .address(wallet.get_network().await) .expect("can derive address from descriptor"); let psbt = wallet.build_tx_lock_psbt(address, amount).await?; @@ -54,9 +54,7 @@ impl TxLock { .extract_tx() .output .iter() - .position(|output| { - output.script_pubkey == self.output_descriptor.script_pubkey(NullCtx) - }) + .position(|output| output.script_pubkey == self.output_descriptor.script_pubkey()) .expect("transaction contains lock output") } diff --git a/swap/src/bitcoin/punish.rs b/swap/src/bitcoin/punish.rs index 79322ce1..c30e3448 100644 --- a/swap/src/bitcoin/punish.rs +++ b/swap/src/bitcoin/punish.rs @@ -2,7 +2,7 @@ use crate::bitcoin::{Address, PublicKey, PunishTimelock, Transaction, TxCancel}; use ::bitcoin::{util::bip143::SigHashCache, SigHash, SigHashType}; use anyhow::Result; use ecdsa_fun::Signature; -use miniscript::NullCtx; +use miniscript::DescriptorTrait; use std::collections::HashMap; #[derive(Debug)] @@ -21,7 +21,7 @@ impl TxPunish { let digest = SigHashCache::new(&tx_punish).signature_hash( 0, // Only one input: cancel transaction - &tx_cancel.output_descriptor.witness_script(NullCtx), + &tx_cancel.output_descriptor.script_code(), tx_cancel.amount().as_sat(), SigHashType::All, ); @@ -64,7 +64,7 @@ impl TxPunish { let mut tx_punish = self.inner; tx_cancel .output_descriptor - .satisfy(&mut tx_punish.input[0], satisfier, NullCtx)?; + .satisfy(&mut tx_punish.input[0], satisfier)?; Ok(tx_punish) } diff --git a/swap/src/bitcoin/redeem.rs b/swap/src/bitcoin/redeem.rs index 11530de8..c9ed27ad 100644 --- a/swap/src/bitcoin/redeem.rs +++ b/swap/src/bitcoin/redeem.rs @@ -5,7 +5,7 @@ use crate::bitcoin::{ use ::bitcoin::{util::bip143::SigHashCache, SigHash, SigHashType, Txid}; use anyhow::{bail, Context, Result}; use ecdsa_fun::Signature; -use miniscript::NullCtx; +use miniscript::DescriptorTrait; use std::collections::HashMap; #[derive(Debug, Clone)] @@ -22,7 +22,7 @@ impl TxRedeem { let digest = SigHashCache::new(&tx_redeem).signature_hash( 0, // Only one input: lock_input (lock transaction) - &tx_lock.output_descriptor.witness_script(NullCtx), + &tx_lock.output_descriptor.script_code(), tx_lock.lock_amount().as_sat(), SigHashType::All, ); @@ -69,7 +69,7 @@ impl TxRedeem { let mut tx_redeem = self.inner; tx_lock .output_descriptor - .satisfy(&mut tx_redeem.input[0], satisfier, NullCtx)?; + .satisfy(&mut tx_redeem.input[0], satisfier)?; Ok(tx_redeem) } diff --git a/swap/src/bitcoin/refund.rs b/swap/src/bitcoin/refund.rs index 498d65ab..18c6af12 100644 --- a/swap/src/bitcoin/refund.rs +++ b/swap/src/bitcoin/refund.rs @@ -5,7 +5,7 @@ use crate::bitcoin::{ use ::bitcoin::{util::bip143::SigHashCache, SigHash, SigHashType, Txid}; use anyhow::{bail, Context, Result}; use ecdsa_fun::Signature; -use miniscript::NullCtx; +use miniscript::DescriptorTrait; use std::collections::HashMap; #[derive(Debug)] @@ -20,7 +20,7 @@ impl TxRefund { let digest = SigHashCache::new(&tx_punish).signature_hash( 0, // Only one input: cancel transaction - &tx_cancel.output_descriptor.witness_script(NullCtx), + &tx_cancel.output_descriptor.script_code(), tx_cancel.amount().as_sat(), SigHashType::All, ); @@ -67,7 +67,7 @@ impl TxRefund { let mut tx_refund = self.inner; tx_cancel .output_descriptor - .satisfy(&mut tx_refund.input[0], satisfier, NullCtx)?; + .satisfy(&mut tx_refund.input[0], satisfier)?; Ok(tx_refund) } diff --git a/swap/src/bitcoin/wallet.rs b/swap/src/bitcoin/wallet.rs index 39accc48..e37512af 100644 --- a/swap/src/bitcoin/wallet.rs +++ b/swap/src/bitcoin/wallet.rs @@ -125,14 +125,12 @@ impl BuildTxLockPsbt for Wallet { output_amount: Amount, ) -> Result { tracing::debug!("building tx lock"); - let (psbt, _details) = self.inner.lock().await.create_tx( - bdk::TxBuilder::with_recipients(vec![( - output_address.script_pubkey(), - output_amount.as_sat(), - )]) - // todo: get actual fee - .fee_rate(FeeRate::from_sat_per_vb(5.0)), - )?; + let wallet = self.inner.lock().await; + + let mut tx_builder = wallet.build_tx(); + tx_builder.add_recipient(output_address.script_pubkey(), output_amount.as_sat()); + tx_builder.fee_rate(FeeRate::from_sat_per_vb(5.0)); // todo: get actual fee + let (psbt, _details) = tx_builder.finish()?; tracing::debug!("tx lock built"); Ok(psbt) } diff --git a/swap/src/lib.rs b/swap/src/lib.rs index 77bd8b98..4ffb2335 100644 --- a/swap/src/lib.rs +++ b/swap/src/lib.rs @@ -27,5 +27,6 @@ pub mod protocol; pub mod seed; pub mod trace; +mod monero_ext; mod network; mod serde_peer_id; diff --git a/swap/src/monero_ext.rs b/swap/src/monero_ext.rs new file mode 100644 index 00000000..7d3ce2a3 --- /dev/null +++ b/swap/src/monero_ext.rs @@ -0,0 +1,20 @@ +use crate::bitcoin::Scalar; +use ecdsa_fun::fun::marker::{Mark, NonZero, Secret}; + +pub trait ScalarExt { + fn to_secpfun_scalar(&self) -> ecdsa_fun::fun::Scalar; +} + +impl ScalarExt for crate::monero::Scalar { + fn to_secpfun_scalar(&self) -> Scalar { + let mut little_endian_bytes = self.to_bytes(); + + little_endian_bytes.reverse(); + let big_endian_bytes = little_endian_bytes; + + ecdsa_fun::fun::Scalar::from_bytes(big_endian_bytes) + .expect("valid scalar") + .mark::() + .expect("non-zero scalar") + } +} diff --git a/swap/src/protocol/alice/execution_setup.rs b/swap/src/protocol/alice/execution_setup.rs index af1e2350..eb9505d9 100644 --- a/swap/src/protocol/alice/execution_setup.rs +++ b/swap/src/protocol/alice/execution_setup.rs @@ -12,13 +12,14 @@ use anyhow::{Context, Error}; use libp2p::PeerId; use libp2p_async_await::BehaviourOutEvent; use serde::{Deserialize, Serialize}; +use sigma_fun::ext::dl_secp256k1_ed25519_eq::CrossCurveDLEQProof; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct Message1 { pub(crate) A: bitcoin::PublicKey, pub(crate) S_a_monero: monero::PublicKey, pub(crate) S_a_bitcoin: bitcoin::PublicKey, - pub(crate) dleq_proof_s_a: cross_curve_dleq::Proof, + pub(crate) dleq_proof_s_a: CrossCurveDLEQProof, pub(crate) v_a: monero::PrivateViewKey, pub(crate) redeem_address: bitcoin::Address, pub(crate) punish_address: bitcoin::Address, diff --git a/swap/src/protocol/alice/state.rs b/swap/src/protocol/alice/state.rs index 9609e1ed..32acba0d 100644 --- a/swap/src/protocol/alice/state.rs +++ b/swap/src/protocol/alice/state.rs @@ -7,17 +7,23 @@ use crate::{ }, execution_params::ExecutionParams, monero, + monero_ext::ScalarExt, protocol::{ alice::{Message1, Message3, TransferProof}, bob::{EncryptedSignature, Message0, Message2, Message4}, }, }; -use anyhow::{anyhow, Context, Result}; -use ecdsa_fun::{adaptor::Adaptor, nonce::Deterministic}; +use anyhow::{anyhow, bail, Context, Result}; +use ecdsa_fun::{ + adaptor::{Adaptor, HashTranscript}, + fun::marker::Mark, + nonce::Deterministic, +}; use libp2p::PeerId; use rand::{CryptoRng, RngCore}; use serde::{Deserialize, Serialize}; use sha2::Sha256; +use sigma_fun::ext::dl_secp256k1_ed25519_eq::{CrossCurveDLEQ, CrossCurveDLEQProof}; use std::fmt; #[derive(Debug)] @@ -80,9 +86,11 @@ impl fmt::Display for AliceState { #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] pub struct State0 { pub a: bitcoin::SecretKey, - pub s_a: cross_curve_dleq::Scalar, + pub s_a: monero::Scalar, pub v_a: monero::PrivateViewKey, - pub dleq_proof_s_a: cross_curve_dleq::Proof, + pub(crate) S_a_monero: monero::PublicKey, + pub(crate) S_a_bitcoin: bitcoin::PublicKey, + pub dleq_proof_s_a: CrossCurveDLEQProof, #[serde(with = "::bitcoin::util::amount::serde::as_sat")] pub btc: bitcoin::Amount, pub xmr: monero::Amount, @@ -104,16 +112,27 @@ impl State0 { R: RngCore + CryptoRng, { let a = bitcoin::SecretKey::new_random(rng); - let s_a = cross_curve_dleq::Scalar::random(rng); let v_a = monero::PrivateViewKey::new_random(rng); let redeem_address = bitcoin_wallet.new_address().await?; let punish_address = redeem_address.clone(); - let dleq_proof_s_a = cross_curve_dleq::Proof::new(rng, &s_a); + + let dleq_proof_system = + CrossCurveDLEQ::>::new( + (*ecdsa_fun::fun::G).mark::(), + curve25519_dalek::constants::ED25519_BASEPOINT_POINT, + ); + + let s_a = monero::Scalar::random(rng); + let (dleq_proof_s_a, (S_a_bitcoin, S_a_monero)) = dleq_proof_system.prove(&s_a, rng); Ok(Self { a, s_a, v_a, + S_a_bitcoin: S_a_bitcoin.into(), + S_a_monero: monero::PublicKey { + point: S_a_monero.compress(), + }, dleq_proof_s_a, redeem_address, punish_address, @@ -125,13 +144,26 @@ impl State0 { } pub fn receive(self, msg: Message0) -> Result { - msg.dleq_proof_s_b.verify( - msg.S_b_bitcoin.clone().into(), - msg.S_b_monero - .point - .decompress() - .ok_or_else(|| anyhow!("S_b is not a monero curve point"))?, - )?; + let dleq_proof_system = + CrossCurveDLEQ::>::new( + (*ecdsa_fun::fun::G).mark::(), + curve25519_dalek::constants::ED25519_BASEPOINT_POINT, + ); + + let valid = dleq_proof_system.verify( + &msg.dleq_proof_s_b, + ( + msg.S_b_bitcoin.into(), + msg.S_b_monero + .point + .decompress() + .ok_or_else(|| anyhow!("S_b is not a monero curve point"))?, + ), + ); + + if !valid { + bail!("Bob's dleq proof doesn't verify") + } let v = self.v_a + msg.v_b; @@ -139,6 +171,8 @@ impl State0 { a: self.a, B: msg.B, s_a: self.s_a, + S_a_monero: self.S_a_monero, + S_a_bitcoin: self.S_a_bitcoin, S_b_monero: msg.S_b_monero, S_b_bitcoin: msg.S_b_bitcoin, v, @@ -159,12 +193,14 @@ impl State0 { pub struct State1 { a: bitcoin::SecretKey, B: bitcoin::PublicKey, - s_a: cross_curve_dleq::Scalar, + s_a: monero::Scalar, + S_a_monero: monero::PublicKey, + S_a_bitcoin: bitcoin::PublicKey, S_b_monero: monero::PublicKey, S_b_bitcoin: bitcoin::PublicKey, v: monero::PrivateViewKey, v_a: monero::PrivateViewKey, - dleq_proof_s_a: cross_curve_dleq::Proof, + dleq_proof_s_a: CrossCurveDLEQProof, #[serde(with = "::bitcoin::util::amount::serde::as_sat")] btc: bitcoin::Amount, xmr: monero::Amount, @@ -179,10 +215,8 @@ impl State1 { pub fn next_message(&self) -> Message1 { Message1 { A: self.a.public(), - S_a_monero: monero::PublicKey::from_private_key(&monero::PrivateKey { - scalar: self.s_a.into_ed25519(), - }), - S_a_bitcoin: self.s_a.into_secp256k1().into(), + S_a_monero: self.S_a_monero, + S_a_bitcoin: self.S_a_bitcoin, dleq_proof_s_a: self.dleq_proof_s_a.clone(), v_a: self.v_a, redeem_address: self.redeem_address.clone(), @@ -214,7 +248,7 @@ impl State1 { pub struct State2 { a: bitcoin::SecretKey, B: bitcoin::PublicKey, - s_a: cross_curve_dleq::Scalar, + s_a: monero::Scalar, S_b_monero: monero::PublicKey, S_b_bitcoin: bitcoin::PublicKey, v: monero::PrivateViewKey, @@ -284,7 +318,7 @@ impl State2 { pub struct State3 { pub a: bitcoin::SecretKey, pub B: bitcoin::PublicKey, - pub s_a: cross_curve_dleq::Scalar, + pub s_a: monero::Scalar, pub S_b_monero: monero::PublicKey, pub S_b_bitcoin: bitcoin::PublicKey, pub v: monero::PrivateViewKey, @@ -332,7 +366,7 @@ impl State3 { pub struct State4 { a: bitcoin::SecretKey, B: bitcoin::PublicKey, - s_a: cross_curve_dleq::Scalar, + s_a: monero::Scalar, S_b_monero: monero::PublicKey, S_b_bitcoin: bitcoin::PublicKey, v: monero::PrivateViewKey, @@ -352,9 +386,7 @@ impl State4 { where W: monero::Transfer, { - let S_a = monero::PublicKey::from_private_key(&monero::PrivateKey { - scalar: self.s_a.into_ed25519(), - }); + let S_a = monero::PublicKey::from_private_key(&monero::PrivateKey { scalar: self.s_a }); let S_b = self.S_b_monero; let (tx_lock_proof, fee) = monero_wallet @@ -425,7 +457,7 @@ impl State4 { pub struct State5 { a: bitcoin::SecretKey, B: bitcoin::PublicKey, - s_a: cross_curve_dleq::Scalar, + s_a: monero::Scalar, S_b_monero: monero::PublicKey, S_b_bitcoin: bitcoin::PublicKey, v: monero::PrivateViewKey, @@ -475,7 +507,7 @@ impl State5 { pub struct State6 { a: bitcoin::SecretKey, B: bitcoin::PublicKey, - s_a: cross_curve_dleq::Scalar, + s_a: monero::Scalar, S_b_monero: monero::PublicKey, S_b_bitcoin: bitcoin::PublicKey, v: monero::PrivateViewKey, @@ -496,13 +528,13 @@ impl State6 { &self, bitcoin_wallet: &W, ) -> Result<()> { - let adaptor = Adaptor::>::default(); + let adaptor = Adaptor::, Deterministic>::default(); let tx_redeem = bitcoin::TxRedeem::new(&self.tx_lock, &self.redeem_address); let sig_a = self.a.sign(tx_redeem.digest()); let sig_b = - adaptor.decrypt_signature(&self.s_a.into_secp256k1(), self.tx_redeem_encsig.clone()); + adaptor.decrypt_signature(&self.s_a.to_secpfun_scalar(), self.tx_redeem_encsig.clone()); let sig_tx_redeem = tx_redeem.add_signatures(&self.tx_lock, (self.a.public(), sig_a), (self.B, sig_b))?; diff --git a/swap/src/protocol/alice/steps.rs b/swap/src/protocol/alice/steps.rs index 680b4f2b..411abd68 100644 --- a/swap/src/protocol/alice/steps.rs +++ b/swap/src/protocol/alice/steps.rs @@ -15,7 +15,10 @@ use crate::{ }, }; use anyhow::{Context, Result}; -use ecdsa_fun::{adaptor::Adaptor, nonce::Deterministic}; +use ecdsa_fun::{ + adaptor::{Adaptor, HashTranscript}, + nonce::Deterministic, +}; use futures::{ future::{select, Either}, pin_mut, @@ -61,9 +64,7 @@ pub async fn lock_xmr( where W: Transfer, { - let S_a = monero::PublicKey::from_private_key(&monero::PrivateKey { - scalar: state3.s_a.into_ed25519(), - }); + let S_a = monero::PublicKey::from_private_key(&monero::PrivateKey { scalar: state3.s_a }); let public_spend_key = S_a + state3.S_b_monero; let public_view_key = state3.v.public(); @@ -103,24 +104,24 @@ pub fn build_bitcoin_redeem_transaction( encrypted_signature: EncryptedSignature, tx_lock: &TxLock, a: bitcoin::SecretKey, - s_a: cross_curve_dleq::Scalar, + s_a: ecdsa_fun::fun::Scalar, B: bitcoin::PublicKey, redeem_address: &bitcoin::Address, ) -> Result { - let adaptor = Adaptor::>::default(); + let adaptor = Adaptor::, Deterministic>::default(); let tx_redeem = bitcoin::TxRedeem::new(tx_lock, redeem_address); bitcoin::verify_encsig( B, - s_a.into_secp256k1().into(), + bitcoin::PublicKey::from(s_a.clone()), &tx_redeem.digest(), &encrypted_signature, ) .context("Invalid encrypted signature received")?; let sig_a = a.sign(tx_redeem.digest()); - let sig_b = adaptor.decrypt_signature(&s_a.into_secp256k1(), encrypted_signature); + let sig_b = adaptor.decrypt_signature(&s_a, encrypted_signature); let tx = tx_redeem .add_signatures(&tx_lock, (a.public(), sig_a), (B, sig_b)) @@ -224,13 +225,11 @@ where pub fn extract_monero_private_key( published_refund_tx: bitcoin::Transaction, tx_refund: TxRefund, - s_a: cross_curve_dleq::Scalar, + s_a: monero::Scalar, a: bitcoin::SecretKey, S_b_bitcoin: bitcoin::PublicKey, ) -> Result { - let s_a = monero::PrivateKey { - scalar: s_a.into_ed25519(), - }; + let s_a = monero::PrivateKey { scalar: s_a }; let tx_refund_sig = tx_refund .extract_signature_by_key(published_refund_tx, a.public()) diff --git a/swap/src/protocol/alice/swap.rs b/swap/src/protocol/alice/swap.rs index 8e2870cb..e24808fe 100644 --- a/swap/src/protocol/alice/swap.rs +++ b/swap/src/protocol/alice/swap.rs @@ -11,6 +11,7 @@ use crate::{ execution_params::ExecutionParams, monero, monero::CreateWalletForOutput, + monero_ext::ScalarExt, protocol::{ alice, alice::{ @@ -199,7 +200,7 @@ async fn run_until_internal( *encrypted_signature, &state3.tx_lock, state3.a.clone(), - state3.s_a, + state3.s_a.to_secpfun_scalar(), state3.B, &state3.redeem_address, ) { diff --git a/swap/src/protocol/bob/execution_setup.rs b/swap/src/protocol/bob/execution_setup.rs index dc87f275..aa301b47 100644 --- a/swap/src/protocol/bob/execution_setup.rs +++ b/swap/src/protocol/bob/execution_setup.rs @@ -10,6 +10,7 @@ use anyhow::{Context, Error, Result}; use libp2p::PeerId; use libp2p_async_await::BehaviourOutEvent; use serde::{Deserialize, Serialize}; +use sigma_fun::ext::dl_secp256k1_ed25519_eq::CrossCurveDLEQProof; use std::sync::Arc; #[derive(Clone, Debug, Serialize, Deserialize)] @@ -17,7 +18,7 @@ pub struct Message0 { pub(crate) B: crate::bitcoin::PublicKey, pub(crate) S_b_monero: monero::PublicKey, pub(crate) S_b_bitcoin: crate::bitcoin::PublicKey, - pub(crate) dleq_proof_s_b: cross_curve_dleq::Proof, + pub(crate) dleq_proof_s_b: CrossCurveDLEQProof, pub(crate) v_b: crate::monero::PrivateViewKey, pub(crate) refund_address: bitcoin::Address, } diff --git a/swap/src/protocol/bob/state.rs b/swap/src/protocol/bob/state.rs index 83780a9b..0b2ca99d 100644 --- a/swap/src/protocol/bob/state.rs +++ b/swap/src/protocol/bob/state.rs @@ -8,17 +8,24 @@ use crate::{ execution_params::ExecutionParams, monero, monero::{monero_private_key, InsufficientFunds, TransferProof}, + monero_ext::ScalarExt, protocol::{ alice::{Message1, Message3}, bob::{EncryptedSignature, Message0, Message2, Message4}, }, }; -use anyhow::{anyhow, Result}; -use ecdsa_fun::{adaptor::Adaptor, nonce::Deterministic, Signature}; +use anyhow::{anyhow, bail, Result}; +use ecdsa_fun::{ + adaptor::{Adaptor, HashTranscript}, + fun::marker::Mark, + nonce::Deterministic, + Signature, +}; use monero_harness::rpc::wallet::BlockHeight; use rand::{CryptoRng, RngCore}; use serde::{Deserialize, Serialize}; use sha2::Sha256; +use sigma_fun::ext::dl_secp256k1_ed25519_eq::{CrossCurveDLEQ, CrossCurveDLEQProof}; use std::fmt; #[derive(Debug, Clone)] @@ -73,9 +80,11 @@ impl fmt::Display for BobState { #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] pub struct State0 { b: bitcoin::SecretKey, - s_b: cross_curve_dleq::Scalar, + s_b: monero::Scalar, + S_b_monero: monero::PublicKey, + S_b_bitcoin: bitcoin::PublicKey, v_b: monero::PrivateViewKey, - dleq_proof_s_b: cross_curve_dleq::Proof, + dleq_proof_s_b: CrossCurveDLEQProof, #[serde(with = "::bitcoin::util::amount::serde::as_sat")] btc: bitcoin::Amount, xmr: monero::Amount, @@ -97,14 +106,25 @@ impl State0 { ) -> Self { let b = bitcoin::SecretKey::new_random(rng); - let s_b = cross_curve_dleq::Scalar::random(rng); + let s_b = monero::Scalar::random(rng); let v_b = monero::PrivateViewKey::new_random(rng); - let dleq_proof_s_b = cross_curve_dleq::Proof::new(rng, &s_b); + + let dleq_proof_system = + CrossCurveDLEQ::>::new( + (*ecdsa_fun::fun::G).mark::(), + curve25519_dalek::constants::ED25519_BASEPOINT_POINT, + ); + + let (dleq_proof_s_b, (S_b_bitcoin, S_b_monero)) = dleq_proof_system.prove(&s_b, rng); Self { b, s_b, v_b, + S_b_bitcoin: bitcoin::PublicKey::from(S_b_bitcoin), + S_b_monero: monero::PublicKey { + point: S_b_monero.compress(), + }, btc, xmr, dleq_proof_s_b, @@ -118,10 +138,8 @@ impl State0 { pub fn next_message(&self) -> Message0 { Message0 { B: self.b.public(), - S_b_monero: monero::PublicKey::from_private_key(&monero::PrivateKey { - scalar: self.s_b.into_ed25519(), - }), - S_b_bitcoin: self.s_b.into_secp256k1().into(), + S_b_monero: self.S_b_monero, + S_b_bitcoin: self.S_b_bitcoin, dleq_proof_s_b: self.dleq_proof_s_b.clone(), v_b: self.v_b, refund_address: self.refund_address.clone(), @@ -132,13 +150,26 @@ impl State0 { where W: BuildTxLockPsbt + GetNetwork, { - msg.dleq_proof_s_a.verify( - msg.S_a_bitcoin.clone().into(), - msg.S_a_monero - .point - .decompress() - .ok_or_else(|| anyhow!("S_a is not a monero curve point"))?, - )?; + let dleq_proof_system = + CrossCurveDLEQ::>::new( + (*ecdsa_fun::fun::G).mark::(), + curve25519_dalek::constants::ED25519_BASEPOINT_POINT, + ); + + let valid = dleq_proof_system.verify( + &msg.dleq_proof_s_a, + ( + msg.S_a_bitcoin.clone().into(), + msg.S_a_monero + .point + .decompress() + .ok_or_else(|| anyhow!("S_a is not a monero curve point"))?, + ), + ); + + if !valid { + bail!("Alice's dleq proof doesn't verify") + } let tx_lock = bitcoin::TxLock::new(wallet, self.btc, msg.A, self.b.public()).await?; let v = msg.v_a + self.v_b; @@ -166,7 +197,7 @@ impl State0 { pub struct State1 { A: bitcoin::PublicKey, b: bitcoin::SecretKey, - s_b: cross_curve_dleq::Scalar, + s_b: monero::Scalar, S_a_monero: monero::PublicKey, S_a_bitcoin: bitcoin::PublicKey, v: monero::PrivateViewKey, @@ -194,7 +225,7 @@ impl State1 { bitcoin::verify_sig(&self.A, &tx_cancel.digest(), &msg.tx_cancel_sig)?; bitcoin::verify_encsig( self.A, - self.s_b.into_secp256k1().into(), + bitcoin::PublicKey::from(self.s_b.to_secpfun_scalar()), &tx_refund.digest(), &msg.tx_refund_encsig, )?; @@ -224,7 +255,7 @@ impl State1 { pub struct State2 { A: bitcoin::PublicKey, b: bitcoin::SecretKey, - s_b: cross_curve_dleq::Scalar, + s_b: monero::Scalar, S_a_monero: monero::PublicKey, S_a_bitcoin: bitcoin::PublicKey, v: monero::PrivateViewKey, @@ -289,7 +320,7 @@ impl State2 { pub struct State3 { A: bitcoin::PublicKey, b: bitcoin::SecretKey, - s_b: cross_curve_dleq::Scalar, + s_b: monero::Scalar, S_a_monero: monero::PublicKey, S_a_bitcoin: bitcoin::PublicKey, v: monero::PrivateViewKey, @@ -314,9 +345,8 @@ impl State3 { where W: monero::WatchForTransfer, { - let S_b_monero = monero::PublicKey::from_private_key(&monero::PrivateKey::from_scalar( - self.s_b.into_ed25519(), - )); + let S_b_monero = + monero::PublicKey::from_private_key(&monero::PrivateKey::from_scalar(self.s_b)); let S = self.S_a_monero + S_b_monero; if let Err(e) = xmr_wallet @@ -401,7 +431,7 @@ impl State3 { pub struct State4 { A: bitcoin::PublicKey, b: bitcoin::SecretKey, - s_b: cross_curve_dleq::Scalar, + s_b: monero::Scalar, S_a_bitcoin: bitcoin::PublicKey, v: monero::PrivateViewKey, cancel_timelock: CancelTimelock, @@ -536,11 +566,11 @@ impl State4 { bitcoin::TxCancel::new(&self.tx_lock, self.cancel_timelock, self.A, self.b.public()); let tx_refund = bitcoin::TxRefund::new(&tx_cancel, &self.refund_address); - let adaptor = Adaptor::>::default(); + let adaptor = Adaptor::, Deterministic>::default(); let sig_b = self.b.sign(tx_refund.digest()); let sig_a = - adaptor.decrypt_signature(&self.s_b.into_secp256k1(), self.tx_refund_encsig.clone()); + adaptor.decrypt_signature(&self.s_b.to_secpfun_scalar(), self.tx_refund_encsig.clone()); let signed_tx_refund = tx_refund.add_signatures( &tx_cancel.clone(), @@ -568,7 +598,7 @@ impl State4 { pub struct State5 { #[serde(with = "monero_private_key")] s_a: monero::PrivateKey, - s_b: cross_curve_dleq::Scalar, + s_b: monero::Scalar, v: monero::PrivateViewKey, tx_lock: bitcoin::TxLock, monero_wallet_restore_blockheight: u32, @@ -579,9 +609,7 @@ impl State5 { where W: monero::CreateWalletForOutput, { - let s_b = monero::PrivateKey { - scalar: self.s_b.into_ed25519(), - }; + let s_b = monero::PrivateKey { scalar: self.s_b }; let s = self.s_a + s_b; diff --git a/swap/tests/testutils/electrs.rs b/swap/tests/testutils/electrs.rs index 0917f920..bc7b7079 100644 --- a/swap/tests/testutils/electrs.rs +++ b/swap/tests/testutils/electrs.rs @@ -137,6 +137,7 @@ impl IntoIterator for ElectrsArgs { Network::Testnet => args.push("--network=testnet".to_string()), Network::Regtest => args.push("--network=regtest".to_string()), Network::Bitcoin => {} + Network::Signet => panic!("signet not yet supported"), } args.push("-vvvvv".to_string()); From cabf0efb8c325fa1f602d4b4561937a499e88f44 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 19 Feb 2021 12:22:55 +1100 Subject: [PATCH 2/3] Only construct proof system once The proof system is a static element and can be reused several times. --- swap/src/protocol.rs | 14 ++++++++++++++ swap/src/protocol/alice/state.rs | 20 ++++---------------- swap/src/protocol/bob/state.rs | 20 ++++---------------- 3 files changed, 22 insertions(+), 32 deletions(-) diff --git a/swap/src/protocol.rs b/swap/src/protocol.rs index abb8f314..23d3ac66 100644 --- a/swap/src/protocol.rs +++ b/swap/src/protocol.rs @@ -1,6 +1,20 @@ +use conquer_once::Lazy; +use ecdsa_fun::fun::marker::Mark; +use sha2::Sha256; +use sigma_fun::{ext::dl_secp256k1_ed25519_eq::CrossCurveDLEQ, HashTranscript}; + pub mod alice; pub mod bob; +pub static CROSS_CURVE_PROOF_SYSTEM: Lazy< + CrossCurveDLEQ>, +> = Lazy::new(|| { + CrossCurveDLEQ::>::new( + (*ecdsa_fun::fun::G).mark::(), + curve25519_dalek::constants::ED25519_BASEPOINT_POINT, + ) +}); + #[derive(Debug, Copy, Clone)] pub struct StartingBalances { pub xmr: crate::monero::Amount, diff --git a/swap/src/protocol/alice/state.rs b/swap/src/protocol/alice/state.rs index 32acba0d..9538e84e 100644 --- a/swap/src/protocol/alice/state.rs +++ b/swap/src/protocol/alice/state.rs @@ -11,19 +11,19 @@ use crate::{ protocol::{ alice::{Message1, Message3, TransferProof}, bob::{EncryptedSignature, Message0, Message2, Message4}, + CROSS_CURVE_PROOF_SYSTEM, }, }; use anyhow::{anyhow, bail, Context, Result}; use ecdsa_fun::{ adaptor::{Adaptor, HashTranscript}, - fun::marker::Mark, nonce::Deterministic, }; use libp2p::PeerId; use rand::{CryptoRng, RngCore}; use serde::{Deserialize, Serialize}; use sha2::Sha256; -use sigma_fun::ext::dl_secp256k1_ed25519_eq::{CrossCurveDLEQ, CrossCurveDLEQProof}; +use sigma_fun::ext::dl_secp256k1_ed25519_eq::CrossCurveDLEQProof; use std::fmt; #[derive(Debug)] @@ -116,14 +116,8 @@ impl State0 { let redeem_address = bitcoin_wallet.new_address().await?; let punish_address = redeem_address.clone(); - let dleq_proof_system = - CrossCurveDLEQ::>::new( - (*ecdsa_fun::fun::G).mark::(), - curve25519_dalek::constants::ED25519_BASEPOINT_POINT, - ); - let s_a = monero::Scalar::random(rng); - let (dleq_proof_s_a, (S_a_bitcoin, S_a_monero)) = dleq_proof_system.prove(&s_a, rng); + let (dleq_proof_s_a, (S_a_bitcoin, S_a_monero)) = CROSS_CURVE_PROOF_SYSTEM.prove(&s_a, rng); Ok(Self { a, @@ -144,13 +138,7 @@ impl State0 { } pub fn receive(self, msg: Message0) -> Result { - let dleq_proof_system = - CrossCurveDLEQ::>::new( - (*ecdsa_fun::fun::G).mark::(), - curve25519_dalek::constants::ED25519_BASEPOINT_POINT, - ); - - let valid = dleq_proof_system.verify( + let valid = CROSS_CURVE_PROOF_SYSTEM.verify( &msg.dleq_proof_s_b, ( msg.S_b_bitcoin.into(), diff --git a/swap/src/protocol/bob/state.rs b/swap/src/protocol/bob/state.rs index 0b2ca99d..5f33db16 100644 --- a/swap/src/protocol/bob/state.rs +++ b/swap/src/protocol/bob/state.rs @@ -12,12 +12,12 @@ use crate::{ protocol::{ alice::{Message1, Message3}, bob::{EncryptedSignature, Message0, Message2, Message4}, + CROSS_CURVE_PROOF_SYSTEM, }, }; use anyhow::{anyhow, bail, Result}; use ecdsa_fun::{ adaptor::{Adaptor, HashTranscript}, - fun::marker::Mark, nonce::Deterministic, Signature, }; @@ -25,7 +25,7 @@ use monero_harness::rpc::wallet::BlockHeight; use rand::{CryptoRng, RngCore}; use serde::{Deserialize, Serialize}; use sha2::Sha256; -use sigma_fun::ext::dl_secp256k1_ed25519_eq::{CrossCurveDLEQ, CrossCurveDLEQProof}; +use sigma_fun::ext::dl_secp256k1_ed25519_eq::CrossCurveDLEQProof; use std::fmt; #[derive(Debug, Clone)] @@ -109,13 +109,7 @@ impl State0 { let s_b = monero::Scalar::random(rng); let v_b = monero::PrivateViewKey::new_random(rng); - let dleq_proof_system = - CrossCurveDLEQ::>::new( - (*ecdsa_fun::fun::G).mark::(), - curve25519_dalek::constants::ED25519_BASEPOINT_POINT, - ); - - let (dleq_proof_s_b, (S_b_bitcoin, S_b_monero)) = dleq_proof_system.prove(&s_b, rng); + let (dleq_proof_s_b, (S_b_bitcoin, S_b_monero)) = CROSS_CURVE_PROOF_SYSTEM.prove(&s_b, rng); Self { b, @@ -150,13 +144,7 @@ impl State0 { where W: BuildTxLockPsbt + GetNetwork, { - let dleq_proof_system = - CrossCurveDLEQ::>::new( - (*ecdsa_fun::fun::G).mark::(), - curve25519_dalek::constants::ED25519_BASEPOINT_POINT, - ); - - let valid = dleq_proof_system.verify( + let valid = CROSS_CURVE_PROOF_SYSTEM.verify( &msg.dleq_proof_s_a, ( msg.S_a_bitcoin.clone().into(), From 2d8ede80e182241d7ddf86ff427882637ff17e08 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 19 Feb 2021 12:33:59 +1100 Subject: [PATCH 3/3] Use released version of backoff --- Cargo.lock | 5 +++-- swap/Cargo.toml | 2 +- swap/src/bitcoin/wallet.rs | 2 +- swap/src/monero/wallet.rs | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4148fd36..e1691b3f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -204,8 +204,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "backoff" -version = "0.2.2-alpha.0" -source = "git+https://github.com/ihrwein/backoff?rev=9d03992a83dfdc596be26276d4e5c5254a4b11a2#9d03992a83dfdc596be26276d4e5c5254a4b11a2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fe17f59a06fe8b87a6fc8bf53bb70b3aba76d7685f432487a68cd5552853625" dependencies = [ "futures-core", "getrandom 0.2.1", diff --git a/swap/Cargo.toml b/swap/Cargo.toml index cbec0f10..597e235f 100644 --- a/swap/Cargo.toml +++ b/swap/Cargo.toml @@ -16,7 +16,7 @@ anyhow = "1" async-recursion = "0.3.1" async-trait = "0.1" atty = "0.2" -backoff = { git = "https://github.com/ihrwein/backoff", rev = "9d03992a83dfdc596be26276d4e5c5254a4b11a2", features = ["tokio"] } +backoff = { version = "0.3", features = ["tokio"] } base64 = "0.12" bdk = { version = "0.4" } bitcoin = { version = "0.26", features = ["rand", "use-serde"] } diff --git a/swap/src/bitcoin/wallet.rs b/swap/src/bitcoin/wallet.rs index e37512af..c0a9d93e 100644 --- a/swap/src/bitcoin/wallet.rs +++ b/swap/src/bitcoin/wallet.rs @@ -9,7 +9,7 @@ use crate::{ use ::bitcoin::{util::psbt::PartiallySignedTransaction, Txid}; use anyhow::{anyhow, bail, Context, Result}; use async_trait::async_trait; -use backoff::{backoff::Constant as ConstantBackoff, tokio::retry}; +use backoff::{backoff::Constant as ConstantBackoff, future::retry}; use bdk::{ blockchain::{noop_progress, Blockchain, ElectrumBlockchain}, electrum_client::{self, Client, ElectrumApi}, diff --git a/swap/src/monero/wallet.rs b/swap/src/monero/wallet.rs index a53c06c3..06cc02e6 100644 --- a/swap/src/monero/wallet.rs +++ b/swap/src/monero/wallet.rs @@ -5,7 +5,7 @@ use crate::monero::{ use ::monero::{Address, Network, PrivateKey, PublicKey}; use anyhow::Result; use async_trait::async_trait; -use backoff::{backoff::Constant as ConstantBackoff, tokio::retry}; +use backoff::{backoff::Constant as ConstantBackoff, future::retry}; use bitcoin::hashes::core::sync::atomic::AtomicU32; use monero_harness::rpc::wallet; use std::{