From 695dfdef6e975627b6cdf2ba404df3bf9e323a37 Mon Sep 17 00:00:00 2001 From: "Phuong N." Date: Thu, 20 Nov 2025 22:12:35 +0000 Subject: [PATCH 1/2] Add tss crate --- Cargo.lock | 495 ++++++++++++------ Cargo.toml | 4 +- chain-signatures/crypto/src/kdf.rs | 2 +- chain-signatures/node/Cargo.toml | 2 +- .../node/src/backlog/selection.rs | 2 +- chain-signatures/node/src/kdf.rs | 33 +- chain-signatures/node/src/mesh/connection.rs | 2 +- chain-signatures/node/src/mesh/mod.rs | 3 +- .../node/src/protocol/contract/primitives.rs | 2 +- .../node/src/protocol/cryptography.rs | 40 +- chain-signatures/node/src/protocol/error.rs | 5 +- .../node/src/protocol/message/mod.rs | 6 +- .../node/src/protocol/message/sub.rs | 2 +- .../node/src/protocol/message/types.rs | 3 +- chain-signatures/node/src/protocol/posit.rs | 4 +- .../node/src/protocol/presignature.rs | 31 +- .../node/src/protocol/signature.rs | 72 ++- chain-signatures/node/src/protocol/state.rs | 2 +- .../node/src/protocol/sync/mod.rs | 2 +- chain-signatures/node/src/protocol/triple.rs | 20 +- chain-signatures/node/src/rpc.rs | 10 +- .../node/src/sign_bidirectional.rs | 8 +- chain-signatures/node/src/storage/mod.rs | 2 +- .../node/src/storage/presignature_storage.rs | 2 +- .../node/src/storage/protocol_storage.rs | 15 +- .../node/src/storage/triple_storage.rs | 3 +- chain-signatures/node/src/types.rs | 70 ++- chain-signatures/node/src/web/mock.rs | 2 +- chain-signatures/node/src/web/mod.rs | 2 +- doc/SCALING_AND_SECURITY.md | 2 +- doc/mpc_node_specification.md | 4 +- integration-tests/Cargo.toml | 2 +- integration-tests/benches/store.rs | 8 +- integration-tests/src/actions/mod.rs | 13 +- integration-tests/src/actions/sign.rs | 25 +- integration-tests/src/actions/wait.rs | 2 +- integration-tests/src/actions/wait_for.rs | 17 +- integration-tests/src/cluster/spawner.rs | 2 +- integration-tests/src/containers.rs | 49 +- integration-tests/src/lib.rs | 2 +- integration-tests/src/mpc_fixture/builder.rs | 2 +- .../src/mpc_fixture/fixture_interface.rs | 2 +- .../src/mpc_fixture/fixture_tasks.rs | 2 +- integration-tests/src/mpc_fixture/input.rs | 2 +- integration-tests/tests/cases/chains.rs | 4 +- integration-tests/tests/cases/mpc.rs | 2 +- integration-tests/tests/cases/store.rs | 6 +- integration-tests/tests/cases/sync.rs | 6 +- 48 files changed, 638 insertions(+), 360 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f2fc6f9a7..965ca195e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -228,7 +228,7 @@ dependencies = [ "serde", "serde_json", "serde_with", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -264,7 +264,7 @@ dependencies = [ "futures", "futures-util", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -306,7 +306,7 @@ dependencies = [ "alloy-rlp", "crc", "serde", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -330,7 +330,7 @@ dependencies = [ "alloy-rlp", "k256", "serde", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -354,7 +354,7 @@ dependencies = [ "serde", "serde_with", "sha2 0.10.9", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -394,7 +394,7 @@ dependencies = [ "http 1.3.1", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.17", "tracing", ] @@ -421,7 +421,7 @@ dependencies = [ "futures-utils-wasm", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -497,7 +497,7 @@ dependencies = [ "reqwest 0.12.15", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.17", "tokio", "tracing", "url 2.5.4", @@ -589,7 +589,7 @@ dependencies = [ "serde", "serde_json", "serde_with", - "thiserror 2.0.12", + "thiserror 2.0.17", "tree_hash", "tree_hash_derive", ] @@ -631,7 +631,7 @@ dependencies = [ "serde", "serde_json", "serde_with", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -657,7 +657,7 @@ dependencies = [ "either", "elliptic-curve", "k256", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -673,7 +673,7 @@ dependencies = [ "async-trait", "k256", "rand 0.8.5", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -765,7 +765,7 @@ dependencies = [ "parking_lot 0.12.3", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.17", "tokio", "tower 0.5.2", "tracing", @@ -1666,7 +1666,7 @@ dependencies = [ "async-task", "concurrent-queue", "fastrand 2.3.0", - "futures-lite 2.6.0", + "futures-lite 2.6.1", "pin-project-lite", "slab", ] @@ -1679,7 +1679,7 @@ checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" dependencies = [ "async-lock 3.4.0", "blocking", - "futures-lite 2.6.0", + "futures-lite 2.6.1", ] [[package]] @@ -1712,7 +1712,7 @@ dependencies = [ "cfg-if 1.0.0", "concurrent-queue", "futures-io", - "futures-lite 2.6.0", + "futures-lite 2.6.1", "parking", "polling 3.7.4", "rustix 0.38.44", @@ -1749,7 +1749,7 @@ checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7" dependencies = [ "async-io 2.4.0", "blocking", - "futures-lite 2.6.0", + "futures-lite 2.6.1", ] [[package]] @@ -1783,7 +1783,7 @@ dependencies = [ "blocking", "cfg-if 1.0.0", "event-listener 5.4.0", - "futures-lite 2.6.0", + "futures-lite 2.6.1", "rustix 0.38.44", "tracing", ] @@ -1878,6 +1878,15 @@ dependencies = [ "bytemuck", ] +[[package]] +name = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + [[package]] name = "atomic-take" version = "1.1.0" @@ -2318,7 +2327,7 @@ dependencies = [ "async-channel 2.3.1", "async-task", "futures-io", - "futures-lite 2.6.0", + "futures-lite 2.6.1", "piper", ] @@ -2348,6 +2357,22 @@ dependencies = [ "zeroize", ] +[[package]] +name = "blstrs" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a8a8ed6fefbeef4a8c7b460e4110e12c5e22a5b7cf32621aae6ad650c4dcf29" +dependencies = [ + "blst", + "byte-slice-cast", + "ff", + "group", + "pairing", + "rand_core 0.6.4", + "serde", + "subtle", +] + [[package]] name = "bollard" version = "0.17.1" @@ -2627,26 +2652,6 @@ dependencies = [ "serde", ] -[[package]] -name = "cait-sith" -version = "0.8.0" -source = "git+https://github.com/sig-net/cait-sith?rev=9f34e8c#9f34e8c7141cdef58078347fcdd07e5469e2c6e6" -dependencies = [ - "auto_ops", - "ck-meow", - "digest 0.10.7", - "ecdsa", - "elliptic-curve", - "event-listener 2.5.3", - "k256", - "magikitten", - "rand_core 0.6.4", - "rmp-serde", - "serde", - "smol", - "subtle", -] - [[package]] name = "camino" version = "1.2.1" @@ -2818,17 +2823,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "ck-meow" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20351a318fc4110699260ffde844f0302bc3b34e528b9c48ea429fcd54d81323" -dependencies = [ - "keccak", - "subtle", - "zeroize", -] - [[package]] name = "clap" version = "4.5.37" @@ -2869,6 +2863,15 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +[[package]] +name = "cobs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" +dependencies = [ + "thiserror 2.0.17", +] + [[package]] name = "coins-bip32" version = "0.8.7" @@ -2934,7 +2937,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" dependencies = [ "lazy_static", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -3012,6 +3015,12 @@ dependencies = [ "web-sys", ] +[[package]] +name = "const-crc32-nostd" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808ac43170e95b11dd23d78aa9eaac5bea45776a602955552c4e833f3f0f823d" + [[package]] name = "const-hex" version = "1.14.0" @@ -3188,6 +3197,12 @@ dependencies = [ "itertools 0.10.5", ] +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + [[package]] name = "crossbeam-channel" version = "0.5.15" @@ -3549,6 +3564,12 @@ dependencies = [ "tokio", ] +[[package]] +name = "debugless-unwrap" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f400d0750c0c069e8493f2256cb4da6f604b6d2eeb69a0ca8863acde352f8400" + [[package]] name = "delay_map" version = "0.3.0" @@ -3611,6 +3632,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive-getters" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74ef43543e701c01ad77d3a5922755c6a1d71b22d942cb8042be4994b380caff" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + [[package]] name = "derive-syn-parse" version = "0.2.0" @@ -3865,6 +3897,15 @@ dependencies = [ "serde_json", ] +[[package]] +name = "document-features" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +dependencies = [ + "litrs", +] + [[package]] name = "downcast-rs" version = "1.2.1" @@ -4034,6 +4075,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + [[package]] name = "ena" version = "0.14.3" @@ -4232,7 +4285,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4890,7 +4943,7 @@ dependencies = [ "scale-info", "scale-type-resolver", "sp-crypto-hashing", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -4905,6 +4958,69 @@ dependencies = [ "serde", ] +[[package]] +name = "frost-core" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2619366c227233c0f817ae01156bd21b8cf74d2bd96cbe0889f4c2e266724e44" +dependencies = [ + "byteorder", + "const-crc32-nostd", + "debugless-unwrap", + "derive-getters", + "document-features", + "hex", + "itertools 0.14.0", + "postcard", + "rand_core 0.6.4", + "serde", + "serdect", + "thiserror 2.0.17", + "visibility", + "zeroize", +] + +[[package]] +name = "frost-ed25519" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f73eb5fa9311d33450c2320199ad1663b5af7a50061d9627d2e0dc776f0acb27" +dependencies = [ + "curve25519-dalek 4.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "document-features", + "frost-core", + "frost-rerandomized", + "rand_core 0.6.4", + "sha2 0.10.9", +] + +[[package]] +name = "frost-rerandomized" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c5eb1ea58c0250b7ce834337f7b19e0417686d14ffc7f626137dea9149762d4" +dependencies = [ + "derive-getters", + "document-features", + "frost-core", + "hex", + "rand_core 0.6.4", +] + +[[package]] +name = "frost-secp256k1" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f6974379aee791f2f9e0db47c37d9e4c77ea8a8233e488ae8949ce4c6864e96" +dependencies = [ + "document-features", + "frost-core", + "frost-rerandomized", + "k256", + "rand_core 0.6.4", + "sha2 0.10.9", +] + [[package]] name = "fs-err" version = "2.11.0" @@ -4996,9 +5112,9 @@ dependencies = [ [[package]] name = "futures-lite" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" dependencies = [ "fastrand 2.3.0", "futures-core", @@ -5356,7 +5472,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", + "rand 0.8.5", "rand_core 0.6.4", + "rand_xorshift", "subtle", ] @@ -5497,6 +5615,20 @@ dependencies = [ "hashbrown 0.14.5", ] +[[package]] +name = "heapless" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" +dependencies = [ + "atomic-polyfill", + "hash32", + "rustc_version 0.4.1", + "serde", + "spin 0.9.8", + "stable_deref_trait", +] + [[package]] name = "heck" version = "0.3.3" @@ -6554,7 +6686,6 @@ dependencies = [ "bollard", "borsh 1.5.7", "bs58 0.5.1", - "cait-sith", "ciborium", "clap", "criterion", @@ -6597,6 +6728,7 @@ dependencies = [ "test-log", "testcontainers", "thiserror 1.0.69", + "threshold-signatures", "tokio", "tracing", "tracing-subscriber 0.3.20", @@ -6641,7 +6773,7 @@ checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ "hermit-abi 0.5.0", "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -7634,6 +7766,12 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" +[[package]] +name = "litrs" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" + [[package]] name = "local-ip-address" version = "0.5.7" @@ -7700,16 +7838,6 @@ dependencies = [ "syn 2.0.101", ] -[[package]] -name = "magikitten" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "277c454ad884bdcf0a283beaa7a22e0791fe0475791d01cf8becd1bd4549f4ba" -dependencies = [ - "ck-meow", - "rand_core 0.6.4", -] - [[package]] name = "matchers" version = "0.2.0" @@ -7951,7 +8079,6 @@ dependencies = [ "axum-extra", "borsh 0.10.4", "borsh 1.5.7", - "cait-sith", "chrono", "ciborium", "clap", @@ -8012,6 +8139,7 @@ dependencies = [ "sysinfo", "test-log", "thiserror 1.0.69", + "threshold-signatures", "tokio", "tokio-stream", "tracing", @@ -8291,7 +8419,7 @@ checksum = "6b992cca8d3b00f34b37f638c9632a97b734656151294e7a29b60b93b8a92948" dependencies = [ "anyhow", "json_comments", - "thiserror 2.0.12", + "thiserror 2.0.17", "tracing", ] @@ -8369,7 +8497,7 @@ dependencies = [ "serde", "serde_json", "subtle", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -8556,7 +8684,7 @@ dependencies = [ "serde_repr", "serde_yaml", "strum 0.24.1", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -8679,7 +8807,7 @@ dependencies = [ "sha3", "smart-default 0.7.1", "strum 0.24.1", - "thiserror 2.0.12", + "thiserror 2.0.17", "tracing", "zstd 0.13.3", ] @@ -8744,7 +8872,7 @@ dependencies = [ "serde", "serde_repr", "sha2 0.10.9", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -8983,7 +9111,7 @@ dependencies = [ "sha3", "strum 0.24.1", "tempfile", - "thiserror 2.0.12", + "thiserror 2.0.17", "tracing", "zeropool-bn", ] @@ -9123,7 +9251,7 @@ dependencies = [ "log", "netlink-packet-core", "netlink-sys", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -9427,7 +9555,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ - "proc-macro-crate 1.1.3", + "proc-macro-crate 3.3.0", "proc-macro2", "quote", "syn 2.0.101", @@ -9507,7 +9635,7 @@ dependencies = [ "alloy-serde", "derive_more 2.0.1", "serde", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -9542,7 +9670,7 @@ dependencies = [ "op-alloy-consensus", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -9651,7 +9779,7 @@ dependencies = [ "futures-sink", "js-sys", "pin-project-lite", - "thiserror 2.0.12", + "thiserror 2.0.17", "tracing", ] @@ -9695,7 +9823,7 @@ dependencies = [ "opentelemetry_sdk", "prost", "reqwest 0.12.15", - "thiserror 2.0.12", + "thiserror 2.0.17", "tracing", ] @@ -9725,7 +9853,7 @@ dependencies = [ "percent-encoding 2.3.1", "rand 0.9.1", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.17", "tokio", "tokio-stream", ] @@ -9776,8 +9904,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e69bf016dc406eff7d53a7d3f7cf1c2e72c82b9088aac1118591e36dd2cd3e9" dependencies = [ "bitcoin_hashes 0.13.0", - "rand 0.7.3", - "rand_core 0.5.1", + "rand 0.8.5", + "rand_core 0.6.4", "serde", "unicode-normalization", ] @@ -10016,7 +10144,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "198db74531d58c70a361c42201efde7e2591e976d518caf7662a47dc5720e7b6" dependencies = [ "memchr", - "thiserror 2.0.12", + "thiserror 2.0.17", "ucd-trie", ] @@ -10267,6 +10395,19 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" +[[package]] +name = "postcard" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24" +dependencies = [ + "cobs", + "embedded-io 0.4.0", + "embedded-io 0.6.1", + "heapless", + "serde", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -10477,7 +10618,7 @@ dependencies = [ "memchr", "parking_lot 0.12.3", "protobuf", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -10632,7 +10773,7 @@ dependencies = [ "rustc-hash 2.1.1", "rustls 0.23.26", "socket2 0.5.9", - "thiserror 2.0.12", + "thiserror 2.0.17", "tokio", "tracing", "web-time", @@ -10671,7 +10812,7 @@ dependencies = [ "rustls-pki-types", "rustls-platform-verifier", "slab", - "thiserror 2.0.12", + "thiserror 2.0.17", "tinyvec", "tracing", "web-time", @@ -10688,7 +10829,7 @@ dependencies = [ "once_cell", "socket2 0.5.9", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -11580,7 +11721,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -11593,7 +11734,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.9.4", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -11731,7 +11872,7 @@ dependencies = [ "security-framework 3.2.0", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -11855,7 +11996,7 @@ dependencies = [ "scale-decode-derive", "scale-type-resolver", "smallvec", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -11882,7 +12023,7 @@ dependencies = [ "scale-encode-derive", "scale-type-resolver", "smallvec", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -11944,7 +12085,7 @@ dependencies = [ "quote", "scale-info", "syn 2.0.101", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -11962,7 +12103,7 @@ dependencies = [ "scale-encode", "scale-type-resolver", "serde", - "thiserror 2.0.12", + "thiserror 2.0.17", "yap", ] @@ -12282,11 +12423,12 @@ dependencies = [ [[package]] name = "serde_bytes" -version = "0.11.17" +version = "0.11.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8437fd221bde2d4ca316d61b90e337e9e702b3820b87d63caa9ba6c02bd06d96" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" dependencies = [ "serde", + "serde_core", ] [[package]] @@ -12322,15 +12464,16 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.140" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ "indexmap 2.9.0", "itoa", "memchr", - "ryu", "serde", + "serde_core", + "zmij", ] [[package]] @@ -12585,7 +12728,7 @@ checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb" dependencies = [ "num-bigint 0.4.6", "num-traits", - "thiserror 2.0.12", + "thiserror 2.0.17", "time", ] @@ -12655,7 +12798,7 @@ dependencies = [ "async-net", "async-process 2.3.0", "blocking", - "futures-lite 2.6.0", + "futures-lite 2.6.1", ] [[package]] @@ -12678,7 +12821,7 @@ dependencies = [ "either", "event-listener 5.4.0", "fnv", - "futures-lite 2.6.0", + "futures-lite 2.6.1", "futures-util", "hashbrown 0.15.5", "hex", @@ -12728,7 +12871,7 @@ dependencies = [ "event-listener 5.4.0", "fnv", "futures-channel", - "futures-lite 2.6.0", + "futures-lite 2.6.1", "futures-util", "hashbrown 0.15.5", "hex", @@ -12875,7 +13018,7 @@ dependencies = [ "spl-token-2022 7.0.0", "spl-token-group-interface", "spl-token-metadata-interface", - "thiserror 2.0.12", + "thiserror 2.0.17", "zstd 0.13.3", ] @@ -12980,7 +13123,7 @@ dependencies = [ "ark-serialize 0.4.2", "bytemuck", "solana-define-syscall", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -13035,7 +13178,7 @@ dependencies = [ "solana-transaction", "solana-transaction-error", "solana-udp-client", - "thiserror 2.0.12", + "thiserror 2.0.17", "tokio", ] @@ -13161,7 +13304,7 @@ dependencies = [ "solana-net-utils", "solana-time-utils", "solana-transaction-error", - "thiserror 2.0.12", + "thiserror 2.0.17", "tokio", ] @@ -13190,7 +13333,7 @@ dependencies = [ "curve25519-dalek 4.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "solana-define-syscall", "subtle", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -13300,7 +13443,7 @@ dependencies = [ "solana-pubkey", "solana-sdk-ids", "solana-system-interface", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -13637,7 +13780,7 @@ dependencies = [ "solana-cluster-type", "solana-sha256-hasher", "solana-time-utils", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -13889,7 +14032,7 @@ dependencies = [ "solana-sysvar", "solana-sysvar-id", "solana-vote-interface", - "thiserror 2.0.12", + "thiserror 2.0.17", "wasm-bindgen", ] @@ -13983,7 +14126,7 @@ dependencies = [ "solana-timings", "solana-transaction-context", "solana-type-overrides", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -14032,7 +14175,7 @@ dependencies = [ "solana-pubkey", "solana-rpc-client-api", "solana-signature", - "thiserror 2.0.12", + "thiserror 2.0.17", "tokio", "tokio-stream", "tokio-tungstenite", @@ -14067,7 +14210,7 @@ dependencies = [ "solana-streamer", "solana-tls-utils", "solana-transaction-error", - "thiserror 2.0.12", + "thiserror 2.0.17", "tokio", ] @@ -14218,7 +14361,7 @@ dependencies = [ "solana-transaction-error", "solana-transaction-status-client-types", "solana-version", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -14235,7 +14378,7 @@ dependencies = [ "solana-pubkey", "solana-rpc-client", "solana-sdk-ids", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -14328,7 +14471,7 @@ dependencies = [ "solana-transaction-context", "solana-transaction-error", "solana-validator-exit", - "thiserror 2.0.12", + "thiserror 2.0.17", "wasm-bindgen", ] @@ -14380,7 +14523,7 @@ dependencies = [ "borsh 1.5.7", "libsecp256k1 0.6.0", "solana-define-syscall", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -14607,7 +14750,7 @@ dependencies = [ "solana-tls-utils", "solana-transaction-error", "solana-transaction-metrics-tracker", - "thiserror 2.0.12", + "thiserror 2.0.17", "tokio", "tokio-util", "x509-parser", @@ -14780,7 +14923,7 @@ dependencies = [ "solana-signer", "solana-transaction", "solana-transaction-error", - "thiserror 2.0.12", + "thiserror 2.0.17", "tokio", ] @@ -14894,7 +15037,7 @@ dependencies = [ "spl-token-2022 7.0.0", "spl-token-group-interface", "spl-token-metadata-interface", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -14917,7 +15060,7 @@ dependencies = [ "solana-transaction", "solana-transaction-context", "solana-transaction-error", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -14942,7 +15085,7 @@ dependencies = [ "solana-net-utils", "solana-streamer", "solana-transaction-error", - "thiserror 2.0.12", + "thiserror 2.0.17", "tokio", ] @@ -15022,7 +15165,7 @@ dependencies = [ "solana-signature", "solana-signer", "subtle", - "thiserror 2.0.12", + "thiserror 2.0.17", "wasm-bindgen", "zeroize", ] @@ -15382,6 +15525,9 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] [[package]] name = "spinning_top" @@ -15508,7 +15654,7 @@ dependencies = [ "solana-program-option", "solana-pubkey", "solana-zk-sdk", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -15626,7 +15772,7 @@ dependencies = [ "spl-token-metadata-interface", "spl-transfer-hook-interface", "spl-type-length-value", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -15652,7 +15798,7 @@ dependencies = [ "solana-program", "solana-zk-sdk", "spl-pod", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -15674,7 +15820,7 @@ checksum = "0e3597628b0d2fe94e7900fd17cdb4cfbb31ee35c66f82809d27d86e44b2848b" dependencies = [ "curve25519-dalek 4.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "solana-zk-sdk", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -15978,7 +16124,7 @@ dependencies = [ "subxt-macro", "subxt-metadata", "subxt-rpcs", - "thiserror 2.0.12", + "thiserror 2.0.17", "tokio", "tokio-util", "tracing", @@ -16001,7 +16147,7 @@ dependencies = [ "scale-typegen", "subxt-metadata", "syn 2.0.101", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -16030,7 +16176,7 @@ dependencies = [ "serde_json", "sp-crypto-hashing", "subxt-metadata", - "thiserror 2.0.12", + "thiserror 2.0.17", "tracing", ] @@ -16045,7 +16191,7 @@ dependencies = [ "serde", "serde_json", "smoldot-light", - "thiserror 2.0.12", + "thiserror 2.0.17", "tokio", "tokio-stream", "tracing", @@ -16080,7 +16226,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-crypto-hashing", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -16101,7 +16247,7 @@ dependencies = [ "serde_json", "subxt-core", "subxt-lightclient", - "thiserror 2.0.12", + "thiserror 2.0.17", "tokio-util", "tracing", "url 2.5.4", @@ -16131,7 +16277,7 @@ dependencies = [ "sha2 0.10.9", "sp-crypto-hashing", "subxt-core", - "thiserror 2.0.12", + "thiserror 2.0.17", "zeroize", ] @@ -16143,7 +16289,7 @@ checksum = "e450f6812a653c5a3e63a079aa3b60a3f4c362722753c3222286eaa1800f9002" dependencies = [ "hex", "parity-scale-codec", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -16344,7 +16490,7 @@ dependencies = [ "getrandom 0.3.2", "once_cell", "rustix 1.0.5", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -16429,11 +16575,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.12" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl 2.0.12", + "thiserror-impl 2.0.17", ] [[package]] @@ -16449,9 +16595,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.12" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", @@ -16477,6 +16623,40 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "threshold-signatures" +version = "0.1.0" +source = "git+https://github.com/near/threshold-signatures?rev=315a9749072fde57cdfc7496000878a3bb97400a#315a9749072fde57cdfc7496000878a3bb97400a" +dependencies = [ + "auto_ops", + "blstrs", + "borsh 1.5.7", + "byteorder", + "derive_more 2.0.1", + "digest 0.10.7", + "ecdsa", + "elliptic-curve", + "frost-core", + "frost-ed25519", + "frost-secp256k1", + "futures", + "futures-lite 2.6.1", + "hex", + "hkdf", + "k256", + "keccak", + "rand_core 0.6.4", + "rmp-serde", + "serde", + "serde_bytes", + "serde_json", + "sha2 0.10.9", + "sha3", + "subtle", + "thiserror 2.0.17", + "zeroize", +] + [[package]] name = "time" version = "0.3.41" @@ -17065,9 +17245,9 @@ version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", "digest 0.10.7", - "rand 0.7.3", + "rand 0.8.5", "static_assertions", ] @@ -17332,6 +17512,17 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "visibility" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d674d135b4a8c1d7e813e2f8d1c9a58308aee4a680323066025e53132218bd91" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + [[package]] name = "void" version = "1.0.2" @@ -17728,7 +17919,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -18176,7 +18367,7 @@ dependencies = [ "pharos", "rustc_version 0.4.1", "send_wrapper 0.6.0", - "thiserror 2.0.12", + "thiserror 2.0.17", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -18397,9 +18588,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.8.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" dependencies = [ "zeroize_derive", ] @@ -18470,6 +18661,12 @@ dependencies = [ "zstd 0.11.2+zstd.1.5.2", ] +[[package]] +name = "zmij" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac93432f5b761b22864c774aac244fa5c0fd877678a4c37ebf6cf42208f9c9ec" + [[package]] name = "zstd" version = "0.11.2+zstd.1.5.2" diff --git a/Cargo.toml b/Cargo.toml index 78e300dd5..6e23f9215 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ version = "1.11.0" alloy = { version = "=1.0.38", features = ["contract", "json"] } anyhow = { version = "1.0.95", features = ["backtrace"] } borsh = "1.5.3" -cait-sith = { git = "https://github.com/sig-net/cait-sith", rev = "9f34e8c", features = ["k256"] } +threshold-signatures = { git = "https://github.com/near/threshold-signatures", rev = "315a9749072fde57cdfc7496000878a3bb97400a" } ciborium = "0.2.2" clap = { version = "4.5.4", features = ["derive", "env"] } deadpool-redis = "0.18.0" @@ -35,7 +35,7 @@ rand = "0.8.5" reqwest = { version = "0.11.16", features = ["blocking", "json"] } semver = "1.0.23" serde = { version = "1", features = ["derive"] } -serde_bytes = "0.11.15" +serde_bytes = "0.11.19" serde_json = "1" sha3 = "0.10.8" thiserror = "1" diff --git a/chain-signatures/crypto/src/kdf.rs b/chain-signatures/crypto/src/kdf.rs index 0cc2da2a6..6e58b257e 100644 --- a/chain-signatures/crypto/src/kdf.rs +++ b/chain-signatures/crypto/src/kdf.rs @@ -124,7 +124,7 @@ pub fn check_ec_signature( ) -> anyhow::Result<()> { let public_key = expected_pk.to_encoded_point(false); let signature = k256::ecdsa::Signature::from_scalars(x_coordinate(big_r), s) - .context("cannot create signature from cait_sith signature")?; + .context("cannot create signature from threshold-signatures signature")?; let found_pk = recover( &msg_hash.to_bytes(), &signature, diff --git a/chain-signatures/node/Cargo.toml b/chain-signatures/node/Cargo.toml index 492378475..72f337fa7 100644 --- a/chain-signatures/node/Cargo.toml +++ b/chain-signatures/node/Cargo.toml @@ -52,7 +52,7 @@ alloy.workspace = true anyhow.workspace = true borsh.workspace = true borsh_sol = { package = "borsh", version = "0.10.4" } # solana anchor requires borsh 0.10 -cait-sith.workspace = true +threshold-signatures.workspace = true ciborium.workspace = true clap.workspace = true deadpool-redis.workspace = true diff --git a/chain-signatures/node/src/backlog/selection.rs b/chain-signatures/node/src/backlog/selection.rs index b82feb526..78b55c608 100644 --- a/chain-signatures/node/src/backlog/selection.rs +++ b/chain-signatures/node/src/backlog/selection.rs @@ -9,8 +9,8 @@ use crate::backlog::Checkpoint; use crate::mesh::MeshState; use crate::node_client::NodeClient; use crate::protocol::Chain; -use cait_sith::protocol::Participant; use std::collections::HashMap; +use threshold_signatures::participants::Participant; use tokio::task::JoinSet; /// Queries all participants for their checkpoints and returns a selected checkpoint diff --git a/chain-signatures/node/src/kdf.rs b/chain-signatures/node/src/kdf.rs index 8e53ff672..0c9146f3a 100644 --- a/chain-signatures/node/src/kdf.rs +++ b/chain-signatures/node/src/kdf.rs @@ -1,34 +1,7 @@ use anyhow::Context; -use hkdf::Hkdf; -use k256::{ecdsa::RecoveryId, elliptic_curve::sec1::ToEncodedPoint, AffinePoint, Scalar}; -use mpc_crypto::{kdf::recover, x_coordinate, ScalarExt}; +use k256::{ecdsa::RecoveryId, elliptic_curve::sec1::ToEncodedPoint, Scalar}; +use mpc_crypto::{kdf::recover, x_coordinate}; use mpc_primitives::Signature; -use near_primitives::hash::CryptoHash; -use sha3::Sha3_256; - -// In case there are multiple requests in the same block (hence same entropy), we need to ensure -// that we generate different random scalars as delta tweaks. -// Receipt ID should be unique inside of a block, so it serves us as the request identifier. -pub fn derive_delta( - request_id: [u8; 32], - entropy: [u8; 32], - presignature_big_r: AffinePoint, -) -> Scalar { - let hk = Hkdf::::new(None, &entropy); - let info = format!("{DELTA_DERIVATION_PREFIX}:{}", CryptoHash(request_id)); - let mut okm = [0u8; 32]; - hk.expand(info.as_bytes(), &mut okm).unwrap(); - hk.expand( - presignature_big_r.to_encoded_point(true).as_bytes(), - &mut okm, - ) - .unwrap(); - Scalar::from_non_biased(okm) -} - -// Constant prefix that ensures delta derivation values are used specifically for -// near-mpc-recovery with key derivation protocol vX.Y.Z. -const DELTA_DERIVATION_PREFIX: &str = "near-mpc-recovery v0.1.0 delta derivation:"; // try to get the correct recovery id for this signature by brute force. pub fn into_eth_sig( @@ -39,7 +12,7 @@ pub fn into_eth_sig( ) -> anyhow::Result { let public_key = public_key.to_encoded_point(false); let signature = k256::ecdsa::Signature::from_scalars(x_coordinate(big_r), s) - .context("cannot create signature from cait_sith signature")?; + .context("cannot create signature from threshold-signatures signature")?; let pk0 = recover( &msg_hash.to_bytes()[..], &signature, diff --git a/chain-signatures/node/src/mesh/connection.rs b/chain-signatures/node/src/mesh/connection.rs index 9ed61ed54..ff84eba80 100644 --- a/chain-signatures/node/src/mesh/connection.rs +++ b/chain-signatures/node/src/mesh/connection.rs @@ -2,8 +2,8 @@ use std::collections::hash_map::Entry; use std::collections::{HashMap, HashSet}; use std::time::Duration; -use cait_sith::protocol::Participant; use near_account_id::AccountId; +use threshold_signatures::participants::Participant; use tokio::sync::{broadcast, watch}; use tokio::task::JoinHandle; use tokio_stream::wrappers::WatchStream; diff --git a/chain-signatures/node/src/mesh/mod.rs b/chain-signatures/node/src/mesh/mod.rs index c890f6dde..e39b430a7 100644 --- a/chain-signatures/node/src/mesh/mod.rs +++ b/chain-signatures/node/src/mesh/mod.rs @@ -7,8 +7,8 @@ use crate::protocol::contract::primitives::Participants; use crate::protocol::ParticipantInfo; use crate::protocol::ProtocolState; use crate::rpc::ContractStateWatcher; -use cait_sith::protocol::Participant; use near_account_id::AccountId; +use threshold_signatures::participants::Participant; use tokio::sync::{mpsc, watch}; pub mod connection; @@ -173,6 +173,7 @@ impl Mesh { ProtocolState::Resharing(resharing) => resharing .new_participants .find(&self.my_id) + .or_else(|| resharing.old_participants.find(&self.my_id)) .map(|(p, info)| (*p, info.clone())), } } diff --git a/chain-signatures/node/src/protocol/contract/primitives.rs b/chain-signatures/node/src/protocol/contract/primitives.rs index 5872f9cf5..b790b04de 100644 --- a/chain-signatures/node/src/protocol/contract/primitives.rs +++ b/chain-signatures/node/src/protocol/contract/primitives.rs @@ -1,4 +1,3 @@ -use cait_sith::protocol::Participant; use mpc_keys::hpke; use near_primitives::{borsh::BorshDeserialize, types::AccountId}; use serde::{Deserialize, Serialize}; @@ -7,6 +6,7 @@ use std::{ hash::Hash, str::FromStr, }; +use threshold_signatures::participants::Participant; type ParticipantId = u32; diff --git a/chain-signatures/node/src/protocol/cryptography.rs b/chain-signatures/node/src/protocol/cryptography.rs index 874992d7e..66892b613 100644 --- a/chain-signatures/node/src/protocol/cryptography.rs +++ b/chain-signatures/node/src/protocol/cryptography.rs @@ -13,10 +13,12 @@ use crate::protocol::state::{PersistentNodeData, WaitingForConsensusState}; use crate::protocol::MeshState; use crate::types::{ReshareProtocol, SecretKeyShare}; -use cait_sith::protocol::{Action, InitializationError, Participant, ProtocolError}; -use k256::elliptic_curve::group::GroupEncoding; +use k256::elliptic_curve::sec1::ToEncodedPoint; use k256::sha2::{Digest, Sha256}; use mpc_crypto::PublicKey; +use threshold_signatures::errors::{InitializationError, ProtocolError}; +use threshold_signatures::participants::Participant; +use threshold_signatures::protocol::Action; use tokio::sync::mpsc; pub static RESHARING_RUNNING_TIMEOUT_SECS: AtomicU64 = AtomicU64::new(300); @@ -31,10 +33,10 @@ pub fn set_resharing_running_timeout(duration: Duration) { #[derive(thiserror::Error, Debug)] pub enum CryptographicError { - #[error("cait-sith initialization error: {0}")] - CaitSithInitializationError(#[from] InitializationError), - #[error("cait-sith protocol error: {0}")] - CaitSithProtocolError(#[from] ProtocolError), + #[error("initialization error: {0}")] + Init(#[from] InitializationError), + #[error("protocol error: {0}")] + Protocol(#[from] ProtocolError), } pub(crate) trait CryptographicProtocol { @@ -93,7 +95,7 @@ impl CryptographicProtocol for GeneratingState { tracing::debug!("generating: sending a message to many participants"); for p in &participants { if p == &self.me { - // Skip yourself, cait-sith never sends messages to oneself + // Skip yourself, threshold-signatures never sends messages to oneself continue; } @@ -124,10 +126,19 @@ impl CryptographicProtocol for GeneratingState { } Action::Return(r) => { tracing::info!( - public_key = hex::encode(r.public_key.to_bytes()), + public_key = hex::encode( + r.public_key + .to_element() + .to_affine() + .to_encoded_point(true) + .as_bytes() + ), "generating: successfully completed key generation" ); - return self.finalize(r.public_key, r.private_share, ctx).await; + // Convert frost_core::VerifyingKey -> AffinePoint for storage + return self + .finalize(r.public_key.to_element().to_affine(), r.private_share, ctx) + .await; } } } @@ -344,11 +355,16 @@ impl CryptographicProtocol for ResharingState { .await; } } - Action::Return(private_share) => { + Action::Return(keygen_output) => { tracing::info!("resharing: successfully completed key reshare"); resharing.last_activity = Instant::now(); - match Self::try_finalize(ctx, &mut resharing, private_share, &self.contract) - .await + match Self::try_finalize( + ctx, + &mut resharing, + keygen_output.private_share, + &self.contract, + ) + .await { Ok(next_state) => return next_state, Err(()) => { diff --git a/chain-signatures/node/src/protocol/error.rs b/chain-signatures/node/src/protocol/error.rs index 3003a33af..733f05553 100644 --- a/chain-signatures/node/src/protocol/error.rs +++ b/chain-signatures/node/src/protocol/error.rs @@ -1,5 +1,6 @@ -use cait_sith::protocol::{InitializationError, Participant}; use mpc_primitives::SignId; +use threshold_signatures::errors::InitializationError; +use threshold_signatures::participants::Participant; use super::{presignature::PresignatureId, triple::TripleId}; @@ -7,7 +8,7 @@ use super::{presignature::PresignatureId, triple::TripleId}; pub enum GenerationError { #[error("presignature already generated")] AlreadyGenerated, - #[error("cait-sith initialization error: {0}")] + #[error("threshold-signatures initialization error: {0}")] CaitSithInitializationError(#[from] InitializationError), #[error("triple {0} is generating or missing")] TripleGeneratingOrMissing(TripleId), diff --git a/chain-signatures/node/src/protocol/message/mod.rs b/chain-signatures/node/src/protocol/message/mod.rs index 9a79830c4..32c883e4d 100644 --- a/chain-signatures/node/src/protocol/message/mod.rs +++ b/chain-signatures/node/src/protocol/message/mod.rs @@ -24,7 +24,6 @@ use crate::node_client::NodeClient; use crate::protocol::message::filter::{MessageFilter, MAX_FILTER_SIZE}; use crate::protocol::Config; -use cait_sith::protocol::Participant; use mpc_contract::config::ProtocolConfig; use mpc_keys::hpke::{self, Ciphered}; use mpc_primitives::SignId; @@ -32,6 +31,7 @@ use near_account_id::AccountId; use near_crypto::Signature; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; +use threshold_signatures::participants::Participant; use tokio::sync::{mpsc, watch}; use std::collections::{HashMap, VecDeque}; @@ -1051,10 +1051,10 @@ const fn cbor_name(value: &ciborium::Value) -> &'static str { mod tests { use std::time::Duration; - use cait_sith::protocol::Participant; use mpc_keys::hpke::{self, Ciphered}; use mpc_primitives::SignId; use serde::{de::DeserializeOwned, Deserialize, Serialize}; + use threshold_signatures::participants::Participant; use crate::{ config::{Config, LocalConfig, NetworkConfig, OverrideConfig}, @@ -1074,7 +1074,7 @@ mod tests { let associated_data = b""; let (cipher_sk, cipher_pk) = mpc_keys::hpke::generate(); let starting_message = Message::Generating(GeneratingMessage { - from: cait_sith::protocol::Participant::from(0), + from: Participant::from(0), data: vec![], }); diff --git a/chain-signatures/node/src/protocol/message/sub.rs b/chain-signatures/node/src/protocol/message/sub.rs index e947dea18..d4df01345 100644 --- a/chain-signatures/node/src/protocol/message/sub.rs +++ b/chain-signatures/node/src/protocol/message/sub.rs @@ -1,5 +1,5 @@ -use cait_sith::protocol::Participant; use mpc_primitives::SignId; +use threshold_signatures::participants::Participant; use tokio::sync::{mpsc, oneshot}; use crate::protocol::message::types::Round; diff --git a/chain-signatures/node/src/protocol/message/types.rs b/chain-signatures/node/src/protocol/message/types.rs index 4021dc137..4491ef994 100644 --- a/chain-signatures/node/src/protocol/message/types.rs +++ b/chain-signatures/node/src/protocol/message/types.rs @@ -1,8 +1,9 @@ use std::collections::HashMap; use std::hash::{DefaultHasher, Hash as _}; -use cait_sith::protocol::{MessageData, Participant}; use serde::{Deserialize, Serialize}; +use threshold_signatures::participants::Participant; +use threshold_signatures::protocol::MessageData; use crate::protocol::posit::PositAction; use crate::protocol::presignature::{FullPresignatureId, PresignatureId}; diff --git a/chain-signatures/node/src/protocol/posit.rs b/chain-signatures/node/src/protocol/posit.rs index 98ff50ee7..86a23e2f4 100644 --- a/chain-signatures/node/src/protocol/posit.rs +++ b/chain-signatures/node/src/protocol/posit.rs @@ -1,5 +1,5 @@ -use cait_sith::protocol::Participant; use serde::{Deserialize, Serialize}; +use threshold_signatures::participants::Participant; use std::collections::hash_map::Entry; use std::collections::{HashMap, HashSet}; @@ -405,7 +405,7 @@ impl SinglePositCounter { #[cfg(test)] mod tests { use super::*; - use cait_sith::protocol::Participant; + use threshold_signatures::participants::Participant; type Id = u64; diff --git a/chain-signatures/node/src/protocol/presignature.rs b/chain-signatures/node/src/protocol/presignature.rs index 75fcb1cb4..506814d56 100644 --- a/chain-signatures/node/src/protocol/presignature.rs +++ b/chain-signatures/node/src/protocol/presignature.rs @@ -12,10 +12,9 @@ use crate::storage::TripleStorage; use crate::types::{PresignatureProtocol, SecretKeyShare}; use crate::util::{AffinePointExt, JoinMap}; -use cait_sith::protocol::{Action, InitializationError, Participant}; -use cait_sith::{KeygenOutput, PresignArguments, PresignOutput}; use chrono::Utc; -use k256::{AffinePoint, Scalar, Secp256k1}; +use k256::ProjectivePoint; +use k256::{AffinePoint, Scalar}; use mpc_contract::config::ProtocolConfig; use mpc_crypto::PublicKey; use serde::ser::SerializeStruct; @@ -24,6 +23,12 @@ use sha3::{Digest, Sha3_256}; use std::collections::HashSet; use std::fmt; use std::time::{Duration, Instant}; +use threshold_signatures::ecdsa::ot_based_ecdsa::{self, PresignArguments, PresignOutput}; +use threshold_signatures::ecdsa::{KeygenOutput, Secp256K1Sha256}; +use threshold_signatures::errors::InitializationError; +use threshold_signatures::frost_core::{Element, VerifyingKey}; +use threshold_signatures::participants::Participant; +use threshold_signatures::protocol::Action; use tokio::sync::{mpsc, watch}; use tokio::task::JoinHandle; use tokio::time; @@ -31,7 +36,7 @@ use tokio::time; use near_account_id::AccountId; /// Unique number used to identify a specific ongoing presignature generation protocol. -/// Without `PresignatureId` it would be unclear where to route incoming cait-sith presignature +/// Without `PresignatureId` it would be unclear where to route incoming threshold-signatures presignature /// generation messages. pub type PresignatureId = u64; @@ -57,7 +62,7 @@ impl FullPresignatureId { /// A completed presignature. pub struct Presignature { pub id: PresignatureId, - pub output: PresignOutput, + pub output: PresignOutput, pub participants: Vec, } @@ -564,9 +569,15 @@ impl PresignatureSpawner { let epoch = self.epoch; let msg = self.msg.clone(); let my_account_id = self.my_account_id.clone(); + + // Convert the project AffinePoint public key into the ciphersuite + // verifying key expected by threshold-signatures. + let pk_element: Element = ProjectivePoint::from(self.public_key); + let verifying_key = VerifyingKey::::new(pk_element); + let keygen_out = KeygenOutput { private_share: self.private_share, - public_key: self.public_key, + public_key: verifying_key, }; let task = async move { @@ -575,11 +586,7 @@ impl PresignatureSpawner { }; let (pair, dropper) = triples.take(); - let protocol = match cait_sith::presign( - &participants, - me, - // These paramaters appear to be to make it easier to use different indexing schemes for triples - // Introduced in this PR https://github.com/LIT-Protocol/cait-sith/pull/7 + let protocol = match ot_based_ecdsa::presign::presign( &participants, me, PresignArguments { @@ -855,8 +862,8 @@ impl PendingTriples { #[cfg(test)] mod tests { - use cait_sith::{protocol::Participant, PresignOutput}; use k256::{elliptic_curve::CurveArithmetic, Secp256k1}; + use threshold_signatures::{ecdsa::ot_based_ecdsa::PresignOutput, participants::Participant}; use crate::protocol::presignature::Presignature; diff --git a/chain-signatures/node/src/protocol/signature.rs b/chain-signatures/node/src/protocol/signature.rs index 1b217b336..2bd3242b9 100644 --- a/chain-signatures/node/src/protocol/signature.rs +++ b/chain-signatures/node/src/protocol/signature.rs @@ -1,7 +1,6 @@ use super::MpcSignProtocol; use crate::backlog::Backlog; use crate::config::Config; -use crate::kdf::derive_delta; use crate::mesh::MeshState; use crate::protocol::contract::primitives::intersect_vec; use crate::protocol::message::{ @@ -14,13 +13,10 @@ use crate::rpc::{ContractStateWatcher, RpcChannel}; use crate::storage::presignature_storage::{PresignatureTaken, PresignatureTakenDropper}; use crate::storage::PresignatureStorage; use crate::types::SignatureProtocol; -use crate::util::{AffinePointExt, JoinMap, TimeoutBudget}; +use crate::util::{JoinMap, TimeoutBudget}; use crate::protocol::SignRequestType; -use cait_sith::protocol::{Action, InitializationError, Participant}; -use cait_sith::PresignOutput; use chrono::Utc; -use k256::Secp256k1; use mpc_contract::config::ProtocolConfig; use mpc_crypto::{derive_key, PublicKey}; use mpc_primitives::{SignArgs, SignId}; @@ -30,6 +26,13 @@ use rand::SeedableRng; use std::collections::{BTreeSet, HashMap, VecDeque}; use std::sync::Arc; use std::time::{Duration, Instant}; +use threshold_signatures::ecdsa::ot_based_ecdsa::RerandomizedPresignOutput; +use threshold_signatures::ecdsa::RerandomizationArguments; +use threshold_signatures::ecdsa::Tweak; +use threshold_signatures::errors::InitializationError; +use threshold_signatures::participants::Participant; +use threshold_signatures::participants::ParticipantList; +use threshold_signatures::protocol::Action; use tokio::sync::{mpsc, watch, RwLock}; use tokio::task::JoinHandle; @@ -856,19 +859,31 @@ impl SignGenerator { ); let (presignature, dropper) = taken.take(); - let PresignOutput { big_r, k, sigma } = presignature.output; - let delta = derive_delta(indexed.id.request_id, indexed.args.entropy, big_r); - // TODO: Check whether it is okay to use invert_vartime instead - let output: PresignOutput = PresignOutput { - big_r: (big_r * delta).to_affine(), - k: k * delta.invert().unwrap(), - sigma: (sigma + indexed.args.epsilon * k) * delta.invert().unwrap(), - }; - let protocol = Box::new(cait_sith::sign( + // Rerandomize the presignature using the same public entropy used by + // derive_delta. `threshold-signatures` exposes a helper for this. + let msg_hash_bytes: [u8; 32] = indexed.args.payload.to_bytes().into(); + let tweak = Tweak::new(indexed.args.epsilon); + let participants_list = ParticipantList::new(&participants).unwrap(); + let rerand_args = RerandomizationArguments::new( + ctx.public_key, + tweak, + msg_hash_bytes, + presignature.output.big_r, + participants_list, + indexed.args.entropy, + ); + let rerandomized: RerandomizedPresignOutput = + RerandomizedPresignOutput::rerandomize_presign(&presignature.output, &rerand_args) + .map_err(|e| { + InitializationError::BadParameters(format!("rerandomization failed: {e:?}")) + })?; + + let protocol = Box::new(threshold_signatures::ecdsa::ot_based_ecdsa::sign::sign( &participants, + proposer, ctx.me, derive_key(ctx.public_key, indexed.args.epsilon), - output, + rerandomized, indexed.args.payload, )?); let inbox = ctx.msg.subscribe_signature(sign_id, presignature_id).await; @@ -1011,18 +1026,23 @@ impl SignGenerator { .await; } Action::Return(output) => { - let big_r = output.big_r; - let s = output.s; tracing::info!( ?sign_id, ?me, presignature_id, - big_r = ?big_r.to_base58(), - ?s, + proposer = ?self.proposer, + publisher = output.is_some(), + big_r = ?output.as_ref().map(|sig| sig.big_r), + s = ?output.as_ref().map(|sig| sig.s), elapsed = ?self.created.elapsed(), "completed signature generation" ); + let Some(output) = output else { + tracing::info!(?sign_id, "signature completed => we aren't the proposer"); + break Ok(()); + }; + accrued_wait_delay.observe(total_wait.as_millis() as f64); poke_counts.observe(total_pokes as f64); crate::metrics::protocols::SIGN_GENERATION_LATENCY @@ -1030,14 +1050,12 @@ impl SignGenerator { .observe(self.created.elapsed().as_secs_f64()); signature_generator_success_metric.inc(); - if self.proposer == me { - ctx.rpc.publish( - ctx.public_key, - self.indexed.clone(), - output, - self.participants.clone(), - ); - } + ctx.rpc.publish( + ctx.public_key, + self.indexed.clone(), + output, + self.participants.clone(), + ); if let SignRequestType::SignBidirectional(event) = &self.indexed.sign_request_type diff --git a/chain-signatures/node/src/protocol/state.rs b/chain-signatures/node/src/protocol/state.rs index c3f1fe0b5..05e28381a 100644 --- a/chain-signatures/node/src/protocol/state.rs +++ b/chain-signatures/node/src/protocol/state.rs @@ -4,9 +4,9 @@ use crate::protocol::presignature::PresignatureSpawnerTask; use crate::protocol::signature::SignatureSpawnerTask; use crate::types::{KeygenProtocol, ReshareProtocol, SecretKeyShare}; -use cait_sith::protocol::Participant; use mpc_crypto::PublicKey; use serde::{Deserialize, Serialize}; +use threshold_signatures::participants::Participant; use tokio::sync::watch; use rand::random; diff --git a/chain-signatures/node/src/protocol/sync/mod.rs b/chain-signatures/node/src/protocol/sync/mod.rs index 7bc676829..c6c23475a 100644 --- a/chain-signatures/node/src/protocol/sync/mod.rs +++ b/chain-signatures/node/src/protocol/sync/mod.rs @@ -1,8 +1,8 @@ use std::sync::Arc; use std::time::{Duration, Instant}; -use cait_sith::protocol::Participant; use serde::{Deserialize, Serialize}; +use threshold_signatures::participants::Participant; use tokio::sync::{mpsc, watch}; use tokio::task::{JoinHandle, JoinSet}; diff --git a/chain-signatures/node/src/protocol/triple.rs b/chain-signatures/node/src/protocol/triple.rs index 14ba9bc90..0999f4664 100644 --- a/chain-signatures/node/src/protocol/triple.rs +++ b/chain-signatures/node/src/protocol/triple.rs @@ -10,12 +10,15 @@ use crate::util::{AffinePointExt, JoinMap}; use mpc_contract::config::ProtocolConfig; -use cait_sith::protocol::{Action, InitializationError, Participant}; -use cait_sith::triples::{TriplePub, TripleShare}; use chrono::Utc; use highway::{HighwayHash, HighwayHasher}; use k256::elliptic_curve::group::GroupEncoding; -use k256::Secp256k1; +use rand::rngs::OsRng; +use threshold_signatures::ecdsa::ot_based_ecdsa::triples::{TriplePub, TripleShare}; +use threshold_signatures::errors::InitializationError; +use threshold_signatures::participants::Participant; +use threshold_signatures::protocol::Action; +// Secp256k1 is not used here; referenced in inner code if necessary from k256 directly. use near_account_id::AccountId; use serde::{Deserialize, Serialize}; use tokio::sync::{mpsc, watch}; @@ -26,15 +29,15 @@ use std::fmt; use std::time::{Duration, Instant}; /// Unique number used to identify a specific ongoing triple generation protocol. -/// Without `TripleId` it would be unclear where to route incoming cait-sith triple generation +/// Without `TripleId` it would be unclear where to route incoming triple generation /// messages. pub type TripleId = u64; /// A completed triple. #[derive(Clone, Serialize, Deserialize, Debug)] pub struct Triple { - pub share: TripleShare, - pub public: TriplePub, + pub share: TripleShare, + pub public: TriplePub, } struct TripleGenerator { @@ -68,8 +71,9 @@ impl TripleGenerator { // for the triple_is_mine check: participants.sort(); - let protocol = - cait_sith::triples::generate_triple_many::(&participants, me, threshold)?; + let protocol = threshold_signatures::ecdsa::ot_based_ecdsa::triples::generate_triple_many::< + 2, + >(&participants, me, threshold, OsRng)?; let inbox = msg.subscribe_triple(id).await; Ok(Self { diff --git a/chain-signatures/node/src/rpc.rs b/chain-signatures/node/src/rpc.rs index ba98c3431..6e9de3fd9 100644 --- a/chain-signatures/node/src/rpc.rs +++ b/chain-signatures/node/src/rpc.rs @@ -15,12 +15,12 @@ use alloy::primitives::Address; use alloy::providers::fillers::{FillProvider, JoinFill, WalletFiller}; use alloy::providers::{Provider, RootProvider, WalletProvider}; use alloy::rpc::types::{Transaction, TransactionReceipt}; -use cait_sith::protocol::Participant; -use cait_sith::FullSignature; -use k256::{AffinePoint, Secp256k1}; +use k256::AffinePoint; use mpc_keys::hpke; use mpc_primitives::SignId; use mpc_primitives::Signature; +use threshold_signatures::ecdsa::Signature as ThresholdSignature; +use threshold_signatures::participants::Participant; use alloy::contract::{ContractInstance, Interface}; use alloy::dyn_abi::DynSolValue; @@ -90,7 +90,7 @@ type EthContractInstance = ContractInstance; pub struct PublishAction { pub public_key: mpc_crypto::PublicKey, pub indexed: IndexedSignRequest, - output: FullSignature, + output: ThresholdSignature, pub participants: Vec, timestamp: Instant, retry_count: usize, @@ -110,7 +110,7 @@ impl RpcChannel { &self, public_key: mpc_crypto::PublicKey, indexed: IndexedSignRequest, - output: FullSignature, + output: ThresholdSignature, participants: Vec, ) { let rpc = self.clone(); diff --git a/chain-signatures/node/src/sign_bidirectional.rs b/chain-signatures/node/src/sign_bidirectional.rs index c79b16b6c..658b07281 100644 --- a/chain-signatures/node/src/sign_bidirectional.rs +++ b/chain-signatures/node/src/sign_bidirectional.rs @@ -325,8 +325,10 @@ pub fn sign_and_hash_legacy_from_unsigned( } /// Get the x coordinate of a point, as a scalar -fn x_coordinate(point: &C::AffinePoint) -> C::Scalar { - ::Uint>>::reduce_bytes(&point.x()) +fn x_coordinate(point: &k256::AffinePoint) -> k256::Scalar { + use k256::elliptic_curve::bigint::U256; + use k256::elliptic_curve::ops::Reduce; + >::reduce_bytes(&point.x()) } fn public_key_to_address(public_key: &secp256k1::PublicKey) -> Address { @@ -346,7 +348,7 @@ pub fn derive_user_address(mpc_pk: mpc_crypto::PublicKey, derivation_epsilon: Sc _ => unreachable!(), }; - let x_coord = x_coordinate::(&user_pk); + let x_coord = x_coordinate(&user_pk); let x_only = secp256k1::XOnlyPublicKey::from_slice(&x_coord.to_bytes()).unwrap(); let secp_pk = secp256k1::PublicKey::from_x_only_public_key(x_only, parity); diff --git a/chain-signatures/node/src/storage/mod.rs b/chain-signatures/node/src/storage/mod.rs index 247aeb5f0..53e7c4b0c 100644 --- a/chain-signatures/node/src/storage/mod.rs +++ b/chain-signatures/node/src/storage/mod.rs @@ -5,8 +5,8 @@ pub mod protocol_storage; pub mod secret_storage; pub mod triple_storage; -use cait_sith::protocol::Participant; pub use presignature_storage::PresignatureStorage; +use threshold_signatures::participants::Participant; pub use triple_storage::TripleStorage; // Can be used to "clear" redis storage in case of a breaking change diff --git a/chain-signatures/node/src/storage/presignature_storage.rs b/chain-signatures/node/src/storage/presignature_storage.rs index a8c3f0b90..51b0f9dd6 100644 --- a/chain-signatures/node/src/storage/presignature_storage.rs +++ b/chain-signatures/node/src/storage/presignature_storage.rs @@ -1,5 +1,5 @@ use deadpool_redis::Pool; -use near_sdk::AccountId; +use near_account_id::AccountId; use redis::{FromRedisValue, RedisError, RedisWrite, ToRedisArgs}; use super::protocol_storage::{ArtifactSlot, ArtifactTaken, ArtifactTakenDropper, ProtocolStorage}; diff --git a/chain-signatures/node/src/storage/protocol_storage.rs b/chain-signatures/node/src/storage/protocol_storage.rs index f364efb84..9d8c880c1 100644 --- a/chain-signatures/node/src/storage/protocol_storage.rs +++ b/chain-signatures/node/src/storage/protocol_storage.rs @@ -1,13 +1,12 @@ -use cait_sith::protocol::Participant; use deadpool_redis::{Connection, Pool}; use near_sdk::AccountId; use redis::{AsyncCommands, FromRedisValue, ToRedisArgs}; use std::collections::HashSet; use std::sync::Arc; use std::{fmt, time::Instant}; +use threshold_signatures::participants::Participant; use tokio::sync::RwLock; use tokio::task::JoinHandle; -use tracing; use super::{owner_key, STORAGE_VERSION}; @@ -585,12 +584,24 @@ impl ProtocolStorage { local artifact_id = ARGV[1] local artifact = ARGV[2] +<<<<<<< HEAD +======= + -- Remove from used set + redis.call("HDEL", used_key, artifact_id) + +>>>>>>> a5e1ae5a (Add tss crate) -- Add back to artifact hash map redis.call("HSET", artifact_key, artifact_id, artifact) -- Add back to mine set redis.call("SADD", mine_key, artifact_id) +<<<<<<< HEAD +======= + -- Ensure it is still reserved + redis.call("SADD", reserved_key, artifact_id) + +>>>>>>> a5e1ae5a (Add tss crate) return 1 "#; diff --git a/chain-signatures/node/src/storage/triple_storage.rs b/chain-signatures/node/src/storage/triple_storage.rs index 90dd0a6b8..0b9d01646 100644 --- a/chain-signatures/node/src/storage/triple_storage.rs +++ b/chain-signatures/node/src/storage/triple_storage.rs @@ -3,11 +3,10 @@ use near_sdk::AccountId; use redis::{FromRedisValue, RedisError, RedisWrite, ToRedisArgs}; use serde::{Deserialize, Serialize}; -use crate::protocol::triple::{Triple, TripleId}; - use super::protocol_storage::{ ArtifactSlot, ArtifactTaken, ArtifactTakenDropper, ProtocolArtifact, ProtocolStorage, }; +use crate::protocol::triple::{Triple, TripleId}; pub type TripleStorage = ProtocolStorage; pub type TriplePairSlot = ArtifactSlot; diff --git a/chain-signatures/node/src/types.rs b/chain-signatures/node/src/types.rs index 1e060a2ca..b4fb52f3c 100644 --- a/chain-signatures/node/src/types.rs +++ b/chain-signatures/node/src/types.rs @@ -1,22 +1,25 @@ -use cait_sith::protocol::{Action, InitializationError, MessageData, Participant, ProtocolError}; -use cait_sith::{protocol::Protocol, KeygenOutput}; -use cait_sith::{FullSignature, PresignOutput}; -use k256::{elliptic_curve::CurveArithmetic, Secp256k1}; +use k256::ProjectivePoint; +use rand::rngs::OsRng; +use threshold_signatures::ecdsa::ot_based_ecdsa::triples::{TriplePub, TripleShare}; +use threshold_signatures::ecdsa::ot_based_ecdsa::PresignOutput; +use threshold_signatures::ecdsa::Signature as EcdsaSignature; +use threshold_signatures::ecdsa::{KeygenOutput, Secp256K1Sha256}; +use threshold_signatures::errors::{InitializationError, ProtocolError}; +use threshold_signatures::frost_core::keys::SigningShare; +use threshold_signatures::frost_core::{Element, VerifyingKey}; +use threshold_signatures::participants::Participant; +use threshold_signatures::protocol::{Action, MessageData, Protocol}; use crate::protocol::contract::ResharingContractState; -pub type SecretKeyShare = ::Scalar; -pub type TripleProtocol = Box< - dyn Protocol< - Output = Vec<( - cait_sith::triples::TripleShare, - cait_sith::triples::TriplePub, - )>, - > + Send - + Sync, ->; -pub type PresignatureProtocol = Box> + Send + Sync>; -pub type SignatureProtocol = Box> + Send + Sync>; +pub type SecretKeyShare = SigningShare; +pub type TripleProtocol = Box> + Send>; +// Presignature protocol implementations from `threshold-signatures` are not +// necessarily `Sync` across the board; make the trait object `Send` only. +pub type PresignatureProtocol = Box + Send>; +// Signature protocols return `SignatureOption` (Option) via +// `threshold-signatures`. Keep the boxed trait object send + sync. +pub type SignatureProtocol = Box> + Send>; pub type Epoch = u64; @@ -24,7 +27,7 @@ pub struct KeygenProtocol { me: Participant, threshold: usize, participants: Vec, - protocol: Box> + Send + Sync>, + protocol: Box + Send>, } impl KeygenProtocol { @@ -33,24 +36,34 @@ impl KeygenProtocol { me: Participant, threshold: usize, ) -> Result { + use rand::rngs::OsRng; + Ok(Self { threshold, me, participants: participants.into(), - protocol: Box::new(cait_sith::keygen::(participants, me, threshold)?), + protocol: Box::new(threshold_signatures::keygen::( + participants, + me, + threshold, + OsRng, + )?), }) } pub async fn refresh(&mut self) -> Result<(), InitializationError> { - self.protocol = Box::new(cait_sith::keygen::( + use rand::rngs::OsRng; + + self.protocol = Box::new(threshold_signatures::keygen::( &self.participants, self.me, self.threshold, + OsRng, )?); Ok(()) } - pub fn poke(&mut self) -> Result>, ProtocolError> { + pub fn poke(&mut self) -> Result, ProtocolError> { self.protocol.poke() } @@ -60,7 +73,7 @@ impl KeygenProtocol { } pub struct ReshareProtocol { - protocol: Box + Send + Sync>, + protocol: Box + Send>, } impl ReshareProtocol { @@ -77,19 +90,26 @@ impl ReshareProtocol { new_participants, me ); - let protocol = Box::new(cait_sith::reshare::( + + // Convert the AffinePoint public key into the ciphersuite verifying key + // `AffinePoint` -> `ProjectivePoint` conversion uses `ProjectivePoint::from` + let pk_element: Element = ProjectivePoint::from(contract_state.public_key); + let verifying_key = VerifyingKey::::new(pk_element); + + let protocol = Box::new(threshold_signatures::reshare::( &old_participants, contract_state.threshold, + private_share, + verifying_key, &new_participants, contract_state.threshold, me, - private_share, - contract_state.public_key, + OsRng, )?); Ok(Self { protocol }) } - pub fn poke(&mut self) -> Result, ProtocolError> { + pub fn poke(&mut self) -> Result, ProtocolError> { self.protocol.poke() } diff --git a/chain-signatures/node/src/web/mock.rs b/chain-signatures/node/src/web/mock.rs index 1371c2eec..c8043a346 100644 --- a/chain-signatures/node/src/web/mock.rs +++ b/chain-signatures/node/src/web/mock.rs @@ -1,6 +1,6 @@ -use cait_sith::protocol::Participant; use mockito::ServerGuard; use near_sdk::AccountId; +use threshold_signatures::participants::Participant; use crate::{ node_client::NodeClient, diff --git a/chain-signatures/node/src/web/mod.rs b/chain-signatures/node/src/web/mod.rs index 6199a3c6a..fce6bc2ff 100644 --- a/chain-signatures/node/src/web/mod.rs +++ b/chain-signatures/node/src/web/mod.rs @@ -22,7 +22,6 @@ use axum::http::StatusCode; use axum::routing::{get, post}; use axum::{Extension, Json, Router}; use axum_extra::extract::WithRejection; -use cait_sith::protocol::Participant; use mpc_keys::hpke::Ciphered; use near_account_id::AccountId; use near_primitives::types::BlockHeight; @@ -31,6 +30,7 @@ use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::sync::Arc; use std::time::Instant; +use threshold_signatures::participants::Participant; struct AxumState { node: NodeStateWatcher, diff --git a/doc/SCALING_AND_SECURITY.md b/doc/SCALING_AND_SECURITY.md index 5353cca2c..e80995428 100644 --- a/doc/SCALING_AND_SECURITY.md +++ b/doc/SCALING_AND_SECURITY.md @@ -2,4 +2,4 @@ Currently chain signatures operates using one signature genertion network and can handle up to 16 concurent requests. Average response time including all network delays is ~4 seconds on Solana. We are planning to improve both metrics wich will allow to handle more requests and reduce response time. ## Security properties -Chain signatures is usign cait-sith threshold ECDSA protocol. Currently our network consist of 8 nodes with treshold 5. This means that at least 5 nodes must collaborate in order to create a valid signature. \ No newline at end of file +Chain signatures is using threshold-signatures threshold ECDSA protocol. Currently our network consist of 8 nodes with threshold 5. This means that at least 5 nodes must collaborate in order to create a valid signature. \ No newline at end of file diff --git a/doc/mpc_node_specification.md b/doc/mpc_node_specification.md index aeeb487de..cbd20af92 100644 --- a/doc/mpc_node_specification.md +++ b/doc/mpc_node_specification.md @@ -108,8 +108,8 @@ participant set. In the prepare phase, we specifically don't know the participant set, yet, thus we should not send messages unless we are okay with wasting Ps and Ts. -Even without the black box assumption, we know that cait-sith requires strict -non-reuse of Ps and Ts. +Even without the black box assumption, we know that threshold-signatures requires strict +non-reuse of Ps and Ts. *Why should we still care about incoming messages?* diff --git a/integration-tests/Cargo.toml b/integration-tests/Cargo.toml index 27980a60b..443548df5 100644 --- a/integration-tests/Cargo.toml +++ b/integration-tests/Cargo.toml @@ -48,7 +48,7 @@ solana-transaction-status.workspace = true ecdsa = "0.16.9" ethers-core.workspace = true ethers = { version = "2.0.13", features = ["abigen"] } -cait-sith = { git = "https://github.com/sig-net/cait-sith", rev = "9f34e8c", features = ["k256"] } +threshold-signatures.workspace = true elliptic-curve = { version = "0.13.5", default-features = false } k256 = { version = "0.13.1", features = ["sha256", "ecdsa", "serde"] } secp256k1.workspace = true diff --git a/integration-tests/benches/store.rs b/integration-tests/benches/store.rs index b6be6923b..0fedb10db 100644 --- a/integration-tests/benches/store.rs +++ b/integration-tests/benches/store.rs @@ -1,10 +1,5 @@ use std::time::Instant; -use cait_sith::{ - protocol::Participant, - triples::{TriplePub, TripleShare}, - PresignOutput, -}; use criterion::{criterion_group, criterion_main, Criterion}; use elliptic_curve::CurveArithmetic; use integration_tests::{cluster::spawner::ClusterSpawner, containers::Redis}; @@ -23,6 +18,9 @@ use mpc_node::{ storage::{triple_storage::TriplePair, PresignatureStorage, TripleStorage}, }; use near_account_id::AccountId; +use threshold_signatures::ecdsa::ot_based_ecdsa::triples::{TriplePub, TripleShare}; +use threshold_signatures::ecdsa::ot_based_ecdsa::PresignOutput; +use threshold_signatures::participants::Participant; use tokio::{ runtime::Runtime, sync::{mpsc, watch}, diff --git a/integration-tests/src/actions/mod.rs b/integration-tests/src/actions/mod.rs index f72618c98..ef3c92321 100644 --- a/integration-tests/src/actions/mod.rs +++ b/integration-tests/src/actions/mod.rs @@ -5,12 +5,11 @@ pub mod wait_for; use crate::cluster::Cluster; use anyhow::Context as _; -use cait_sith::FullSignature; use elliptic_curve::sec1::ToEncodedPoint; use k256::ecdsa::VerifyingKey; use k256::elliptic_curve::point::AffineCoordinates; use k256::elliptic_curve::sec1::FromEncodedPoint; -use k256::{AffinePoint, EncodedPoint, Scalar, Secp256k1}; +use k256::{AffinePoint, EncodedPoint, Scalar}; use mpc_contract::errors::SignError; use mpc_contract::primitives::SignRequest; use mpc_crypto::ScalarExt; @@ -23,6 +22,7 @@ use near_workspaces::types::Gas; use near_workspaces::types::NearToken; use near_workspaces::Account; use rand::Rng; +use threshold_signatures::ecdsa::Signature as FullSignature; use wait_for::{SignatureError, WaitForError}; use std::time::Duration; @@ -105,7 +105,7 @@ pub async fn validate_signature( account_id: &near_workspaces::AccountId, mpc_pk_bytes: &[u8], payload: [u8; 32], - signature: &FullSignature, + signature: &FullSignature, ) -> anyhow::Result<()> { let mpc_point = EncodedPoint::from_bytes(mpc_pk_bytes).unwrap(); let mpc_pk = AffinePoint::from_encoded_point(&mpc_point).unwrap(); @@ -152,7 +152,7 @@ pub async fn batch_duplicate_signature_production(nodes: &Cluster) -> anyhow::Re } /// Get the x coordinate of a point, as a scalar -pub fn x_coordinate(point: &C::AffinePoint) -> C::Scalar { +pub fn x_coordinate(point: &C::AffinePoint) -> C::Scalar { ::Uint>>::reduce_bytes(&point.x()) } @@ -257,6 +257,7 @@ mod tests { use k256::{AffinePoint, EncodedPoint, Scalar}; use mpc_crypto::{derive_epsilon_near, derive_key, ScalarExt as _}; use mpc_primitives::LEGACY_MPC_KEY_VERSION_0; + use threshold_signatures::ecdsa::Signature as FullSignature; use super::{public_key_to_address, recover, recover_eth_address, x_coordinate}; @@ -309,8 +310,7 @@ mod tests { let s = k256::Scalar::from_bytes(s).unwrap(); let r = x_coordinate::(&big_r); - let signature = cait_sith::FullSignature:: { big_r, s }; - + let signature = FullSignature { big_r, s }; let multichain_sig = mpc_node::kdf::into_eth_sig( &user_pk, &signature.big_r, @@ -319,7 +319,6 @@ mod tests { ) .unwrap(); - // Check signature using cait-sith tooling let is_signature_valid_for_user_pk = signature.verify(&user_pk, &payload_hash_scalar); let is_signature_valid_for_mpc_pk = signature.verify(&mpc_pk, &payload_hash_scalar); let another_user_pk = derive_key(mpc_pk, derivation_epsilon + k256::Scalar::ONE); diff --git a/integration-tests/src/actions/sign.rs b/integration-tests/src/actions/sign.rs index d667e50f8..02e75c779 100644 --- a/integration-tests/src/actions/sign.rs +++ b/integration-tests/src/actions/sign.rs @@ -13,11 +13,9 @@ use alloy::sol_types::SolEvent; use anchor_client::anchor_lang::{AnchorDeserialize, Discriminator}; use anchor_client::{Client, Cluster as AnchorCluster}; use anyhow::Context as _; -use cait_sith::FullSignature; use elliptic_curve::sec1::FromEncodedPoint; use futures::StreamExt; use generic_array::GenericArray; -use k256::Secp256k1; use mpc_contract::errors; use mpc_contract::primitives::SignRequest; use mpc_crypto::ScalarExt as _; @@ -35,6 +33,7 @@ use solana_sdk::commitment_config::CommitmentConfig; use solana_sdk::pubkey::Pubkey; use solana_sdk::signature::Signature as SolSignature; use solana_sdk::signer::Signer as _; +use threshold_signatures::ecdsa::Signature as FullSignature; use tokio::sync::oneshot; use tokio::time::sleep; @@ -116,7 +115,7 @@ pub struct SignOutcome { pub payload: [u8; 32], pub payload_hash: [u8; 32], - pub signature: FullSignature, + pub signature: FullSignature, } impl fmt::Debug for SignOutcome { @@ -376,7 +375,7 @@ impl<'a> IntoFuture for SolSignAction<'a> { pub struct SolSignOutcome { pub tx_signature: SolSignature, - pub signature: FullSignature, + pub signature: FullSignature, pub recovery_id: u8, pub signer_account: String, pub request_id: [u8; 32], @@ -411,7 +410,7 @@ impl fmt::Debug for SolSignOutcome { struct SolSignatureResponse { request_id: [u8; 32], - signature: FullSignature, + signature: FullSignature, recovery_id: u8, } @@ -419,7 +418,7 @@ pub struct SolRespondBidirectionalOutcome { pub request_id: [u8; 32], pub responder: String, pub serialized_output: Vec, - pub signature: FullSignature, + pub signature: FullSignature, pub recovery_id: u8, } @@ -847,12 +846,18 @@ impl SignAction<'_> { // We have to use seperate transactions because one could fail. // This leads to a potential race condition where this transaction could get sent after the signature completes, but I think that's unlikely let rogue = if self.execute_rogue { + // wait a little for the tx to appear in sandbox + tokio::time::sleep(Duration::from_millis(500)).await; let (rogue, rogue_status) = self .transact_rogue_respond(payload_hash, account.id()) .await?; let err = wait_for::rogue_message_responded(rogue_status).await?; - assert!(err.contains(&errors::RespondError::InvalidSignature.to_string())); + assert!( + err.contains(&errors::RespondError::InvalidSignature.to_string()) + || err.contains(&errors::InvalidParameters::RequestNotFound.to_string()), + "{err:?}" + ); Some(rogue) } else { None @@ -980,7 +985,7 @@ impl SignAction<'_> { /// Convert a Solana contract signature to FullSignature fn parse_sol_signature( solana_sig: &signet_program::Signature, -) -> anyhow::Result<(FullSignature, u8)> { +) -> anyhow::Result<(FullSignature, u8)> { use k256::elliptic_curve::sec1::FromEncodedPoint; use k256::{AffinePoint, Scalar}; @@ -1011,7 +1016,7 @@ pub struct EthSignOutcome { pub contract_address: String, pub eth_tx_hash: Option, pub deposit_amount: u64, - pub signature: FullSignature, + pub signature: FullSignature, pub payload: [u8; 32], pub payload_hash: [u8; 32], pub algo: String, @@ -1310,7 +1315,7 @@ impl EthSignAction<'_> { let s = k256::Scalar::from_bytes(s_bytes.into()) .ok_or_else(|| anyhow::anyhow!("invalid scalar value in event {s_bytes:?}"))?; - let signature = FullSignature:: { big_r, s }; + let signature = FullSignature { big_r, s }; tracing::info!("successfully parsed signature from SignatureResponded event"); return Ok(EthSignOutcome { diff --git a/integration-tests/src/actions/wait.rs b/integration-tests/src/actions/wait.rs index bb8c47d1b..f36bc5cd3 100644 --- a/integration-tests/src/actions/wait.rs +++ b/integration-tests/src/actions/wait.rs @@ -319,7 +319,7 @@ pub async fn running_mpc( let strategy = ConstantBuilder::default() .with_delay(std::time::Duration::from_millis(500)) - .with_max_times(40); + .with_max_times(80); is_running.retry(&strategy).await.with_context(|| { format!( diff --git a/integration-tests/src/actions/wait_for.rs b/integration-tests/src/actions/wait_for.rs index cf31a4809..91b22015a 100644 --- a/integration-tests/src/actions/wait_for.rs +++ b/integration-tests/src/actions/wait_for.rs @@ -4,8 +4,6 @@ use std::time::Duration; use anyhow::Context; use backon::ConstantBuilder; use backon::Retryable; -use cait_sith::FullSignature; -use k256::Secp256k1; use mpc_primitives::Signature; use near_fetch::ops::AsyncTransactionStatus; use near_primitives::errors::ActionErrorKind; @@ -14,6 +12,7 @@ use near_primitives::views::ExecutionOutcomeWithIdView; use near_primitives::views::ExecutionStatusView; use near_primitives::views::FinalExecutionStatus; use std::collections::HashMap; +use threshold_signatures::ecdsa::Signature as FullSignature; #[derive(Debug, thiserror::Error)] pub enum SignatureError { @@ -36,14 +35,14 @@ pub enum WaitForError { /// Used locally for testing to circumvent retrying on all errors. This will avoid retrying /// on failed signatures as we should abort early on those when in the retrying loop. enum Outcome { - Signature(FullSignature), + Signature(FullSignature), Failed(String), - Signatures(Vec>), + Signatures(Vec), } pub async fn signature_responded( status: AsyncTransactionStatus, -) -> Result, WaitForError> { +) -> Result { let is_tx_ready = || async { let Poll::Ready(outcome) = status .status() @@ -60,7 +59,7 @@ pub async fn signature_responded( let result: Signature = outcome .json() .map_err(|err| WaitForError::SerdeJson(format!("{err:?}")))?; - Ok(Outcome::Signature(cait_sith::FullSignature:: { + Ok(Outcome::Signature(FullSignature { big_r: result.big_r, s: result.s, })) @@ -136,7 +135,7 @@ pub async fn rogue_message_responded(status: AsyncTransactionStatus) -> anyhow:: pub async fn batch_signature_responded( status: AsyncTransactionStatus, -) -> Result>, WaitForError> { +) -> Result, WaitForError> { let is_tx_ready = || async { let Poll::Ready(outcome) = status .status() @@ -170,7 +169,7 @@ pub async fn batch_signature_responded( let starting_receipts = &receipt_outcomes.first().unwrap().outcome.receipt_ids; - let mut signatures: Vec> = vec![]; + let mut signatures: Vec = vec![]; for receipt_id in starting_receipts { if !result_receipts.contains_key(receipt_id) { break; @@ -190,7 +189,7 @@ pub async fn batch_signature_responded( ExecutionStatusView::SuccessValue(value) => { let result: Signature = serde_json::from_slice(&value) .map_err(|err| WaitForError::SerdeJson(format!("{err:?}")))?; - let signature = cait_sith::FullSignature:: { + let signature = FullSignature { big_r: result.big_r, s: result.s, }; diff --git a/integration-tests/src/cluster/spawner.rs b/integration-tests/src/cluster/spawner.rs index 1ec57c408..91d7109b5 100644 --- a/integration-tests/src/cluster/spawner.rs +++ b/integration-tests/src/cluster/spawner.rs @@ -1,9 +1,9 @@ -use cait_sith::protocol::Participant; use mpc_contract::config::ProtocolConfig; use mpc_node::protocol::state::NodeKeyInfo; use near_account_id::AccountId; use near_workspaces::network::Sandbox; use near_workspaces::{Account, Worker}; +use threshold_signatures::participants::Participant; use std::collections::BTreeMap; use std::future::{Future, IntoFuture}; diff --git a/integration-tests/src/containers.rs b/integration-tests/src/containers.rs index 30e57f9ce..eb4eb4a96 100644 --- a/integration-tests/src/containers.rs +++ b/integration-tests/src/containers.rs @@ -13,13 +13,10 @@ use bollard::network::CreateNetworkOptions; use bollard::secret::Ipam; use bollard::Docker; use borsh::{BorshDeserialize, BorshSerialize}; -use cait_sith::protocol::Participant; -use cait_sith::triples::{TriplePub, TripleShare}; -use cait_sith::FullSignature; use elliptic_curve::rand_core::OsRng; use futures::StreamExt as _; use k256::elliptic_curve::sec1::ToEncodedPoint as _; -use k256::Secp256k1; +use k256::ProjectivePoint; use mpc_contract::primitives::Participants; use mpc_keys::hpke; use mpc_node::config::OverrideConfig; @@ -45,6 +42,10 @@ use testcontainers::{ runners::AsyncRunner, GenericImage, ImageExt, }; +use threshold_signatures::ecdsa::ot_based_ecdsa::triples::{TriplePub, TripleShare}; +use threshold_signatures::ecdsa::Polynomial; +use threshold_signatures::ecdsa::Signature as FullSignature; +use threshold_signatures::participants::Participant; use tokio::io::AsyncWriteExt; use tokio::time::{sleep, Duration}; use tracing; @@ -405,8 +406,37 @@ impl Redis { .values() .map(|id| Participant::from(*id)) .collect::>(); - let (public, shares): (TriplePub, Vec>) = - cait_sith::triples::deal(&mut OsRng, &participant_ids, cfg.threshold); + + // Create triples by sampling values and distributing shares (similar to + // `threshold-signatures` test helper `deal`). + let mut rng = OsRng; + let f_a = Polynomial::generate_polynomial(None, cfg.threshold - 1, &mut rng).unwrap(); + let a = f_a.eval_at_zero().unwrap().0; + + let f_b = Polynomial::generate_polynomial(None, cfg.threshold - 1, &mut rng).unwrap(); + let b = f_b.eval_at_zero().unwrap().0; + let c = a * b; + let f_c = Polynomial::generate_polynomial(Some(c), cfg.threshold - 1, &mut rng).unwrap(); + + let mut shares = Vec::with_capacity(participant_ids.len()); + let mut participants_owned = Vec::with_capacity(participant_ids.len()); + + for p in &participant_ids { + participants_owned.push(*p); + shares.push(TripleShare { + a: f_a.eval_at_participant(*p).unwrap().0, + b: f_b.eval_at_participant(*p).unwrap().0, + c: f_c.eval_at_participant(*p).unwrap().0, + }); + } + + let public = TriplePub { + big_a: (ProjectivePoint::GENERATOR * a).to_affine(), + big_b: (ProjectivePoint::GENERATOR * b).to_affine(), + big_c: (ProjectivePoint::GENERATOR * c).to_affine(), + participants: participants_owned, + threshold: cfg.threshold, + }; // - first/second loop add at least min_triples per node // - third loop: for each pair, store the shares as pairs per node @@ -570,10 +600,7 @@ fn derive_secret_key(mnemonic: &str) -> anyhow::Result { Ok(format!("0x{}", hex::encode(bytes))) } -fn shares_to_triples( - public: &TriplePub, - shares: &[TripleShare], -) -> Vec { +fn shares_to_triples(public: &TriplePub, shares: &[TripleShare]) -> Vec { shares .iter() .map(|share| Triple { @@ -1071,7 +1098,7 @@ impl Solana { &self, request_id: [u8; 32], serialized_output: Vec, - signature: &FullSignature, + signature: &FullSignature, recovery_id: u8, ) -> anyhow::Result { if self.rpc_client.get_version().await.is_err() { diff --git a/integration-tests/src/lib.rs b/integration-tests/src/lib.rs index d0fbe1bcc..e8cd24d72 100644 --- a/integration-tests/src/lib.rs +++ b/integration-tests/src/lib.rs @@ -413,7 +413,7 @@ pub async fn setup(spawner: &mut ClusterSpawner) -> anyhow::Result { if spawner.pregenerated_keys.is_enabled() { tracing::info!("injecting pregenerated keyshares into storage..."); for (i, account) in spawner.accounts.iter().enumerate() { - let participant = cait_sith::protocol::Participant::from(i as u32); + let participant = threshold_signatures::participants::Participant::from(i as u32); if let Some(key_info) = spawner.pregenerated_keys.get(&participant) { let mut secret_storage = storage::secret_storage::init( None, // No GCP service for tests diff --git a/integration-tests/src/mpc_fixture/builder.rs b/integration-tests/src/mpc_fixture/builder.rs index 63799c845..4066d18a0 100644 --- a/integration-tests/src/mpc_fixture/builder.rs +++ b/integration-tests/src/mpc_fixture/builder.rs @@ -7,7 +7,6 @@ use crate::mpc_fixture::fixture_tasks::MessageFilter; use crate::mpc_fixture::input::FixtureInput; use crate::mpc_fixture::mock_governance::MockGovernance; use crate::mpc_fixture::{fixture_tasks, MpcFixture, MpcFixtureNode}; -use cait_sith::protocol::Participant; use mpc_contract::config::{min_to_ms, ProtocolConfig}; use mpc_contract::primitives::{ CandidateInfo, Candidates as CandidatesById, ParticipantInfo, Participants as ParticipantsById, @@ -28,6 +27,7 @@ use mpc_node::storage::{secret_storage, triple_storage::TriplePair, Options}; use near_sdk::AccountId; use std::collections::HashMap; use std::sync::Arc; +use threshold_signatures::participants::Participant; use tokio::sync::mpsc::{self, Sender}; use tokio::sync::watch; use tokio::sync::RwLock; diff --git a/integration-tests/src/mpc_fixture/fixture_interface.rs b/integration-tests/src/mpc_fixture/fixture_interface.rs index 8b78fd435..713e8ff7c 100644 --- a/integration-tests/src/mpc_fixture/fixture_interface.rs +++ b/integration-tests/src/mpc_fixture/fixture_interface.rs @@ -2,7 +2,6 @@ //! it with controlled inputs, and assert on outputs. use crate::containers::Redis; -use cait_sith::protocol::Participant; use mpc_node::backlog::Backlog; use mpc_node::config::Config; use mpc_node::mesh::MeshState; @@ -14,6 +13,7 @@ use near_sdk::AccountId; use std::collections::HashSet; use std::sync::Arc; use std::time::Duration; +use threshold_signatures::participants::Participant; use tokio::sync::mpsc; use tokio::sync::{watch, Mutex}; diff --git a/integration-tests/src/mpc_fixture/fixture_tasks.rs b/integration-tests/src/mpc_fixture/fixture_tasks.rs index 13439df2e..a6a034653 100644 --- a/integration-tests/src/mpc_fixture/fixture_tasks.rs +++ b/integration-tests/src/mpc_fixture/fixture_tasks.rs @@ -2,7 +2,6 @@ //! passing between nodes and updates to the governance smart contract. use crate::mpc_fixture::fixture_interface::SharedOutput; -use cait_sith::protocol::Participant; use mpc_keys::hpke::Ciphered; use mpc_node::config::Config; use mpc_node::mesh::MeshState; @@ -11,6 +10,7 @@ use mpc_node::protocol::message::{MessageOutbox, SendMessage, SignedMessage}; use mpc_node::rpc::RpcAction; use std::collections::HashMap; use std::sync::Arc; +use threshold_signatures::participants::Participant; use tokio::sync::mpsc::{Receiver, Sender}; use tokio::sync::watch; use tokio::task::JoinHandle; diff --git a/integration-tests/src/mpc_fixture/input.rs b/integration-tests/src/mpc_fixture/input.rs index d7e907e0d..eac36170a 100644 --- a/integration-tests/src/mpc_fixture/input.rs +++ b/integration-tests/src/mpc_fixture/input.rs @@ -1,8 +1,8 @@ -use cait_sith::protocol::Participant; use mpc_node::protocol::presignature::Presignature; use mpc_node::protocol::state::NodeKeyInfo; use mpc_node::storage::triple_storage::TriplePair; use std::collections::BTreeMap; +use threshold_signatures::participants::Participant; #[derive(serde::Deserialize, serde::Serialize)] pub struct FixtureInput { diff --git a/integration-tests/tests/cases/chains.rs b/integration-tests/tests/cases/chains.rs index 9db08c7df..504f59779 100644 --- a/integration-tests/tests/cases/chains.rs +++ b/integration-tests/tests/cases/chains.rs @@ -1,7 +1,6 @@ use alloy::primitives::{keccak256, Address as AlloyAddress, U256}; use anyhow::Context as _; use anyhow::Result; -use cait_sith::FullSignature; use integration_tests::{actions, cluster}; use k256::ecdsa::SigningKey; use k256::elliptic_curve::ops::Reduce; @@ -19,6 +18,7 @@ use sha3::{Digest, Keccak256}; use solana_sdk::signer::Signer as _; use std::time::Duration; use test_log::test; +use threshold_signatures::ecdsa::Signature as FullSignature; use tokio::time::sleep; const FUNDING_TOP_UP_WEI: u128 = 200_000_000_000_000; // 0.0002 ETH @@ -247,7 +247,7 @@ fn append_u256(stream: &mut RlpStream, value: &U256) { } } -fn signature_components(signature: &FullSignature) -> (U256, U256) { +fn signature_components(signature: &FullSignature) -> (U256, U256) { let r_scalar = actions::x_coordinate::(&signature.big_r); let r_bytes = r_scalar.to_bytes(); let r = U256::from_be_slice(r_bytes.as_slice()); diff --git a/integration-tests/tests/cases/mpc.rs b/integration-tests/tests/cases/mpc.rs index 2250d2070..42a15c279 100644 --- a/integration-tests/tests/cases/mpc.rs +++ b/integration-tests/tests/cases/mpc.rs @@ -25,7 +25,7 @@ const PRESIGNATURES_FILE: &str = "tmp/presignatures.json"; async fn test_basic_generate_keys() { let network = MpcFixtureBuilder::new(5, 4).build().await; - let result = tokio::time::timeout(Duration::from_secs(10), async { + let result = tokio::time::timeout(Duration::from_secs(30), async { let mut contract_state_watcher = network.shared_contract_state.subscribe(); contract_state_watcher .wait_for(|protocol_state| { diff --git a/integration-tests/tests/cases/store.rs b/integration-tests/tests/cases/store.rs index b1fcb8d36..b5e98e40e 100644 --- a/integration-tests/tests/cases/store.rs +++ b/integration-tests/tests/cases/store.rs @@ -1,6 +1,3 @@ -use cait_sith::protocol::Participant; -use cait_sith::triples::{TriplePub, TripleShare}; -use cait_sith::PresignOutput; use elliptic_curve::CurveArithmetic; use integration_tests::cluster::spawner::ClusterSpawner; use integration_tests::containers; @@ -12,6 +9,9 @@ use mpc_node::protocol::MessageChannel; use mpc_node::storage::triple_storage::TriplePair; use mpc_node::types::SecretKeyShare; use test_log::test; +use threshold_signatures::ecdsa::ot_based_ecdsa::triples::{TriplePub, TripleShare}; +use threshold_signatures::ecdsa::ot_based_ecdsa::PresignOutput; +use threshold_signatures::participants::Participant; #[test(tokio::test)] async fn test_triple_persistence() -> anyhow::Result<()> { diff --git a/integration-tests/tests/cases/sync.rs b/integration-tests/tests/cases/sync.rs index cd26427c5..192852c98 100644 --- a/integration-tests/tests/cases/sync.rs +++ b/integration-tests/tests/cases/sync.rs @@ -1,11 +1,11 @@ use std::time::Duration; -use cait_sith::protocol::Participant; -use cait_sith::triples::{TriplePub, TripleShare}; -use cait_sith::PresignOutput; use elliptic_curve::CurveArithmetic; use integration_tests::cluster; use k256::Secp256k1; +use threshold_signatures::ecdsa::ot_based_ecdsa::triples::{TriplePub, TripleShare}; +use threshold_signatures::ecdsa::ot_based_ecdsa::PresignOutput; +use threshold_signatures::participants::Participant; use integration_tests::cluster::spawner::ClusterSpawner; use mpc_node::mesh::Mesh; From daced653aa06eb08badc038a002e3151ffe1ca08 Mon Sep 17 00:00:00 2001 From: Phuong N Date: Tue, 13 Jan 2026 22:40:38 +0000 Subject: [PATCH 2/2] Fix merge issues --- .../node/src/storage/protocol_storage.rs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/chain-signatures/node/src/storage/protocol_storage.rs b/chain-signatures/node/src/storage/protocol_storage.rs index 9d8c880c1..2b78a33a1 100644 --- a/chain-signatures/node/src/storage/protocol_storage.rs +++ b/chain-signatures/node/src/storage/protocol_storage.rs @@ -583,25 +583,11 @@ impl ProtocolStorage { local mine_key = KEYS[2] local artifact_id = ARGV[1] local artifact = ARGV[2] - -<<<<<<< HEAD -======= - -- Remove from used set - redis.call("HDEL", used_key, artifact_id) - ->>>>>>> a5e1ae5a (Add tss crate) -- Add back to artifact hash map redis.call("HSET", artifact_key, artifact_id, artifact) -- Add back to mine set redis.call("SADD", mine_key, artifact_id) - -<<<<<<< HEAD -======= - -- Ensure it is still reserved - redis.call("SADD", reserved_key, artifact_id) - ->>>>>>> a5e1ae5a (Add tss crate) return 1 "#;