From 0ae4ca303fcc7c50d6348f969410ee7ad721a39f Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Mon, 25 Nov 2024 13:57:38 +0100 Subject: [PATCH 01/19] Update `hd-wallet` to v0.6 Signed-off-by: Denis Varlakov --- Cargo.lock | 5 ++-- Cargo.toml | 6 +++- cggmp21/Cargo.toml | 8 ++++-- cggmp21/src/signing.rs | 13 +++++---- tests/Cargo.toml | 2 +- tests/tests/it/pipeline.rs | 31 ++++++++++++-------- tests/tests/it/signing.rs | 59 +++++++++++++++++++++++++------------- 7 files changed, 79 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7e2b161..7ae9076 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1085,9 +1085,8 @@ checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" [[package]] name = "hd-wallet" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4111172d55e2217d689df0fc9038cbd65826dd842ac5df9a04363accfa0769a3" +version = "0.6.0" +source = "git+https://github.com/LFDT-Lockness/hd-wallet?branch=dt#158b65ce54ed6d0d031a9414890b4a9170dd4f11" dependencies = [ "generic-array", "generic-ec", diff --git a/Cargo.toml b/Cargo.toml index 381648c..1135cd6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,6 +41,10 @@ serde_with = { version = "2", default-features = false } serde_json = "1" hex = { version = "0.4", default-features = false } -hd-wallet = { version = "0.5", default-features = false } +hd-wallet = { version = "0.6", default-features = false } generic-tests = "0.1" + +[patch.crates-io.hd-wallet] +git = "https://github.com/LFDT-Lockness/hd-wallet" +branch = "dt" diff --git a/cggmp21/Cargo.toml b/cggmp21/Cargo.toml index deed531..19eff1c 100644 --- a/cggmp21/Cargo.toml +++ b/cggmp21/Cargo.toml @@ -47,10 +47,12 @@ generic-tests = { workspace = true } [features] all-curves = ["curve-secp256k1", "curve-secp256r1", "curve-stark"] -curve-secp256k1 = ["generic-ec/curve-secp256k1"] -curve-secp256r1 = ["generic-ec/curve-secp256r1"] -curve-stark = ["generic-ec/curve-stark"] +curve-secp256k1 = ["generic-ec/curve-secp256k1", "hd-wallet?/curve-secp256k1"] +curve-secp256r1 = ["generic-ec/curve-secp256r1", "hd-wallet?/curve-secp256r1"] +curve-stark = ["generic-ec/curve-stark", "hd-wallet?/curve-stark"] hd-wallet = ["dep:hd-wallet", "cggmp21-keygen/hd-wallet"] +hd-slip10 = ["hd-wallet/slip10"] +hd-stark = ["hd-wallet/stark"] spof = ["key-share/spof"] state-machine = ["cggmp21-keygen/state-machine"] diff --git a/cggmp21/src/signing.rs b/cggmp21/src/signing.rs index 800a77c..e2d0a8a 100644 --- a/cggmp21/src/signing.rs +++ b/cggmp21/src/signing.rs @@ -350,9 +350,10 @@ where /// ``` /// /// ## Derivation algorithm - /// This method uses [`hd_wallet::Slip10Like`] derivation algorithm. If you need to use another one, see + /// This method uses [`hd_wallet::Slip10`] derivation algorithm, which can only be used with secp256k1 + /// and secp256r1 curves. If you need to use another one, see /// [`set_derivation_path_with_algo`](Self::set_derivation_path_with_algo) - #[cfg(feature = "hd-wallet")] + #[cfg(all(feature = "hd-wallet", feature = "hd-slip10"))] pub fn set_derivation_path( self, path: impl IntoIterator, @@ -361,9 +362,10 @@ where crate::key_share::HdError<>::Error>, > where + hd_wallet::Slip10: hd_wallet::HdWallet, hd_wallet::NonHardenedIndex: TryFrom, { - self.set_derivation_path_with_algo::(path) + self.set_derivation_path_with_algo::(path) } /// Specifies HD derivation path, using HD derivation algorithm [`hd_wallet::HdWallet`] @@ -1292,16 +1294,17 @@ impl Presignature { /// /// For HD derivation, uses [`hd_wallet::Slip10Like`] algorithm. If you need to /// use another derivation algorithm, see [`set_derivation_path_with_algo`](Self::set_derivation_path_with_algo) - #[cfg(feature = "hd-wallet")] + #[cfg(all(feature = "hd-wallet", feature = "hd-slip10"))] pub fn set_derivation_path( self, epub: hd_wallet::ExtendedPublicKey, derivation_path: impl IntoIterator, ) -> Result>::Error> where + hd_wallet::Slip10: hd_wallet::HdWallet, hd_wallet::NonHardenedIndex: TryFrom, { - self.set_derivation_path_with_algo::(epub, derivation_path) + self.set_derivation_path_with_algo::(epub, derivation_path) } /// Specifies HD derivation path diff --git a/tests/Cargo.toml b/tests/Cargo.toml index eee6ea0..c1768d2 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -45,7 +45,7 @@ generic-tests = "0.1" test-case = "3" [features] -hd-wallet = ["cggmp21/hd-wallet"] +hd-wallet = ["cggmp21/hd-wallet", "cggmp21/hd-slip10", "cggmp21/hd-stark"] [[bin]] name = "precompute_shares" diff --git a/tests/tests/it/pipeline.rs b/tests/tests/it/pipeline.rs index 454f830..12af57c 100644 --- a/tests/tests/it/pipeline.rs +++ b/tests/tests/it/pipeline.rs @@ -17,14 +17,17 @@ mod generic { #[test_case::case(3, 5, false; "t3n5")] #[cfg_attr(feature = "hd-wallet", test_case::case(3, 5, true; "t3n5-hd"))] #[tokio::test] - async fn full_pipeline_works(t: u16, n: u16, hd_enabled: bool) - where + async fn full_pipeline_works>( + t: u16, + n: u16, + hd_enabled: bool, + ) where Point: generic_ec::coords::HasAffineX, { let mut rng = DevRng::new(); let incomplete_shares = run_keygen(t, n, hd_enabled, &mut rng).await; let shares = run_aux_gen(incomplete_shares, &mut rng).await; - run_signing(&shares, hd_enabled, &mut rng).await; + run_signing::(&shares, hd_enabled, &mut rng).await; } async fn run_keygen( @@ -104,10 +107,14 @@ mod generic { .collect() } - async fn run_signing(shares: &[KeyShare], random_derivation_path: bool, rng: &mut DevRng) - where + async fn run_signing( + shares: &[KeyShare], + random_derivation_path: bool, + rng: &mut DevRng, + ) where E: Curve, Point: generic_ec::coords::HasAffineX, + Hd: cggmp21::hd_wallet::HdWallet, { #[cfg(not(feature = "hd-wallet"))] assert!(!random_derivation_path); @@ -152,7 +159,9 @@ mod generic { #[cfg(feature = "hd-wallet")] let signing = if let Some(derivation_path) = derivation_path { - signing.set_derivation_path(derivation_path).unwrap() + signing + .set_derivation_path_with_algo::(derivation_path) + .unwrap() } else { signing }; @@ -169,9 +178,7 @@ mod generic { let public_key = if let Some(path) = &derivation_path { generic_ec::NonZero::from_point( shares[0] - .derive_child_public_key::( - path.iter().cloned(), - ) + .derive_child_public_key::(path.iter().cloned()) .unwrap() .public_key, ) @@ -189,10 +196,10 @@ mod generic { assert!(signatures.iter().all(|s_i| signatures[0] == *s_i)); } - #[instantiate_tests()] + #[instantiate_tests()] mod secp256r1 {} - #[instantiate_tests()] + #[instantiate_tests()] mod secp256k1 {} - #[instantiate_tests()] + #[instantiate_tests()] mod stark {} } diff --git a/tests/tests/it/signing.rs b/tests/tests/it/signing.rs index 8b06d2f..669f0bb 100644 --- a/tests/tests/it/signing.rs +++ b/tests/tests/it/signing.rs @@ -24,7 +24,7 @@ mod generic { #[cfg_attr(feature = "hd-wallet", test_case::case(Some(2), 3, false, true; "t2n3-hd"))] #[cfg_attr(feature = "hd-wallet", test_case::case(Some(3), 3, false, true; "t3n3-hd"))] #[tokio::test] - async fn signing_works( + async fn signing_works, V>( t: Option, n: u16, reliable_broadcast: bool, @@ -80,7 +80,9 @@ mod generic { #[cfg(feature = "hd-wallet")] let signing = if let Some(derivation_path) = derivation_path { - signing.set_derivation_path(derivation_path).unwrap() + signing + .set_derivation_path_with_algo::(derivation_path) + .unwrap() } else { signing }; @@ -97,9 +99,7 @@ mod generic { let public_key = if let Some(path) = &derivation_path { generic_ec::NonZero::from_point( shares[0] - .derive_child_public_key::( - path.iter().cloned(), - ) + .derive_child_public_key::(path.iter().cloned()) .unwrap() .public_key, ) @@ -123,8 +123,11 @@ mod generic { #[test_case::case(Some(3), 5, false; "t3n5")] #[cfg_attr(feature = "hd-wallet", test_case::case(Some(3), 5, true; "t3n5-hd"))] #[tokio::test] - async fn signing_with_presigs(t: Option, n: u16, hd_wallet: bool) - where + async fn signing_with_presigs, V>( + t: Option, + n: u16, + hd_wallet: bool, + ) where Point: HasAffineX, V: ExternalVerifier, { @@ -187,7 +190,10 @@ mod generic { let presig = if let Some(derivation_path) = &derivation_path { let epub = shares[0].extended_public_key().expect("not hd wallet"); presig - .set_derivation_path(epub, derivation_path.iter().copied()) + .set_derivation_path_with_algo::( + epub, + derivation_path.iter().copied(), + ) .unwrap() } else { presig @@ -203,9 +209,7 @@ mod generic { let public_key = if let Some(path) = &derivation_path { generic_ec::NonZero::from_point( shares[0] - .derive_child_public_key::( - path.iter().cloned(), - ) + .derive_child_public_key::(path.iter().cloned()) .unwrap() .public_key, ) @@ -228,8 +232,11 @@ mod generic { #[test_case::case(Some(3), 5, false; "t3n5")] #[cfg_attr(feature = "hd-wallet", test_case::case(None, 3, true; "n3-hd"))] #[cfg_attr(feature = "hd-wallet", test_case::case(Some(3), 5, true; "t3n5-hd"))] - fn signing_sync(t: Option, n: u16, hd_wallet: bool) - where + fn signing_sync, V>( + t: Option, + n: u16, + hd_wallet: bool, + ) where Point: HasAffineX, V: ExternalVerifier, { @@ -276,7 +283,9 @@ mod generic { #[cfg(feature = "hd-wallet")] let signing = if let Some(derivation_path) = derivation_path.clone() { - signing.set_derivation_path(derivation_path).unwrap() + signing + .set_derivation_path_with_algo::(derivation_path) + .unwrap() } else { signing }; @@ -296,9 +305,7 @@ mod generic { let public_key = if let Some(path) = &derivation_path { generic_ec::NonZero::from_point( shares[0] - .derive_child_public_key::( - path.iter().cloned(), - ) + .derive_child_public_key::(path.iter().cloned()) .unwrap() .public_key, ) @@ -319,10 +326,22 @@ mod generic { .expect("external verification failed") } - #[instantiate_tests()] + #[instantiate_tests(< + cggmp21::supported_curves::Secp256k1, + cggmp21::hd_wallet::Slip10, + cggmp21_tests::external_verifier::blockchains::Bitcoin + >)] mod secp256k1 {} - #[instantiate_tests()] + #[instantiate_tests(< + cggmp21::supported_curves::Secp256r1, + cggmp21::hd_wallet::Slip10, + cggmp21_tests::external_verifier::Noop + >)] mod secp256r1 {} - #[instantiate_tests()] + #[instantiate_tests(< + cggmp21::supported_curves::Stark, + cggmp21::hd_wallet::Stark, + cggmp21_tests::external_verifier::blockchains::StarkNet + >)] mod stark {} } From 93a17ca690b6b72da40f2bf961defc2d525694a8 Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Mon, 25 Nov 2024 14:01:04 +0100 Subject: [PATCH 02/19] Bump versions & update changelogs Signed-off-by: Denis Varlakov --- Cargo.lock | 6 +++--- Cargo.toml | 6 +++--- cggmp21-keygen/CHANGELOG.md | 5 +++++ cggmp21-keygen/Cargo.toml | 2 +- cggmp21/CHANGELOG.md | 5 +++++ cggmp21/Cargo.toml | 2 +- key-share/CHANGELOG.md | 5 +++++ key-share/Cargo.toml | 2 +- 8 files changed, 24 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7ae9076..d89b8e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -271,7 +271,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cggmp21" -version = "0.5.0" +version = "0.6.0" dependencies = [ "cggmp21-keygen", "digest", @@ -297,7 +297,7 @@ dependencies = [ [[package]] name = "cggmp21-keygen" -version = "0.4.0" +version = "0.5.0" dependencies = [ "digest", "displaydoc", @@ -1369,7 +1369,7 @@ dependencies = [ [[package]] name = "key-share" -version = "0.5.0" +version = "0.6.0" dependencies = [ "displaydoc", "generic-ec", diff --git a/Cargo.toml b/Cargo.toml index 1135cd6..f7e54d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,9 +11,9 @@ exclude = [ ] [workspace.dependencies] -cggmp21 = { version = "0.5", path = "cggmp21" } -cggmp21-keygen = { version = "0.4", path = "cggmp21-keygen" } -key-share = { version = "0.5", path = "key-share", default-features = false } +cggmp21 = { version = "0.6", path = "cggmp21" } +cggmp21-keygen = { version = "0.5", path = "cggmp21-keygen" } +key-share = { version = "0.6", path = "key-share", default-features = false } generic-ec = { version = "0.4.1", default-features = false } generic-ec-zkp = { version = "0.4.1", default-features = false } diff --git a/cggmp21-keygen/CHANGELOG.md b/cggmp21-keygen/CHANGELOG.md index a16b852..7760914 100644 --- a/cggmp21-keygen/CHANGELOG.md +++ b/cggmp21-keygen/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## v0.5.0 +* Update `hd-wallet` dep to v0.6 [#120] + +[#120]: https://github.com/LFDT-Lockness/cggmp21/pull/120 + ## v0.4.0 * BREAKING: use `hd-wallet` crate for HD support instead of `slip-10` [#115] * BREAKING: rename `hd-wallets` feature into `hd-wallet` [#115] diff --git a/cggmp21-keygen/Cargo.toml b/cggmp21-keygen/Cargo.toml index f6d6764..85b2b9e 100644 --- a/cggmp21-keygen/Cargo.toml +++ b/cggmp21-keygen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cggmp21-keygen" -version = "0.4.0" +version = "0.5.0" edition = "2021" license = "MIT OR Apache-2.0" description = "UC-secure DKG implementation based on CGGMP21 paper" diff --git a/cggmp21/CHANGELOG.md b/cggmp21/CHANGELOG.md index 5177c58..6ac24b9 100644 --- a/cggmp21/CHANGELOG.md +++ b/cggmp21/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## v0.6.0 +* Update `hd-wallet` dep to v0.6 [#120] + +[#120]: https://github.com/LFDT-Lockness/cggmp21/pull/120 + ## v0.5.0 * BREAKING: use `hd-wallet` crate for HD support instead of `slip-10` [#115] * BREAKING: rename `hd-wallets` feature into `hd-wallet` [#115] diff --git a/cggmp21/Cargo.toml b/cggmp21/Cargo.toml index 19eff1c..016bbd1 100644 --- a/cggmp21/Cargo.toml +++ b/cggmp21/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cggmp21" -version = "0.5.0" +version = "0.6.0" edition = "2021" license = "MIT OR Apache-2.0" description = "TSS ECDSA implementation based on CGGMP21 paper" diff --git a/key-share/CHANGELOG.md b/key-share/CHANGELOG.md index 05d4fc4..f3c77e4 100644 --- a/key-share/CHANGELOG.md +++ b/key-share/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## v0.6.0 +* Update `hd-wallet` dep to v0.6 [#120] + +[#120]: https://github.com/LFDT-Lockness/cggmp21/pull/120 + ## v0.5.0 * BREAKING: use `hd-wallet` crate for HD support instead of `slip-10` [#115] * BREAKING: rename `hd-wallets` feature into `hd-wallet` [#115] diff --git a/key-share/Cargo.toml b/key-share/Cargo.toml index 8baa41c..e57be9f 100644 --- a/key-share/Cargo.toml +++ b/key-share/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "key-share" -version = "0.5.0" +version = "0.6.0" edition = "2021" license = "MIT OR Apache-2.0" description = "Key share of any Threshold Signature Scheme (TSS)" From 7dade25aa9c75f0b9341f79eb05d4ebc5c78cf1d Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Mon, 25 Nov 2024 14:12:21 +0100 Subject: [PATCH 03/19] Fix tests compilation when hd is opted out Signed-off-by: Denis Varlakov --- tests/src/lib.rs | 22 +++++++++++++++++++++ tests/tests/it/pipeline.rs | 30 ++++++++++++---------------- tests/tests/it/signing.rs | 40 ++++++++++++++------------------------ 3 files changed, 49 insertions(+), 43 deletions(-) diff --git a/tests/src/lib.rs b/tests/src/lib.rs index faf02ba..f012a32 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -173,3 +173,25 @@ pub fn random_derivation_path(rng: &mut impl rand::RngCore) -> Vec { .take(len) .collect::>() } + +/// Parameters per each curve that are needed in tests +pub trait CurveParams: Curve { + /// Which HD derivation algorithm to use with that curve + #[cfg(feature = "hd-wallet")] + type HdAlgo: cggmp21::hd_wallet::HdWallet; +} + +impl CurveParams for cggmp21::supported_curves::Secp256k1 { + #[cfg(feature = "hd-wallet")] + type HdAlgo = cggmp21::hd_wallet::Slip10; +} + +impl CurveParams for cggmp21::supported_curves::Secp256r1 { + #[cfg(feature = "hd-wallet")] + type HdAlgo = cggmp21::hd_wallet::Slip10; +} + +impl CurveParams for cggmp21::supported_curves::Stark { + #[cfg(feature = "hd-wallet")] + type HdAlgo = cggmp21::hd_wallet::Stark; +} diff --git a/tests/tests/it/pipeline.rs b/tests/tests/it/pipeline.rs index 12af57c..a50c708 100644 --- a/tests/tests/it/pipeline.rs +++ b/tests/tests/it/pipeline.rs @@ -17,17 +17,15 @@ mod generic { #[test_case::case(3, 5, false; "t3n5")] #[cfg_attr(feature = "hd-wallet", test_case::case(3, 5, true; "t3n5-hd"))] #[tokio::test] - async fn full_pipeline_works>( - t: u16, - n: u16, - hd_enabled: bool, - ) where + async fn full_pipeline_works(t: u16, n: u16, hd_enabled: bool) + where + E: Curve + cggmp21_tests::CurveParams, Point: generic_ec::coords::HasAffineX, { let mut rng = DevRng::new(); let incomplete_shares = run_keygen(t, n, hd_enabled, &mut rng).await; let shares = run_aux_gen(incomplete_shares, &mut rng).await; - run_signing::(&shares, hd_enabled, &mut rng).await; + run_signing(&shares, hd_enabled, &mut rng).await; } async fn run_keygen( @@ -107,14 +105,10 @@ mod generic { .collect() } - async fn run_signing( - shares: &[KeyShare], - random_derivation_path: bool, - rng: &mut DevRng, - ) where - E: Curve, + async fn run_signing(shares: &[KeyShare], random_derivation_path: bool, rng: &mut DevRng) + where + E: Curve + cggmp21_tests::CurveParams, Point: generic_ec::coords::HasAffineX, - Hd: cggmp21::hd_wallet::HdWallet, { #[cfg(not(feature = "hd-wallet"))] assert!(!random_derivation_path); @@ -160,7 +154,7 @@ mod generic { #[cfg(feature = "hd-wallet")] let signing = if let Some(derivation_path) = derivation_path { signing - .set_derivation_path_with_algo::(derivation_path) + .set_derivation_path_with_algo::(derivation_path) .unwrap() } else { signing @@ -178,7 +172,7 @@ mod generic { let public_key = if let Some(path) = &derivation_path { generic_ec::NonZero::from_point( shares[0] - .derive_child_public_key::(path.iter().cloned()) + .derive_child_public_key::(path.iter().cloned()) .unwrap() .public_key, ) @@ -196,10 +190,10 @@ mod generic { assert!(signatures.iter().all(|s_i| signatures[0] == *s_i)); } - #[instantiate_tests()] + #[instantiate_tests()] mod secp256r1 {} - #[instantiate_tests()] + #[instantiate_tests()] mod secp256k1 {} - #[instantiate_tests()] + #[instantiate_tests()] mod stark {} } diff --git a/tests/tests/it/signing.rs b/tests/tests/it/signing.rs index 669f0bb..1236add 100644 --- a/tests/tests/it/signing.rs +++ b/tests/tests/it/signing.rs @@ -24,12 +24,9 @@ mod generic { #[cfg_attr(feature = "hd-wallet", test_case::case(Some(2), 3, false, true; "t2n3-hd"))] #[cfg_attr(feature = "hd-wallet", test_case::case(Some(3), 3, false, true; "t3n3-hd"))] #[tokio::test] - async fn signing_works, V>( - t: Option, - n: u16, - reliable_broadcast: bool, - hd_wallet: bool, - ) where + async fn signing_works(t: Option, n: u16, reliable_broadcast: bool, hd_wallet: bool) + where + E: Curve + cggmp21_tests::CurveParams, Point: HasAffineX, V: ExternalVerifier, { @@ -81,7 +78,7 @@ mod generic { #[cfg(feature = "hd-wallet")] let signing = if let Some(derivation_path) = derivation_path { signing - .set_derivation_path_with_algo::(derivation_path) + .set_derivation_path_with_algo::(derivation_path) .unwrap() } else { signing @@ -99,7 +96,7 @@ mod generic { let public_key = if let Some(path) = &derivation_path { generic_ec::NonZero::from_point( shares[0] - .derive_child_public_key::(path.iter().cloned()) + .derive_child_public_key::(path.iter().cloned()) .unwrap() .public_key, ) @@ -123,11 +120,9 @@ mod generic { #[test_case::case(Some(3), 5, false; "t3n5")] #[cfg_attr(feature = "hd-wallet", test_case::case(Some(3), 5, true; "t3n5-hd"))] #[tokio::test] - async fn signing_with_presigs, V>( - t: Option, - n: u16, - hd_wallet: bool, - ) where + async fn signing_with_presigs(t: Option, n: u16, hd_wallet: bool) + where + E: Curve + cggmp21_tests::CurveParams, Point: HasAffineX, V: ExternalVerifier, { @@ -190,7 +185,7 @@ mod generic { let presig = if let Some(derivation_path) = &derivation_path { let epub = shares[0].extended_public_key().expect("not hd wallet"); presig - .set_derivation_path_with_algo::( + .set_derivation_path_with_algo::( epub, derivation_path.iter().copied(), ) @@ -209,7 +204,7 @@ mod generic { let public_key = if let Some(path) = &derivation_path { generic_ec::NonZero::from_point( shares[0] - .derive_child_public_key::(path.iter().cloned()) + .derive_child_public_key::(path.iter().cloned()) .unwrap() .public_key, ) @@ -232,11 +227,9 @@ mod generic { #[test_case::case(Some(3), 5, false; "t3n5")] #[cfg_attr(feature = "hd-wallet", test_case::case(None, 3, true; "n3-hd"))] #[cfg_attr(feature = "hd-wallet", test_case::case(Some(3), 5, true; "t3n5-hd"))] - fn signing_sync, V>( - t: Option, - n: u16, - hd_wallet: bool, - ) where + fn signing_sync(t: Option, n: u16, hd_wallet: bool) + where + E: Curve + cggmp21_tests::CurveParams, Point: HasAffineX, V: ExternalVerifier, { @@ -284,7 +277,7 @@ mod generic { #[cfg(feature = "hd-wallet")] let signing = if let Some(derivation_path) = derivation_path.clone() { signing - .set_derivation_path_with_algo::(derivation_path) + .set_derivation_path_with_algo::(derivation_path) .unwrap() } else { signing @@ -305,7 +298,7 @@ mod generic { let public_key = if let Some(path) = &derivation_path { generic_ec::NonZero::from_point( shares[0] - .derive_child_public_key::(path.iter().cloned()) + .derive_child_public_key::(path.iter().cloned()) .unwrap() .public_key, ) @@ -328,19 +321,16 @@ mod generic { #[instantiate_tests(< cggmp21::supported_curves::Secp256k1, - cggmp21::hd_wallet::Slip10, cggmp21_tests::external_verifier::blockchains::Bitcoin >)] mod secp256k1 {} #[instantiate_tests(< cggmp21::supported_curves::Secp256r1, - cggmp21::hd_wallet::Slip10, cggmp21_tests::external_verifier::Noop >)] mod secp256r1 {} #[instantiate_tests(< cggmp21::supported_curves::Stark, - cggmp21::hd_wallet::Stark, cggmp21_tests::external_verifier::blockchains::StarkNet >)] mod stark {} From 4a96936d3d8db17fc78461e5c15484724f5fd4a7 Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Mon, 25 Nov 2024 14:15:30 +0100 Subject: [PATCH 04/19] Fix wasm/nostd compilation Signed-off-by: Denis Varlakov --- wasm/no_std/Cargo.lock | 39 ++++++++++++--------------------------- wasm/no_std/Cargo.toml | 3 +++ 2 files changed, 15 insertions(+), 27 deletions(-) diff --git a/wasm/no_std/Cargo.lock b/wasm/no_std/Cargo.lock index a7f81aa..05f7039 100644 --- a/wasm/no_std/Cargo.lock +++ b/wasm/no_std/Cargo.lock @@ -31,12 +31,13 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cggmp21-keygen" -version = "0.3.0" +version = "0.5.0" dependencies = [ "digest", "displaydoc", "generic-ec", "generic-ec-zkp", + "hd-wallet", "hex", "key-share", "rand_core", @@ -44,7 +45,6 @@ dependencies = [ "serde", "serde_with", "sha2", - "slip-10", "udigest", ] @@ -163,7 +163,6 @@ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", "crypto-common", - "subtle", ] [[package]] @@ -304,21 +303,20 @@ dependencies = [ ] [[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +name = "hd-wallet" +version = "0.6.0" +source = "git+https://github.com/LFDT-Lockness/hd-wallet?branch=dt#158b65ce54ed6d0d031a9414890b4a9170dd4f11" dependencies = [ - "serde", + "generic-ec", ] [[package]] -name = "hmac" -version = "0.12.1" +name = "hex" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" dependencies = [ - "digest", + "serde", ] [[package]] @@ -335,16 +333,16 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "key-share" -version = "0.4.1" +version = "0.6.0" dependencies = [ "displaydoc", "generic-ec", "generic-ec-zkp", + "hd-wallet", "hex", "rand_core", "serde", "serde_with", - "slip-10", "udigest", ] @@ -580,19 +578,6 @@ dependencies = [ "digest", ] -[[package]] -name = "slip-10" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10c50b6de806a216bce1d98e9107e03f60b54abcfbe6be3935a528ab57c19f6a" -dependencies = [ - "generic-array", - "generic-ec", - "hmac", - "sha2", - "subtle", -] - [[package]] name = "strsim" version = "0.11.1" diff --git a/wasm/no_std/Cargo.toml b/wasm/no_std/Cargo.toml index 01d1a5f..346d53c 100644 --- a/wasm/no_std/Cargo.toml +++ b/wasm/no_std/Cargo.toml @@ -15,3 +15,6 @@ path = "../../cggmp21-keygen" default-features = false features = ["hd-wallet", "state-machine"] +[patch.crates-io.hd-wallet] +git = "https://github.com/LFDT-Lockness/hd-wallet" +branch = "dt" From c5f311f9ccf6dbb5d1eb178a0f2bc2068f98da33 Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Mon, 25 Nov 2024 14:18:05 +0100 Subject: [PATCH 05/19] clippy fix Signed-off-by: Denis Varlakov --- tests/tests/it/signing.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tests/it/signing.rs b/tests/tests/it/signing.rs index 1236add..a4e589b 100644 --- a/tests/tests/it/signing.rs +++ b/tests/tests/it/signing.rs @@ -227,7 +227,7 @@ mod generic { #[test_case::case(Some(3), 5, false; "t3n5")] #[cfg_attr(feature = "hd-wallet", test_case::case(None, 3, true; "n3-hd"))] #[cfg_attr(feature = "hd-wallet", test_case::case(Some(3), 5, true; "t3n5-hd"))] - fn signing_sync(t: Option, n: u16, hd_wallet: bool) + fn signing_sync(t: Option, n: u16, hd_wallet: bool) where E: Curve + cggmp21_tests::CurveParams, Point: HasAffineX, From cafea585a4da8b41b40f2b1424dc56ac69b7a57d Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Mon, 25 Nov 2024 14:21:00 +0100 Subject: [PATCH 06/19] Fix docs and docs workflow Signed-off-by: Denis Varlakov --- .github/workflows/rust.yml | 2 +- cggmp21/src/signing.rs | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index a2495a8..54adecf 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -102,7 +102,7 @@ jobs: with: cache-on-failure: "true" - name: Check docs - run: RUSTDOCFLAGS="--cfg docsrs -D warnings" cargo +nightly doc --workspace --all-features --no-deps + run: RUSTDOCFLAGS="-D warnings" cargo doc --workspace --all-features --no-deps bench: runs-on: ubuntu-latest diff --git a/cggmp21/src/signing.rs b/cggmp21/src/signing.rs index e2d0a8a..a8cce16 100644 --- a/cggmp21/src/signing.rs +++ b/cggmp21/src/signing.rs @@ -1292,8 +1292,10 @@ impl Presignature { /// assoicated with the key share that was used to generate presignature. /// Using wrong `epub` will simply lead to invalid signature. /// - /// For HD derivation, uses [`hd_wallet::Slip10Like`] algorithm. If you need to - /// use another derivation algorithm, see [`set_derivation_path_with_algo`](Self::set_derivation_path_with_algo) + /// ## Derivation algorithm + /// This method uses [`hd_wallet::Slip10`] derivation algorithm, which can only be used with secp256k1 + /// and secp256r1 curves. If you need to use another one, see + /// [`set_derivation_path_with_algo`](Self::set_derivation_path_with_algo) #[cfg(all(feature = "hd-wallet", feature = "hd-slip10"))] pub fn set_derivation_path( self, From d7f5f600dfd5cb198baefe61e5fd98ac8822199a Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Mon, 25 Nov 2024 18:09:24 +0100 Subject: [PATCH 07/19] Try using custom test_suite! macro Signed-off-by: Denis Varlakov --- tests/src/lib.rs | 187 +++++++++++ tests/tests/it/signing.rs | 678 ++++++++++++++++++++------------------ 2 files changed, 549 insertions(+), 316 deletions(-) diff --git a/tests/src/lib.rs b/tests/src/lib.rs index f012a32..9a3ffdd 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -195,3 +195,190 @@ impl CurveParams for cggmp21::supported_curves::Stark { #[cfg(feature = "hd-wallet")] type HdAlgo = cggmp21::hd_wallet::Stark; } + +#[macro_export] +macro_rules! test_suite { + ( + async_test = $test:ident, + generics = [$($gmod:ident = <$($generic:path),*>),+$(,)?], + suites = [$($suites:tt)*] + $(,)? + ) => { + mod $test { + use super::$test; + $crate::test_suite_traverse! { + async_test = $test, + generics_list = [$($gmod = <$($generic),+>),+], + suites = [$($suites)*] + } + } + }; + + ( + test = $test:ident, + generics = [$($gmod:ident = <$($generic:path),*>),+$(,)?], + suites = [$($suites:tt)*] + $(,)? + ) => { + mod $test { + use super::$test; + $crate::test_suite_traverse! { + test = $test, + generics_list = [$($gmod = <$($generic),+>),+], + suites = [$($suites)*] + } + } + }; +} + +#[macro_export] +#[doc(hidden)] +macro_rules! test_suite_traverse { + // --- Async Test Function + ( + async_test = $test:ident, + // we traverse over `generics_list` + generics_list = [$gmod:ident = <$($generic:path),*>$(, $($generics_rest:tt)*)?], + suites = [$($suites:tt)*] + ) => { + mod $gmod { + use super::$test; + $crate::test_suite_traverse! { + async_test = $test, + generics = <$($generic),+>, + suites = [$($suites)*] + } + $crate::test_suite_traverse! { + async_test = $test, + generics_list = [$($($generics_rest)*)?], + suites = [$($suites)*] + } + } + }; + ( + async_test = $test:ident, + // generics_list is empty - nothing to traverse + generics_list = [], + suites = [$($suites:tt)*] + ) => {}; + + ( + async_test = $test:ident, + generics = <$($generic:path),*>, + // we traverse suites + suites = [$suite_name:ident($($args:tt)*)$(, $($rest:tt)*)?] + ) => { + #[tokio::test] + async fn $suite_name() { + $test::<$($generic),+>($($args)*).await + } + + $crate::test_suite_traverse! { + async_test = $test, + generics = <$($generic),*>, + suites = [$($($rest)*)?] + } + }; + ( + async_test = $test:ident, + generics = <$($generic:path),*>, + // we traverse suites, the next suite has extra attrs + suites = [ + $(#[$attr:meta])+ + $suite_name:ident($($args:tt)*) + $(, $($rest:tt)*)? + ] + ) => { + $(#[$attr])+ + #[tokio::test] + async fn $suite_name() { + $test::<$($generic),+>($($args)*).await + } + + $crate::test_suite_traverse! { + async_test = $test, + generics = <$($generic),*>, + suites = [$($($rest)*)?] + } + }; + ( + async_test = $test:ident, + generics = <$($generic:path),*>, + // suites list is empty - nothing to traverse + suites = [] + ) => {}; + + // --- Sync Test Function + ( + test = $test:ident, + // we traverse over `generics_list` + generics_list = [$gmod:ident = <$($generic:path),*>$(, $($generics_rest:tt)*)?], + suites = [$($suites:tt)*] + ) => { + mod $gmod { + use super::$test; + $crate::test_suite_traverse! { + test = $test, + generics = <$($generic),+>, + suites = [$($suites)*] + } + $crate::test_suite_traverse! { + test = $test, + generics_list = [$($($generics_rest)*)?], + suites = [$($suites)*] + } + } + }; + ( + test = $test:ident, + // generics_list is empty - nothing to traverse + generics_list = [], + suites = [$($suites:tt)*] + ) => {}; + + ( + test = $test:ident, + generics = <$($generic:path),*>, + // we traverse suites + suites = [$suite_name:ident($($args:tt)*)$(, $($rest:tt)*)?] + ) => { + #[test] + fn $suite_name() { + $test::<$($generic),+>($($args)*) + } + + $crate::test_suite_traverse! { + test = $test, + generics = <$($generic),*>, + suites = [$($($rest)*)?] + } + }; + ( + test = $test:ident, + generics = <$($generic:path),*>, + // we traverse suites, the next suite has extra attrs + suites = [ + $(#[$attr:meta])+ + $suite_name:ident($($args:tt)*) + $(, $($rest:tt)*)? + ] + ) => { + $(#[$attr])+ + #[test] + fn $suite_name() { + $test::<$($generic),+>($($args)*) + } + + $crate::test_suite_traverse! { + test = $test, + generics = <$($generic),*>, + suites = [$($($rest)*)?] + } + }; + ( + test = $test:ident, + generics = <$($generic:path),*>, + // suites list is empty - nothing to traverse + suites = [] + ) => {}; +} diff --git a/tests/tests/it/signing.rs b/tests/tests/it/signing.rs index a4e589b..901d01e 100644 --- a/tests/tests/it/signing.rs +++ b/tests/tests/it/signing.rs @@ -1,337 +1,383 @@ -#[generic_tests::define(attrs(tokio::test, test_case::case, cfg_attr))] -mod generic { - use std::iter; - - use cggmp21_tests::external_verifier::ExternalVerifier; - use generic_ec::{coords::HasAffineX, Curve, Point}; - use rand::seq::SliceRandom; - use rand::{Rng, RngCore}; - use rand_dev::DevRng; - use round_based::simulation::{Simulation, SimulationSync}; - use sha2::Sha256; - - use cggmp21::key_share::AnyKeyShare; - use cggmp21::signing::{msg::Msg, DataToSign}; - use cggmp21::{security_level::SecurityLevel128, ExecutionId}; - - #[test_case::case(None, 2, false, false; "n2")] - #[test_case::case(None, 2, true, false; "n2-reliable")] - #[test_case::case(Some(2), 2, false, false; "t2n2")] - #[test_case::case(None, 3, false, false; "n3")] - #[test_case::case(Some(2), 3, false, false; "t2n3")] - #[test_case::case(Some(3), 3, false, false; "t3n3")] - #[cfg_attr(feature = "hd-wallet", test_case::case(None, 3, false, true; "n3-hd"))] - #[cfg_attr(feature = "hd-wallet", test_case::case(Some(2), 3, false, true; "t2n3-hd"))] - #[cfg_attr(feature = "hd-wallet", test_case::case(Some(3), 3, false, true; "t3n3-hd"))] - #[tokio::test] - async fn signing_works(t: Option, n: u16, reliable_broadcast: bool, hd_wallet: bool) - where - E: Curve + cggmp21_tests::CurveParams, - Point: HasAffineX, - V: ExternalVerifier, - { - #[cfg(not(feature = "hd-wallet"))] - assert!(!hd_wallet); - - let mut rng = DevRng::new(); - - let shares = cggmp21_tests::CACHED_SHARES - .get_shares::(t, n, hd_wallet) - .expect("retrieve cached shares"); - - let mut simulation = Simulation::>::new(); - - let eid: [u8; 32] = rng.gen(); - let eid = ExecutionId::new(&eid); - - let mut original_message_to_sign = [0u8; 100]; - rng.fill_bytes(&mut original_message_to_sign); - let message_to_sign = DataToSign::digest::(&original_message_to_sign); +use std::iter; + +use cggmp21_tests::external_verifier::ExternalVerifier; +use generic_ec::{coords::HasAffineX, Curve, Point}; +use rand::seq::SliceRandom; +use rand::{Rng, RngCore}; +use rand_dev::DevRng; +use round_based::simulation::{Simulation, SimulationSync}; +use sha2::Sha256; + +use cggmp21::key_share::AnyKeyShare; +use cggmp21::signing::{msg::Msg, DataToSign}; +use cggmp21::{security_level::SecurityLevel128, ExecutionId}; + +cggmp21_tests::test_suite! { + async_test = signing_works, + generics = [ + secp256k1 = < + cggmp21::supported_curves::Secp256k1, + cggmp21_tests::external_verifier::blockchains::Bitcoin + >, + secp256r1 = < + cggmp21::supported_curves::Secp256r1, + cggmp21_tests::external_verifier::Noop + >, + stark = < + cggmp21::supported_curves::Stark, + cggmp21_tests::external_verifier::blockchains::StarkNet + >, + ], + suites = [ + n2(None, 2, false, false), + n2_reliable(None, 2, true, false), + t2n2(Some(2), 2, false, false), + n3(None, 3, false, false), + t2n3(Some(2), 3, false, false), + t3n3(Some(3), 3, false, false), #[cfg(feature = "hd-wallet")] - let derivation_path = if hd_wallet { - Some(cggmp21_tests::random_derivation_path(&mut rng)) - } else { - None - }; - - // Choose `t` signers to perform signing - let t = shares[0].min_signers(); - let mut participants = (0..n).collect::>(); - participants.shuffle(&mut rng); - let participants = &participants[..usize::from(t)]; - println!("Signers: {participants:?}"); - let participants_shares = participants.iter().map(|i| &shares[usize::from(*i)]); - - let mut outputs = vec![]; - for (i, share) in (0..).zip(participants_shares) { - let party = simulation.add_party(); - let mut party_rng = rng.fork(); - - #[cfg(feature = "hd-wallet")] - let derivation_path = derivation_path.clone(); - - outputs.push(async move { - let signing = cggmp21::signing(eid, i, participants, share) - .enforce_reliable_broadcast(reliable_broadcast); + n3_hd(None, 3, false, true), + #[cfg(feature = "hd-wallet")] + t2n3_hd(Some(2), 3, false, true), + #[cfg(feature = "hd-wallet")] + t3n3_hd(Some(3), 3, false, true), + ] +} - #[cfg(feature = "hd-wallet")] - let signing = if let Some(derivation_path) = derivation_path { - signing - .set_derivation_path_with_algo::(derivation_path) - .unwrap() - } else { - signing - }; +async fn signing_works(t: Option, n: u16, reliable_broadcast: bool, hd_wallet: bool) +where + E: Curve + cggmp21_tests::CurveParams, + Point: HasAffineX, + V: ExternalVerifier, +{ + #[cfg(not(feature = "hd-wallet"))] + assert!(!hd_wallet); + + let mut rng = DevRng::new(); + + let shares = cggmp21_tests::CACHED_SHARES + .get_shares::(t, n, hd_wallet) + .expect("retrieve cached shares"); + + let mut simulation = Simulation::>::new(); + + let eid: [u8; 32] = rng.gen(); + let eid = ExecutionId::new(&eid); + + let mut original_message_to_sign = [0u8; 100]; + rng.fill_bytes(&mut original_message_to_sign); + let message_to_sign = DataToSign::digest::(&original_message_to_sign); + + #[cfg(feature = "hd-wallet")] + let derivation_path = if hd_wallet { + Some(cggmp21_tests::random_derivation_path(&mut rng)) + } else { + None + }; + + // Choose `t` signers to perform signing + let t = shares[0].min_signers(); + let mut participants = (0..n).collect::>(); + participants.shuffle(&mut rng); + let participants = &participants[..usize::from(t)]; + println!("Signers: {participants:?}"); + let participants_shares = participants.iter().map(|i| &shares[usize::from(*i)]); + + let mut outputs = vec![]; + for (i, share) in (0..).zip(participants_shares) { + let party = simulation.add_party(); + let mut party_rng = rng.fork(); - signing.sign(&mut party_rng, party, message_to_sign).await - }); - } + #[cfg(feature = "hd-wallet")] + let derivation_path = derivation_path.clone(); - let signatures = futures::future::try_join_all(outputs) - .await - .expect("signing failed"); + outputs.push(async move { + let signing = cggmp21::signing(eid, i, participants, share) + .enforce_reliable_broadcast(reliable_broadcast); - #[cfg(feature = "hd-wallet")] - let public_key = if let Some(path) = &derivation_path { - generic_ec::NonZero::from_point( - shares[0] - .derive_child_public_key::(path.iter().cloned()) + #[cfg(feature = "hd-wallet")] + let signing = if let Some(derivation_path) = derivation_path { + signing + .set_derivation_path_with_algo::(derivation_path) .unwrap() - .public_key, - ) - .unwrap() - } else { - shares[0].shared_public_key - }; - #[cfg(not(feature = "hd-wallet"))] - let public_key = shares[0].shared_public_key; - - signatures[0] - .verify(&public_key, &message_to_sign) - .expect("signature is not valid"); - - assert!(signatures.iter().all(|s_i| signatures[0] == *s_i)); - - V::verify(&public_key, &signatures[0], &original_message_to_sign) - .expect("external verification failed") + } else { + signing + }; + + signing.sign(&mut party_rng, party, message_to_sign).await + }); } - #[test_case::case(Some(3), 5, false; "t3n5")] - #[cfg_attr(feature = "hd-wallet", test_case::case(Some(3), 5, true; "t3n5-hd"))] - #[tokio::test] - async fn signing_with_presigs(t: Option, n: u16, hd_wallet: bool) - where - E: Curve + cggmp21_tests::CurveParams, - Point: HasAffineX, - V: ExternalVerifier, - { - #[cfg(not(feature = "hd-wallet"))] - assert!(!hd_wallet); - - let mut rng = DevRng::new(); - - let shares = cggmp21_tests::CACHED_SHARES - .get_shares::(t, n, hd_wallet) - .expect("retrieve cached shares"); - - let mut simulation = Simulation::>::new(); - - let eid: [u8; 32] = rng.gen(); - let eid = ExecutionId::new(&eid); - - // Choose `t` signers to generate presignature - let t = shares[0].min_signers(); - let mut participants = (0..n).collect::>(); - participants.shuffle(&mut rng); - let participants = &participants[..usize::from(t)]; - println!("Signers: {participants:?}"); - - let participants_shares = participants.iter().map(|i| &shares[usize::from(*i)]); - - let mut outputs = vec![]; - for (i, share) in (0..).zip(participants_shares) { - let party = simulation.add_party(); - let mut party_rng = rng.fork(); - - outputs.push(async move { - cggmp21::signing(eid, i, participants, share) - .generate_presignature(&mut party_rng, party) - .await - }); - } - - let presignatures = futures::future::try_join_all(outputs) - .await - .expect("signing failed"); - - // Now, that we have presignatures generated, we learn (generate) a messages to sign - // and the derivation path (if hd is enabled) - let mut original_message_to_sign = [0u8; 100]; - rng.fill_bytes(&mut original_message_to_sign); - let message_to_sign = DataToSign::digest::(&original_message_to_sign); + let signatures = futures::future::try_join_all(outputs) + .await + .expect("signing failed"); + + #[cfg(feature = "hd-wallet")] + let public_key = if let Some(path) = &derivation_path { + generic_ec::NonZero::from_point( + shares[0] + .derive_child_public_key::(path.iter().cloned()) + .unwrap() + .public_key, + ) + .unwrap() + } else { + shares[0].shared_public_key + }; + #[cfg(not(feature = "hd-wallet"))] + let public_key = shares[0].shared_public_key; + + signatures[0] + .verify(&public_key, &message_to_sign) + .expect("signature is not valid"); + + assert!(signatures.iter().all(|s_i| signatures[0] == *s_i)); + + V::verify(&public_key, &signatures[0], &original_message_to_sign) + .expect("external verification failed") +} +cggmp21_tests::test_suite! { + async_test = signing_with_presigs, + generics = [ + secp256k1 = < + cggmp21::supported_curves::Secp256k1, + cggmp21_tests::external_verifier::blockchains::Bitcoin + >, + secp256r1 = < + cggmp21::supported_curves::Secp256r1, + cggmp21_tests::external_verifier::Noop + >, + stark = < + cggmp21::supported_curves::Stark, + cggmp21_tests::external_verifier::blockchains::StarkNet + >, + ], + suites = [ + t3n5(Some(3), 5, false), #[cfg(feature = "hd-wallet")] - let derivation_path = if hd_wallet { - Some(cggmp21_tests::random_derivation_path(&mut rng)) - } else { - None - }; - - let partial_signatures = presignatures - .into_iter() - .map(|presig| { - #[cfg(feature = "hd-wallet")] - let presig = if let Some(derivation_path) = &derivation_path { - let epub = shares[0].extended_public_key().expect("not hd wallet"); - presig - .set_derivation_path_with_algo::( - epub, - derivation_path.iter().copied(), - ) - .unwrap() - } else { - presig - }; - presig.issue_partial_signature(message_to_sign) - }) - .collect::>(); - - let signature = cggmp21::PartialSignature::combine(&partial_signatures) - .expect("invalid partial sigantures"); + t3n5_hd(Some(3), 5, false), + ] +} - #[cfg(feature = "hd-wallet")] - let public_key = if let Some(path) = &derivation_path { - generic_ec::NonZero::from_point( - shares[0] - .derive_child_public_key::(path.iter().cloned()) - .unwrap() - .public_key, - ) - .unwrap() - } else { - shares[0].shared_public_key - }; - #[cfg(not(feature = "hd-wallet"))] - let public_key = shares[0].shared_public_key; - - signature - .verify(&public_key, &message_to_sign) - .expect("signature is not valid"); - - V::verify(&public_key, &signature, &original_message_to_sign) - .expect("external verification failed") +async fn signing_with_presigs(t: Option, n: u16, hd_wallet: bool) +where + E: Curve + cggmp21_tests::CurveParams, + Point: HasAffineX, + V: ExternalVerifier, +{ + #[cfg(not(feature = "hd-wallet"))] + assert!(!hd_wallet); + + let mut rng = DevRng::new(); + + let shares = cggmp21_tests::CACHED_SHARES + .get_shares::(t, n, hd_wallet) + .expect("retrieve cached shares"); + + let mut simulation = Simulation::>::new(); + + let eid: [u8; 32] = rng.gen(); + let eid = ExecutionId::new(&eid); + + // Choose `t` signers to generate presignature + let t = shares[0].min_signers(); + let mut participants = (0..n).collect::>(); + participants.shuffle(&mut rng); + let participants = &participants[..usize::from(t)]; + println!("Signers: {participants:?}"); + + let participants_shares = participants.iter().map(|i| &shares[usize::from(*i)]); + + let mut outputs = vec![]; + for (i, share) in (0..).zip(participants_shares) { + let party = simulation.add_party(); + let mut party_rng = rng.fork(); + + outputs.push(async move { + cggmp21::signing(eid, i, participants, share) + .generate_presignature(&mut party_rng, party) + .await + }); } - #[test_case::case(None, 3, false; "n3")] - #[test_case::case(Some(3), 5, false; "t3n5")] - #[cfg_attr(feature = "hd-wallet", test_case::case(None, 3, true; "n3-hd"))] - #[cfg_attr(feature = "hd-wallet", test_case::case(Some(3), 5, true; "t3n5-hd"))] - fn signing_sync(t: Option, n: u16, hd_wallet: bool) - where - E: Curve + cggmp21_tests::CurveParams, - Point: HasAffineX, - V: ExternalVerifier, - { - #[cfg(not(feature = "hd-wallet"))] - assert!(!hd_wallet); - - let mut rng = DevRng::new(); - - let shares = cggmp21_tests::CACHED_SHARES - .get_shares::(t, n, hd_wallet) - .expect("retrieve cached shares"); - - let eid: [u8; 32] = rng.gen(); - let eid = ExecutionId::new(&eid); - - let mut original_message_to_sign = [0u8; 100]; - rng.fill_bytes(&mut original_message_to_sign); - let message_to_sign = DataToSign::digest::(&original_message_to_sign); + let presignatures = futures::future::try_join_all(outputs) + .await + .expect("signing failed"); + + // Now, that we have presignatures generated, we learn (generate) a messages to sign + // and the derivation path (if hd is enabled) + let mut original_message_to_sign = [0u8; 100]; + rng.fill_bytes(&mut original_message_to_sign); + let message_to_sign = DataToSign::digest::(&original_message_to_sign); + + #[cfg(feature = "hd-wallet")] + let derivation_path = if hd_wallet { + Some(cggmp21_tests::random_derivation_path(&mut rng)) + } else { + None + }; + + let partial_signatures = presignatures + .into_iter() + .map(|presig| { + #[cfg(feature = "hd-wallet")] + let presig = if let Some(derivation_path) = &derivation_path { + let epub = shares[0].extended_public_key().expect("not hd wallet"); + presig + .set_derivation_path_with_algo::( + epub, + derivation_path.iter().copied(), + ) + .unwrap() + } else { + presig + }; + presig.issue_partial_signature(message_to_sign) + }) + .collect::>(); + + let signature = cggmp21::PartialSignature::combine(&partial_signatures) + .expect("invalid partial sigantures"); + + #[cfg(feature = "hd-wallet")] + let public_key = if let Some(path) = &derivation_path { + generic_ec::NonZero::from_point( + shares[0] + .derive_child_public_key::(path.iter().cloned()) + .unwrap() + .public_key, + ) + .unwrap() + } else { + shares[0].shared_public_key + }; + #[cfg(not(feature = "hd-wallet"))] + let public_key = shares[0].shared_public_key; + + signature + .verify(&public_key, &message_to_sign) + .expect("signature is not valid"); + + V::verify(&public_key, &signature, &original_message_to_sign) + .expect("external verification failed") +} +cggmp21_tests::test_suite! { + test = signing_sync, + generics = [ + secp256k1 = < + cggmp21::supported_curves::Secp256k1, + cggmp21_tests::external_verifier::blockchains::Bitcoin + >, + secp256r1 = < + cggmp21::supported_curves::Secp256r1, + cggmp21_tests::external_verifier::Noop + >, + stark = < + cggmp21::supported_curves::Stark, + cggmp21_tests::external_verifier::blockchains::StarkNet + >, + ], + suites = [ + n3(None, 3, false), + t3n5(Some(3), 5, false), #[cfg(feature = "hd-wallet")] - let derivation_path = if hd_wallet { - Some(cggmp21_tests::random_derivation_path(&mut rng)) - } else { - None - }; - - // Choose `t` signers to perform signing - let t = shares[0].min_signers(); - let mut participants = (0..n).collect::>(); - participants.shuffle(&mut rng); - let participants = &participants[..usize::from(t)]; - println!("Signers: {participants:?}"); - let participants_shares = participants.iter().map(|i| &shares[usize::from(*i)]); - - let mut signer_rng = iter::repeat_with(|| rng.fork()) - .take(n.into()) - .collect::>(); - - let mut simulation = SimulationSync::with_capacity(n); - - for ((i, share), signer_rng) in (0..).zip(participants_shares).zip(&mut signer_rng) { - simulation.add_party({ - let signing = cggmp21::signing(eid, i, participants, share); - - #[cfg(feature = "hd-wallet")] - let signing = if let Some(derivation_path) = derivation_path.clone() { - signing - .set_derivation_path_with_algo::(derivation_path) - .unwrap() - } else { - signing - }; - - signing.sign_sync(signer_rng, message_to_sign) - }) - } - - let signatures = simulation - .run() - .unwrap() - .into_iter() - .collect::, _>>() - .unwrap(); - + n3_hd(None, 3, true), #[cfg(feature = "hd-wallet")] - let public_key = if let Some(path) = &derivation_path { - generic_ec::NonZero::from_point( - shares[0] - .derive_child_public_key::(path.iter().cloned()) + t3n5_hd(Some(3), 5, true), + ] +} + +fn signing_sync(t: Option, n: u16, hd_wallet: bool) +where + E: Curve + cggmp21_tests::CurveParams, + Point: HasAffineX, + V: ExternalVerifier, +{ + #[cfg(not(feature = "hd-wallet"))] + assert!(!hd_wallet); + + let mut rng = DevRng::new(); + + let shares = cggmp21_tests::CACHED_SHARES + .get_shares::(t, n, hd_wallet) + .expect("retrieve cached shares"); + + let eid: [u8; 32] = rng.gen(); + let eid = ExecutionId::new(&eid); + + let mut original_message_to_sign = [0u8; 100]; + rng.fill_bytes(&mut original_message_to_sign); + let message_to_sign = DataToSign::digest::(&original_message_to_sign); + + #[cfg(feature = "hd-wallet")] + let derivation_path = if hd_wallet { + Some(cggmp21_tests::random_derivation_path(&mut rng)) + } else { + None + }; + + // Choose `t` signers to perform signing + let t = shares[0].min_signers(); + let mut participants = (0..n).collect::>(); + participants.shuffle(&mut rng); + let participants = &participants[..usize::from(t)]; + println!("Signers: {participants:?}"); + let participants_shares = participants.iter().map(|i| &shares[usize::from(*i)]); + + let mut signer_rng = iter::repeat_with(|| rng.fork()) + .take(n.into()) + .collect::>(); + + let mut simulation = SimulationSync::with_capacity(n); + + for ((i, share), signer_rng) in (0..).zip(participants_shares).zip(&mut signer_rng) { + simulation.add_party({ + let signing = cggmp21::signing(eid, i, participants, share); + + #[cfg(feature = "hd-wallet")] + let signing = if let Some(derivation_path) = derivation_path.clone() { + signing + .set_derivation_path_with_algo::(derivation_path) .unwrap() - .public_key, - ) - .unwrap() - } else { - shares[0].shared_public_key - }; - #[cfg(not(feature = "hd-wallet"))] - let public_key = shares[0].shared_public_key; - - signatures[0] - .verify(&public_key, &message_to_sign) - .expect("signature is not valid"); - - assert!(signatures.iter().all(|s_i| signatures[0] == *s_i)); - - V::verify(&public_key, &signatures[0], &original_message_to_sign) - .expect("external verification failed") + } else { + signing + }; + + signing.sign_sync(signer_rng, message_to_sign) + }) } - #[instantiate_tests(< - cggmp21::supported_curves::Secp256k1, - cggmp21_tests::external_verifier::blockchains::Bitcoin - >)] - mod secp256k1 {} - #[instantiate_tests(< - cggmp21::supported_curves::Secp256r1, - cggmp21_tests::external_verifier::Noop - >)] - mod secp256r1 {} - #[instantiate_tests(< - cggmp21::supported_curves::Stark, - cggmp21_tests::external_verifier::blockchains::StarkNet - >)] - mod stark {} + let signatures = simulation + .run() + .unwrap() + .into_iter() + .collect::, _>>() + .unwrap(); + + #[cfg(feature = "hd-wallet")] + let public_key = if let Some(path) = &derivation_path { + generic_ec::NonZero::from_point( + shares[0] + .derive_child_public_key::(path.iter().cloned()) + .unwrap() + .public_key, + ) + .unwrap() + } else { + shares[0].shared_public_key + }; + #[cfg(not(feature = "hd-wallet"))] + let public_key = shares[0].shared_public_key; + + signatures[0] + .verify(&public_key, &message_to_sign) + .expect("signature is not valid"); + + assert!(signatures.iter().all(|s_i| signatures[0] == *s_i)); + + V::verify(&public_key, &signatures[0], &original_message_to_sign) + .expect("external verification failed") } From fe75209be5559487a449c9ce53c52396e9f757e8 Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Mon, 25 Nov 2024 18:13:44 +0100 Subject: [PATCH 08/19] Move external verifier into CurveParams Signed-off-by: Denis Varlakov --- tests/src/lib.rs | 5 ++++ tests/tests/it/signing.rs | 60 ++++++++++----------------------------- 2 files changed, 20 insertions(+), 45 deletions(-) diff --git a/tests/src/lib.rs b/tests/src/lib.rs index 9a3ffdd..5efb327 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -179,21 +179,26 @@ pub trait CurveParams: Curve { /// Which HD derivation algorithm to use with that curve #[cfg(feature = "hd-wallet")] type HdAlgo: cggmp21::hd_wallet::HdWallet; + /// External verifier for signatures on this curve + type ExVerifier: external_verifier::ExternalVerifier; } impl CurveParams for cggmp21::supported_curves::Secp256k1 { #[cfg(feature = "hd-wallet")] type HdAlgo = cggmp21::hd_wallet::Slip10; + type ExVerifier = external_verifier::blockchains::Bitcoin; } impl CurveParams for cggmp21::supported_curves::Secp256r1 { #[cfg(feature = "hd-wallet")] type HdAlgo = cggmp21::hd_wallet::Slip10; + type ExVerifier = external_verifier::Noop; } impl CurveParams for cggmp21::supported_curves::Stark { #[cfg(feature = "hd-wallet")] type HdAlgo = cggmp21::hd_wallet::Stark; + type ExVerifier = external_verifier::blockchains::StarkNet; } #[macro_export] diff --git a/tests/tests/it/signing.rs b/tests/tests/it/signing.rs index 901d01e..b1b7797 100644 --- a/tests/tests/it/signing.rs +++ b/tests/tests/it/signing.rs @@ -15,18 +15,9 @@ use cggmp21::{security_level::SecurityLevel128, ExecutionId}; cggmp21_tests::test_suite! { async_test = signing_works, generics = [ - secp256k1 = < - cggmp21::supported_curves::Secp256k1, - cggmp21_tests::external_verifier::blockchains::Bitcoin - >, - secp256r1 = < - cggmp21::supported_curves::Secp256r1, - cggmp21_tests::external_verifier::Noop - >, - stark = < - cggmp21::supported_curves::Stark, - cggmp21_tests::external_verifier::blockchains::StarkNet - >, + secp256k1 = , + secp256r1 = , + stark = , ], suites = [ n2(None, 2, false, false), @@ -45,11 +36,10 @@ cggmp21_tests::test_suite! { ] } -async fn signing_works(t: Option, n: u16, reliable_broadcast: bool, hd_wallet: bool) +async fn signing_works(t: Option, n: u16, reliable_broadcast: bool, hd_wallet: bool) where E: Curve + cggmp21_tests::CurveParams, Point: HasAffineX, - V: ExternalVerifier, { #[cfg(not(feature = "hd-wallet"))] assert!(!hd_wallet); @@ -134,25 +124,16 @@ where assert!(signatures.iter().all(|s_i| signatures[0] == *s_i)); - V::verify(&public_key, &signatures[0], &original_message_to_sign) + E::ExVerifier::verify(&public_key, &signatures[0], &original_message_to_sign) .expect("external verification failed") } cggmp21_tests::test_suite! { async_test = signing_with_presigs, generics = [ - secp256k1 = < - cggmp21::supported_curves::Secp256k1, - cggmp21_tests::external_verifier::blockchains::Bitcoin - >, - secp256r1 = < - cggmp21::supported_curves::Secp256r1, - cggmp21_tests::external_verifier::Noop - >, - stark = < - cggmp21::supported_curves::Stark, - cggmp21_tests::external_verifier::blockchains::StarkNet - >, + secp256k1 = , + secp256r1 = , + stark = , ], suites = [ t3n5(Some(3), 5, false), @@ -161,11 +142,10 @@ cggmp21_tests::test_suite! { ] } -async fn signing_with_presigs(t: Option, n: u16, hd_wallet: bool) +async fn signing_with_presigs(t: Option, n: u16, hd_wallet: bool) where E: Curve + cggmp21_tests::CurveParams, Point: HasAffineX, - V: ExternalVerifier, { #[cfg(not(feature = "hd-wallet"))] assert!(!hd_wallet); @@ -260,25 +240,16 @@ where .verify(&public_key, &message_to_sign) .expect("signature is not valid"); - V::verify(&public_key, &signature, &original_message_to_sign) + E::ExVerifier::verify(&public_key, &signature, &original_message_to_sign) .expect("external verification failed") } cggmp21_tests::test_suite! { test = signing_sync, generics = [ - secp256k1 = < - cggmp21::supported_curves::Secp256k1, - cggmp21_tests::external_verifier::blockchains::Bitcoin - >, - secp256r1 = < - cggmp21::supported_curves::Secp256r1, - cggmp21_tests::external_verifier::Noop - >, - stark = < - cggmp21::supported_curves::Stark, - cggmp21_tests::external_verifier::blockchains::StarkNet - >, + secp256k1 = , + secp256r1 = , + stark = , ], suites = [ n3(None, 3, false), @@ -290,11 +261,10 @@ cggmp21_tests::test_suite! { ] } -fn signing_sync(t: Option, n: u16, hd_wallet: bool) +fn signing_sync(t: Option, n: u16, hd_wallet: bool) where E: Curve + cggmp21_tests::CurveParams, Point: HasAffineX, - V: ExternalVerifier, { #[cfg(not(feature = "hd-wallet"))] assert!(!hd_wallet); @@ -378,6 +348,6 @@ where assert!(signatures.iter().all(|s_i| signatures[0] == *s_i)); - V::verify(&public_key, &signatures[0], &original_message_to_sign) + E::ExVerifier::verify(&public_key, &signatures[0], &original_message_to_sign) .expect("external verification failed") } From ff87f8fc880e7d5487cf0c14df9c98d51ae94af0 Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Tue, 26 Nov 2024 10:53:05 +0100 Subject: [PATCH 09/19] Simplify the macro a lil bit Signed-off-by: Denis Varlakov --- tests/src/lib.rs | 66 ++++++++++++------------------------------------ 1 file changed, 16 insertions(+), 50 deletions(-) diff --git a/tests/src/lib.rs b/tests/src/lib.rs index 5efb327..34233eb 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -213,7 +213,7 @@ macro_rules! test_suite { use super::$test; $crate::test_suite_traverse! { async_test = $test, - generics_list = [$($gmod = <$($generic),+>),+], + generics = [$($gmod = <$($generic),+>),+], suites = [$($suites)*] } } @@ -229,7 +229,7 @@ macro_rules! test_suite { use super::$test; $crate::test_suite_traverse! { test = $test, - generics_list = [$($gmod = <$($generic),+>),+], + generics = [$($gmod = <$($generic),+>),+], suites = [$($suites)*] } } @@ -242,8 +242,8 @@ macro_rules! test_suite_traverse { // --- Async Test Function ( async_test = $test:ident, - // we traverse over `generics_list` - generics_list = [$gmod:ident = <$($generic:path),*>$(, $($generics_rest:tt)*)?], + // we traverse over `generics` + generics = [$gmod:ident = <$($generic:path),*>$(, $($generics_rest:tt)*)?], suites = [$($suites:tt)*] ) => { mod $gmod { @@ -255,15 +255,15 @@ macro_rules! test_suite_traverse { } $crate::test_suite_traverse! { async_test = $test, - generics_list = [$($($generics_rest)*)?], + generics = [$($($generics_rest)*)?], suites = [$($suites)*] } } }; ( async_test = $test:ident, - // generics_list is empty - nothing to traverse - generics_list = [], + // generics list is empty - nothing to traverse + generics = [], suites = [$($suites:tt)*] ) => {}; @@ -271,30 +271,13 @@ macro_rules! test_suite_traverse { async_test = $test:ident, generics = <$($generic:path),*>, // we traverse suites - suites = [$suite_name:ident($($args:tt)*)$(, $($rest:tt)*)?] - ) => { - #[tokio::test] - async fn $suite_name() { - $test::<$($generic),+>($($args)*).await - } - - $crate::test_suite_traverse! { - async_test = $test, - generics = <$($generic),*>, - suites = [$($($rest)*)?] - } - }; - ( - async_test = $test:ident, - generics = <$($generic:path),*>, - // we traverse suites, the next suite has extra attrs suites = [ - $(#[$attr:meta])+ + $(#[$attr:meta])* $suite_name:ident($($args:tt)*) $(, $($rest:tt)*)? ] ) => { - $(#[$attr])+ + $(#[$attr])* #[tokio::test] async fn $suite_name() { $test::<$($generic),+>($($args)*).await @@ -316,8 +299,8 @@ macro_rules! test_suite_traverse { // --- Sync Test Function ( test = $test:ident, - // we traverse over `generics_list` - generics_list = [$gmod:ident = <$($generic:path),*>$(, $($generics_rest:tt)*)?], + // we traverse over `generics` + generics = [$gmod:ident = <$($generic:path),*>$(, $($generics_rest:tt)*)?], suites = [$($suites:tt)*] ) => { mod $gmod { @@ -329,15 +312,15 @@ macro_rules! test_suite_traverse { } $crate::test_suite_traverse! { test = $test, - generics_list = [$($($generics_rest)*)?], + generics = [$($($generics_rest)*)?], suites = [$($suites)*] } } }; ( test = $test:ident, - // generics_list is empty - nothing to traverse - generics_list = [], + // generics list is empty - nothing to traverse + generics = [], suites = [$($suites:tt)*] ) => {}; @@ -345,30 +328,13 @@ macro_rules! test_suite_traverse { test = $test:ident, generics = <$($generic:path),*>, // we traverse suites - suites = [$suite_name:ident($($args:tt)*)$(, $($rest:tt)*)?] - ) => { - #[test] - fn $suite_name() { - $test::<$($generic),+>($($args)*) - } - - $crate::test_suite_traverse! { - test = $test, - generics = <$($generic),*>, - suites = [$($($rest)*)?] - } - }; - ( - test = $test:ident, - generics = <$($generic:path),*>, - // we traverse suites, the next suite has extra attrs suites = [ - $(#[$attr:meta])+ + $(#[$attr:meta])* $suite_name:ident($($args:tt)*) $(, $($rest:tt)*)? ] ) => { - $(#[$attr])+ + $(#[$attr])* #[test] fn $suite_name() { $test::<$($generic),+>($($args)*) From fe34cbc5cceeda17c05d55bf2fa25cf04147dce2 Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Tue, 26 Nov 2024 11:02:48 +0100 Subject: [PATCH 10/19] Improve the macro Signed-off-by: Denis Varlakov --- tests/src/lib.rs | 90 ++++++++++++++------------------------- tests/tests/it/signing.rs | 18 ++------ 2 files changed, 35 insertions(+), 73 deletions(-) diff --git a/tests/src/lib.rs b/tests/src/lib.rs index 34233eb..9ca983e 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -204,31 +204,35 @@ impl CurveParams for cggmp21::supported_curves::Stark { #[macro_export] macro_rules! test_suite { ( - async_test = $test:ident, - generics = [$($gmod:ident = <$($generic:path),*>),+$(,)?], + $(async_test = $async_test:ident,)? + $(test = $test:ident,)? + generics = all_curves, suites = [$($suites:tt)*] $(,)? ) => { - mod $test { - use super::$test; - $crate::test_suite_traverse! { - async_test = $test, - generics = [$($gmod = <$($generic),+>),+], - suites = [$($suites)*] - } + $crate::test_suite! { + $(async_test = $async_test,)? + $(test = $test,)? + generics = [ + secp256k1 = , + secp256r1 = , + stark = , + ], + suites = [$($suites)*] } }; - ( - test = $test:ident, + $(async_test = $async_test:ident,)? + $(test = $test:ident,)? generics = [$($gmod:ident = <$($generic:path),*>),+$(,)?], suites = [$($suites:tt)*] $(,)? ) => { - mod $test { - use super::$test; + mod $($test)? $($async_test)? { + use super::$($test)? $($async_test)?; $crate::test_suite_traverse! { - test = $test, + $(async_test = $async_test,)? + $(test = $test,)? generics = [$($gmod = <$($generic),+>),+], suites = [$($suites)*] } @@ -239,29 +243,33 @@ macro_rules! test_suite { #[macro_export] #[doc(hidden)] macro_rules! test_suite_traverse { - // --- Async Test Function ( - async_test = $test:ident, + // Either `$async_test` or `$test` must be present, but not at the same time + $(async_test = $async_test:ident,)? + $(test = $test:ident,)? // we traverse over `generics` generics = [$gmod:ident = <$($generic:path),*>$(, $($generics_rest:tt)*)?], suites = [$($suites:tt)*] ) => { mod $gmod { - use super::$test; + use super::$($test)? $($async_test)?; $crate::test_suite_traverse! { - async_test = $test, + $(async_test = $async_test,)? + $(test = $test,)? generics = <$($generic),+>, suites = [$($suites)*] } $crate::test_suite_traverse! { - async_test = $test, + $(async_test = $async_test,)? + $(test = $test,)? generics = [$($($generics_rest)*)?], suites = [$($suites)*] } } }; ( - async_test = $test:ident, + $(async_test = $async_test:ident,)? + $(test = $test:ident,)? // generics list is empty - nothing to traverse generics = [], suites = [$($suites:tt)*] @@ -270,7 +278,7 @@ macro_rules! test_suite_traverse { ( async_test = $test:ident, generics = <$($generic:path),*>, - // we traverse suites + // we traverse async suites suites = [ $(#[$attr:meta])* $suite_name:ident($($args:tt)*) @@ -289,45 +297,10 @@ macro_rules! test_suite_traverse { suites = [$($($rest)*)?] } }; - ( - async_test = $test:ident, - generics = <$($generic:path),*>, - // suites list is empty - nothing to traverse - suites = [] - ) => {}; - - // --- Sync Test Function - ( - test = $test:ident, - // we traverse over `generics` - generics = [$gmod:ident = <$($generic:path),*>$(, $($generics_rest:tt)*)?], - suites = [$($suites:tt)*] - ) => { - mod $gmod { - use super::$test; - $crate::test_suite_traverse! { - test = $test, - generics = <$($generic),+>, - suites = [$($suites)*] - } - $crate::test_suite_traverse! { - test = $test, - generics = [$($($generics_rest)*)?], - suites = [$($suites)*] - } - } - }; - ( - test = $test:ident, - // generics list is empty - nothing to traverse - generics = [], - suites = [$($suites:tt)*] - ) => {}; - ( test = $test:ident, generics = <$($generic:path),*>, - // we traverse suites + // we traverse sync suites suites = [ $(#[$attr:meta])* $suite_name:ident($($args:tt)*) @@ -347,7 +320,8 @@ macro_rules! test_suite_traverse { } }; ( - test = $test:ident, + $(async_test = $async_test:ident,)? + $(test = $test:ident,)? generics = <$($generic:path),*>, // suites list is empty - nothing to traverse suites = [] diff --git a/tests/tests/it/signing.rs b/tests/tests/it/signing.rs index b1b7797..0a6af3b 100644 --- a/tests/tests/it/signing.rs +++ b/tests/tests/it/signing.rs @@ -14,11 +14,7 @@ use cggmp21::{security_level::SecurityLevel128, ExecutionId}; cggmp21_tests::test_suite! { async_test = signing_works, - generics = [ - secp256k1 = , - secp256r1 = , - stark = , - ], + generics = all_curves, suites = [ n2(None, 2, false, false), n2_reliable(None, 2, true, false), @@ -130,11 +126,7 @@ where cggmp21_tests::test_suite! { async_test = signing_with_presigs, - generics = [ - secp256k1 = , - secp256r1 = , - stark = , - ], + generics = all_curves, suites = [ t3n5(Some(3), 5, false), #[cfg(feature = "hd-wallet")] @@ -246,11 +238,7 @@ where cggmp21_tests::test_suite! { test = signing_sync, - generics = [ - secp256k1 = , - secp256r1 = , - stark = , - ], + generics = all_curves, suites = [ n3(None, 3, false), t3n5(Some(3), 5, false), From 18f5abbac549db2142321cad0eeb22906852179e Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Tue, 26 Nov 2024 17:37:33 +0100 Subject: [PATCH 11/19] Fix bug in the macro Signed-off-by: Denis Varlakov --- tests/src/lib.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/src/lib.rs b/tests/src/lib.rs index 9ca983e..ebd3e9e 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -259,12 +259,12 @@ macro_rules! test_suite_traverse { generics = <$($generic),+>, suites = [$($suites)*] } - $crate::test_suite_traverse! { - $(async_test = $async_test,)? - $(test = $test,)? - generics = [$($($generics_rest)*)?], - suites = [$($suites)*] - } + } + $crate::test_suite_traverse! { + $(async_test = $async_test,)? + $(test = $test,)? + generics = [$($($generics_rest)*)?], + suites = [$($suites)*] } }; ( From 81191c0659bb9bf1f4ef901e3d6cc428fc45eb22 Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Wed, 27 Nov 2024 14:42:45 +0100 Subject: [PATCH 12/19] Update round-based to v0.4 Signed-off-by: Denis Varlakov --- Cargo.lock | 37 ++-------- Cargo.toml | 6 +- cggmp21/Cargo.toml | 2 +- cggmp21/src/signing.rs | 2 +- tests/Cargo.toml | 3 +- tests/src/bin/measure_perf.rs | 92 +++++++++---------------- tests/tests/it/key_refresh.rs | 100 +++++++++++---------------- tests/tests/it/keygen.rs | 63 ++++++----------- tests/tests/it/pipeline.rs | 110 ++++++++++++------------------ tests/tests/it/signing.rs | 106 +++++++++++----------------- tests/tests/it/stark_prehashed.rs | 35 ++++------ 11 files changed, 202 insertions(+), 354 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d89b8e2..9df0848 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -342,7 +342,6 @@ dependencies = [ "starknet-providers", "starknet-signers", "test-case", - "tokio", "url", ] @@ -1815,25 +1814,21 @@ dependencies = [ [[package]] name = "round-based" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55f473f56ecfa6457a75c0922c4e51ad036d4a1d27b0a697ac3a9b26f74acc3b" +version = "0.4.0" +source = "git+https://github.com/LFDT-Lockness/round-based?branch=impr-sim#e662e7142eb3c5d96f3202c6cc7f853a2db0486b" dependencies = [ "displaydoc", "futures-util", "phantom-type 0.3.1", "round-based-derive", "thiserror", - "tokio", - "tokio-stream", "tracing", ] [[package]] name = "round-based-derive" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c3f220fb17bab108a448f516ce4ec470584675233ab3a799915ba71295da32e" +version = "0.2.2" +source = "git+https://github.com/LFDT-Lockness/round-based?branch=impr-sim#e662e7142eb3c5d96f3202c6cc7f853a2db0486b" dependencies = [ "proc-macro2", "quote", @@ -2448,21 +2443,9 @@ dependencies = [ "mio", "pin-project-lite", "socket2", - "tokio-macros", "winapi", ] -[[package]] -name = "tokio-macros" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.101", -] - [[package]] name = "tokio-rustls" version = "0.24.1" @@ -2473,18 +2456,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-stream" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6edf2d6bc038a43d31353570e27270603f4648d18f5ed10c0e179abe43255af" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", - "tokio-util", -] - [[package]] name = "tokio-util" version = "0.7.4" diff --git a/Cargo.toml b/Cargo.toml index f7e54d2..263f06b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ key-share = { version = "0.6", path = "key-share", default-features = false } generic-ec = { version = "0.4.1", default-features = false } generic-ec-zkp = { version = "0.4.1", default-features = false } -round-based = { version = "0.3", default-features = false } +round-based = { version = "0.4", default-features = false } paillier-zk = "0.4.1" udigest = { version = "0.2.1", default-features = false } @@ -48,3 +48,7 @@ generic-tests = "0.1" [patch.crates-io.hd-wallet] git = "https://github.com/LFDT-Lockness/hd-wallet" branch = "dt" + +[patch.crates-io.round-based] +git = "https://github.com/LFDT-Lockness/round-based" +branch = "impr-sim" diff --git a/cggmp21/Cargo.toml b/cggmp21/Cargo.toml index 016bbd1..5b9e99e 100644 --- a/cggmp21/Cargo.toml +++ b/cggmp21/Cargo.toml @@ -38,7 +38,7 @@ hex = { workspace = true, default-features = false, features = ["serde"] } hd-wallet = { workspace = true, optional = true, features = ["std"] } [dev-dependencies] -round-based = { workspace = true, features = ["derive", "dev"] } +round-based = { workspace = true, features = ["derive", "sim"] } rand = { workspace = true } rand_dev = { workspace = true } diff --git a/cggmp21/src/signing.rs b/cggmp21/src/signing.rs index a8cce16..9f5d92b 100644 --- a/cggmp21/src/signing.rs +++ b/cggmp21/src/signing.rs @@ -96,7 +96,7 @@ pub struct PartialSignature { } /// ECDSA signature -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, Debug)] #[serde(bound = "")] pub struct Signature { /// $r$ component of signature diff --git a/tests/Cargo.toml b/tests/Cargo.toml index c1768d2..3efa9bb 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -19,14 +19,13 @@ rand_dev = { workspace = true } sha2 = { workspace = true } -round-based = { workspace = true, features = ["derive", "dev", "state-machine"] } +round-based = { workspace = true, features = ["derive", "sim", "state-machine"] } generic-ec = { workspace = true, features = ["serde", "all-curves"] } bpaf = "0.7" include_dir = "0.7" ciborium = "0.2" -tokio = { version = "1", features = ["macros"] } futures = "0.3" lazy_static = "1.4" diff --git a/tests/src/bin/measure_perf.rs b/tests/src/bin/measure_perf.rs index 337feb5..494a5c4 100644 --- a/tests/src/bin/measure_perf.rs +++ b/tests/src/bin/measure_perf.rs @@ -8,11 +8,9 @@ use cggmp21::{ }; use rand::Rng; use rand_dev::DevRng; -use round_based::simulation::Simulation; use sha2::Sha256; type E = generic_ec::curves::Secp256k1; -type D = sha2::Sha256; struct Args { n: Vec, @@ -55,17 +53,16 @@ fn args() -> Args { .to_options() .run() } -#[tokio::main(flavor = "current_thread")] -async fn main() { +fn main() { let args = args(); if args.custom_sec_level { - do_becnhmarks::(args).await + do_becnhmarks::(args) } else { - do_becnhmarks::(args).await + do_becnhmarks::(args) } } -async fn do_becnhmarks(args: Args) { +fn do_becnhmarks(args: Args) { let mut rng = DevRng::new(); for n in args.n { @@ -89,11 +86,7 @@ async fn do_becnhmarks(args: Args) { let eid: [u8; 32] = rng.gen(); let eid = ExecutionId::new(&eid); - let mut simulation = - Simulation::>::new(); - - let outputs = (0..n).map(|i| { - let party = simulation.add_party(); + let outputs = round_based::simulation::run(n, |i, party| { let mut party_rng = rng.fork(); let mut profiler = PerfProfiler::new(); @@ -108,11 +101,10 @@ async fn do_becnhmarks(args: Args) { let report = profiler.get_report().context("get perf report")?; Ok::<_, anyhow::Error>((key_share, report)) } - }); - - let outputs = futures::future::try_join_all(outputs) - .await - .expect("non-threshold keygen failed"); + }) + .unwrap() + .expect_ok() + .into_vec(); if args.bench_non_threshold_keygen { println!("Non-threshold DKG"); @@ -132,13 +124,7 @@ async fn do_becnhmarks(args: Args) { let eid: [u8; 32] = rng.gen(); let eid = ExecutionId::new(&eid); - let mut simulation = - Simulation::>::with_capacity( - (2 * n * n).into(), - ); - - let outputs = (0..n).map(|i| { - let party = simulation.add_party(); + let outputs = round_based::simulation::run(n, |i, party| { let mut party_rng = rng.fork(); let mut profiler = PerfProfiler::new(); @@ -154,11 +140,10 @@ async fn do_becnhmarks(args: Args) { let report = profiler.get_report().context("get perf report")?; Ok::<_, anyhow::Error>((key_share, report)) } - }); - - let outputs = futures::future::try_join_all(outputs) - .await - .expect("threshold keygen failed"); + }) + .unwrap() + .expect_ok() + .into_vec(); println!("Threshold DKG"); println!("{}", outputs[0].1.clone().display_io(false)); @@ -174,12 +159,9 @@ async fn do_becnhmarks(args: Args) { let eid: [u8; 32] = rng.gen(); let eid = ExecutionId::new(&eid); - let mut simulation = Simulation::>::new(); - let mut primes = cggmp21_tests::CACHED_PRIMES.iter::(); - let outputs = (0..n).map(|i| { - let party = simulation.add_party(); + let outputs = round_based::simulation::run(n, |i, party| { let mut party_rng = rng.fork(); let pregen = primes.next().expect("Can't get pregenerated prime"); @@ -194,11 +176,10 @@ async fn do_becnhmarks(args: Args) { let report = profiler.get_report().context("get perf report")?; Ok::<_, anyhow::Error>((aux_data, report)) } - }); - - let outputs = futures::future::try_join_all(outputs) - .await - .expect("key refresh failed"); + }) + .unwrap() + .expect_ok() + .into_vec(); if args.bench_aux_data_gen { println!("Auxiliary data generation protocol"); @@ -261,29 +242,24 @@ async fn do_becnhmarks(args: Args) { let message_to_sign = b"Dfns rules!"; let message_to_sign = DataToSign::digest::(message_to_sign); - use cggmp21::signing::msg::Msg; - let mut simulation = Simulation::>::new(); - - let mut outputs = vec![]; - for (i, share) in (0..).zip(&shares) { - let party = simulation.add_party(); - let mut party_rng = rng.fork(); + let perf_reports = + round_based::simulation::run_with_setup(&shares, |i, party, share| { + let mut party_rng = rng.fork(); - let mut profiler = PerfProfiler::new(); + let mut profiler = PerfProfiler::new(); - outputs.push(async move { - let _signature = cggmp21::signing(eid, i, signers_indexes_at_keygen, share) - .set_progress_tracer(&mut profiler) - .sign(&mut party_rng, party, message_to_sign) - .await - .context("signing failed")?; - profiler.get_report().context("get perf report") + async move { + let _signature = cggmp21::signing(eid, i, signers_indexes_at_keygen, share) + .set_progress_tracer(&mut profiler) + .sign(&mut party_rng, party, message_to_sign) + .await + .context("signing failed")?; + profiler.get_report().context("get perf report") + } }) - } - - let perf_reports = futures::future::try_join_all(outputs) - .await - .expect("signing failed"); + .unwrap() + .expect_ok() + .into_vec(); println!("Signing protocol"); println!("{}", perf_reports[0].clone().display_io(false)); diff --git a/tests/tests/it/key_refresh.rs b/tests/tests/it/key_refresh.rs index d9fad60..46c5b30 100644 --- a/tests/tests/it/key_refresh.rs +++ b/tests/tests/it/key_refresh.rs @@ -3,7 +3,6 @@ mod generic { use generic_ec::Point; use rand::seq::SliceRandom; use rand::Rng; - use round_based::simulation::Simulation; use sha2::Sha256; use cggmp21::{ @@ -15,8 +14,7 @@ mod generic { #[test_case::case(3, false; "n3")] #[test_case::case(5, false; "n5")] #[test_case::case(5, true; "n5-reliable")] - #[tokio::test] - async fn key_refresh_works(n: u16, reliable_broadcast: bool) + fn key_refresh_works(n: u16, reliable_broadcast: bool) where Point: generic_ec::coords::HasAffineX, { @@ -29,16 +27,14 @@ mod generic { #[cfg(feature = "hd-wallet")] assert!(shares[0].chain_code.is_some()); - let mut primes = cggmp21_tests::CACHED_PRIMES.iter(); + let mut primes = cggmp21_tests::CACHED_PRIMES.iter::(); // Perform refresh let eid: [u8; 32] = rng.gen(); let eid = ExecutionId::new(&eid); - let mut simulation = - Simulation::>::new(); - let outputs = shares.iter().map(|share| { - let party = simulation.add_party(); + + let key_shares = round_based::simulation::run_with_setup(&shares, |_i, party, share| { let mut party_rng = rng.fork(); let pregenerated_data = primes.next().expect("Can't fetch primes"); async move { @@ -47,11 +43,10 @@ mod generic { .start(&mut party_rng, party) .await } - }); - - let key_shares = futures::future::try_join_all(outputs) - .await - .expect("keygen failed"); + }) + .unwrap() + .expect_ok() + .into_vec(); // validate key shares @@ -89,15 +84,12 @@ mod generic { // attempt to sign with new shares and verify the signature - let mut simulation = Simulation::>::new(); - let eid: [u8; 32] = rng.gen(); let eid = ExecutionId::new(&eid); let message_to_sign = cggmp21::signing::DataToSign::digest::(&[42; 100]); let participants = &(0..n).collect::>(); - let outputs = key_shares.iter().map(|share| { - let party = simulation.add_party(); + let sig = round_based::simulation::run_with_setup(&key_shares, |_i, party, share| { let mut party_rng = rng.fork(); async move { cggmp21::signing(eid, share.core.i, participants, share) @@ -105,23 +97,19 @@ mod generic { .sign(&mut party_rng, party, message_to_sign) .await } - }); - let signatures = futures::future::try_join_all(outputs) - .await - .expect("signing failed"); - - for signature in &signatures { - signature - .verify(&key_shares[0].core.shared_public_key, &message_to_sign) - .expect("signature is not valid"); - } + }) + .unwrap() + .expect_ok() + .expect_eq(); + + sig.verify(&key_shares[0].core.shared_public_key, &message_to_sign) + .expect("signature is not valid"); } #[test_case::case(2, 3, false; "t2n3")] #[test_case::case(3, 5, false; "t3n5")] #[test_case::case(3, 5, true; "t3n5-reliable")] - #[tokio::test] - async fn aux_gen_works(t: u16, n: u16, reliable_broadcast: bool) + fn aux_gen_works(t: u16, n: u16, reliable_broadcast: bool) where Point: generic_ec::coords::HasAffineX, { @@ -130,18 +118,14 @@ mod generic { let shares = cggmp21_tests::CACHED_SHARES .get_shares::(Some(t), n, false) .expect("retrieve cached shares"); - let mut primes = cggmp21_tests::CACHED_PRIMES.iter(); + let mut primes = cggmp21_tests::CACHED_PRIMES.iter::(); // Perform refresh - let mut simulation = - Simulation::>::new(); - let eid: [u8; 32] = rng.gen(); let eid = ExecutionId::new(&eid); - let outputs = (0..n).map(|i| { - let party = simulation.add_party(); + let aux_infos = round_based::simulation::run(n, |i, party| { let mut party_rng = rng.fork(); let pregenerated_data = primes.next().expect("Can't fetch primes"); async move { @@ -150,11 +134,10 @@ mod generic { .start(&mut party_rng, party) .await } - }); - - let aux_infos = futures::future::try_join_all(outputs) - .await - .expect("keygen failed"); + }) + .unwrap() + .expect_ok() + .into_vec(); // validate key shares @@ -173,8 +156,6 @@ mod generic { // attempt to sign with new shares and verify the signature - let mut simulation = Simulation::>::new(); - let eid: [u8; 32] = rng.gen(); let eid = ExecutionId::new(&eid); @@ -187,25 +168,22 @@ mod generic { println!("Signers: {participants:?}"); let participants_shares = participants.iter().map(|i| &key_shares[usize::from(*i)]); - let outputs = participants_shares.zip(0..).map(|(share, i)| { - let party = simulation.add_party(); - let mut party_rng = rng.fork(); - async move { - cggmp21::signing(eid, i, participants, share) - .enforce_reliable_broadcast(reliable_broadcast) - .sign(&mut party_rng, party, message_to_sign) - .await - } - }); - let signatures = futures::future::try_join_all(outputs) - .await - .expect("signing failed"); - - for signature in &signatures { - signature - .verify(&key_shares[0].core.shared_public_key, &message_to_sign) - .expect("signature is not valid"); - } + let sig = + round_based::simulation::run_with_setup(participants_shares, |i, party, share| { + let mut party_rng = rng.fork(); + async move { + cggmp21::signing(eid, i, participants, share) + .enforce_reliable_broadcast(reliable_broadcast) + .sign(&mut party_rng, party, message_to_sign) + .await + } + }) + .unwrap() + .expect_ok() + .expect_eq(); + + sig.verify(&key_shares[0].core.shared_public_key, &message_to_sign) + .expect("signature is not valid"); } #[instantiate_tests()] diff --git a/tests/tests/it/keygen.rs b/tests/tests/it/keygen.rs index d21c53a..6ea83e1 100644 --- a/tests/tests/it/keygen.rs +++ b/tests/tests/it/keygen.rs @@ -5,13 +5,8 @@ mod generic { use generic_ec::{Curve, Point}; use rand::{seq::SliceRandom, Rng}; use rand_dev::DevRng; - use round_based::simulation::{Simulation, SimulationSync}; - use sha2::Sha256; - use cggmp21::keygen::{NonThresholdMsg, ThresholdMsg}; - use cggmp21::{ - key_share::reconstruct_secret_key, security_level::SecurityLevel128, ExecutionId, - }; + use cggmp21::{key_share::reconstruct_secret_key, ExecutionId}; #[test_case::case(3, false, false; "n3")] #[test_case::case(5, false, false; "n5")] @@ -22,37 +17,31 @@ mod generic { #[cfg_attr(feature = "hd-wallet", test_case::case(5, false, true; "n5-hd"))] #[cfg_attr(feature = "hd-wallet", test_case::case(7, false, true; "n7-hd"))] #[cfg_attr(feature = "hd-wallet", test_case::case(10, false, true; "n10-hd"))] - #[tokio::test] - async fn keygen_works(n: u16, reliable_broadcast: bool, hd_wallet: bool) { + fn keygen_works(n: u16, reliable_broadcast: bool, hd_wallet: bool) { #[cfg(not(feature = "hd-wallet"))] assert!(!hd_wallet); let mut rng = DevRng::new(); - let mut simulation = Simulation::>::new(); - let eid: [u8; 32] = rng.gen(); let eid = ExecutionId::new(&eid); - let mut outputs = vec![]; - for i in 0..n { - let party = simulation.add_party(); + let key_shares = round_based::simulation::run(n, |i, party| { let mut party_rng = rng.fork(); - outputs.push(async move { + async move { let keygen = - cggmp21::keygen(eid, i, n).enforce_reliable_broadcast(reliable_broadcast); + cggmp21::keygen::(eid, i, n).enforce_reliable_broadcast(reliable_broadcast); #[cfg(feature = "hd-wallet")] let keygen = keygen.hd_wallet(hd_wallet); keygen.start(&mut party_rng, party).await - }) - } - - let key_shares = futures::future::try_join_all(outputs) - .await - .expect("keygen failed"); + } + }) + .unwrap() + .expect_ok() + .into_vec(); validate_keygen_output(&mut rng, &key_shares, hd_wallet); } @@ -62,30 +51,20 @@ mod generic { #[test_case::case(3, 5, true, false; "t3n5-reliable")] #[cfg_attr(feature = "hd-wallet", test_case::case(2, 3, false, true; "t2n3-hd"))] #[cfg_attr(feature = "hd-wallet", test_case::case(3, 5, false, true; "t3n5-hd"))] - #[tokio::test] - async fn threshold_keygen_works( - t: u16, - n: u16, - reliable_broadcast: bool, - hd_wallet: bool, - ) { + fn threshold_keygen_works(t: u16, n: u16, reliable_broadcast: bool, hd_wallet: bool) { #[cfg(not(feature = "hd-wallet"))] assert!(!hd_wallet); let mut rng = DevRng::new(); - let mut simulation = Simulation::>::new(); - let eid: [u8; 32] = rng.gen(); let eid = ExecutionId::new(&eid); - let mut outputs = vec![]; - for i in 0..n { - let party = simulation.add_party(); + let key_shares = round_based::simulation::run(n, |i, party| { let mut party_rng = rng.fork(); - outputs.push(async move { - let keygen = cggmp21::keygen(eid, i, n) + async move { + let keygen = cggmp21::keygen::(eid, i, n) .enforce_reliable_broadcast(reliable_broadcast) .set_threshold(t); @@ -93,12 +72,11 @@ mod generic { let keygen = keygen.hd_wallet(hd_wallet); keygen.start(&mut party_rng, party).await - }) - } - - let key_shares = futures::future::try_join_all(outputs) - .await - .expect("keygen failed"); + } + }) + .unwrap() + .expect_ok() + .into_vec(); validate_keygen_output(&mut rng, &key_shares, hd_wallet); } @@ -118,7 +96,7 @@ mod generic { .take(n.into()) .collect::>(); - let mut simulation = SimulationSync::with_capacity(n); + let mut simulation = round_based::simulation::Simulation::with_capacity(n); for (i, party_rng) in (0..).zip(&mut party_rng) { simulation.add_party({ let keygen = cggmp21::keygen::(eid, i, n).set_threshold(t); @@ -132,6 +110,7 @@ mod generic { let key_shares = simulation .run() .unwrap() + .into_vec() .into_iter() .collect::, _>>() .unwrap(); diff --git a/tests/tests/it/pipeline.rs b/tests/tests/it/pipeline.rs index a50c708..6a4396f 100644 --- a/tests/tests/it/pipeline.rs +++ b/tests/tests/it/pipeline.rs @@ -3,32 +3,28 @@ mod generic { use generic_ec::{Curve, Point}; use rand::{seq::SliceRandom, Rng, RngCore}; use rand_dev::DevRng; - use round_based::simulation::Simulation; use sha2::Sha256; use cggmp21::{ key_share::{AnyKeyShare, IncompleteKeyShare, KeyShare}, - keygen::ThresholdMsg, - security_level::SecurityLevel128, ExecutionId, }; #[test_case::case(2, 3, false; "t2n3")] #[test_case::case(3, 5, false; "t3n5")] #[cfg_attr(feature = "hd-wallet", test_case::case(3, 5, true; "t3n5-hd"))] - #[tokio::test] - async fn full_pipeline_works(t: u16, n: u16, hd_enabled: bool) + fn full_pipeline_works(t: u16, n: u16, hd_enabled: bool) where E: Curve + cggmp21_tests::CurveParams, Point: generic_ec::coords::HasAffineX, { let mut rng = DevRng::new(); - let incomplete_shares = run_keygen(t, n, hd_enabled, &mut rng).await; - let shares = run_aux_gen(incomplete_shares, &mut rng).await; - run_signing(&shares, hd_enabled, &mut rng).await; + let incomplete_shares = run_keygen(t, n, hd_enabled, &mut rng); + let shares = run_aux_gen(incomplete_shares, &mut rng); + run_signing(&shares, hd_enabled, &mut rng); } - async fn run_keygen( + fn run_keygen( t: u16, n: u16, hd_enabled: bool, @@ -40,49 +36,37 @@ mod generic { #[cfg(not(feature = "hd-wallet"))] assert!(!hd_enabled); - let mut simulation = Simulation::>::new(); - let eid: [u8; 32] = rng.gen(); let eid = ExecutionId::new(&eid); - let mut outputs = vec![]; - for i in 0..n { - let party = simulation.add_party(); + round_based::simulation::run(n, |i, party| { let mut party_rng = rng.fork(); - outputs.push(async move { + async move { let keygen = cggmp21::keygen(eid, i, n).set_threshold(t); #[cfg(feature = "hd-wallet")] let keygen = keygen.hd_wallet(hd_enabled); keygen.start(&mut party_rng, party).await - }) - } - - futures::future::try_join_all(outputs) - .await - .expect("keygen failed") + } + }) + .unwrap() + .expect_ok() + .into_vec() } - async fn run_aux_gen( - shares: Vec>, - rng: &mut DevRng, - ) -> Vec> + fn run_aux_gen(shares: Vec>, rng: &mut DevRng) -> Vec> where E: Curve, { let mut primes = cggmp21_tests::CACHED_PRIMES.iter(); let n = shares.len().try_into().unwrap(); - let mut simulation = - Simulation::>::new(); - let eid: [u8; 32] = rng.gen(); let eid = ExecutionId::new(&eid); - let outputs = (0..n).map(|i| { - let party = simulation.add_party(); + let aux_infos = round_based::simulation::run(n, |i, party| { let mut party_rng = rng.fork(); let pregenerated_data = primes.next().expect("Can't fetch primes"); async move { @@ -90,11 +74,10 @@ mod generic { .start(&mut party_rng, party) .await } - }); - - let aux_infos = futures::future::try_join_all(outputs) - .await - .expect("keygen failed"); + }) + .unwrap() + .expect_ok() + .into_vec(); shares .into_iter() @@ -105,7 +88,7 @@ mod generic { .collect() } - async fn run_signing(shares: &[KeyShare], random_derivation_path: bool, rng: &mut DevRng) + fn run_signing(shares: &[KeyShare], random_derivation_path: bool, rng: &mut DevRng) where E: Curve + cggmp21_tests::CurveParams, Point: generic_ec::coords::HasAffineX, @@ -123,8 +106,6 @@ mod generic { None }; - let mut simulation = Simulation::>::new(); - let eid: [u8; 32] = rng.gen(); let eid = ExecutionId::new(&eid); @@ -140,33 +121,31 @@ mod generic { println!("Signers: {participants:?}"); let participants_shares = participants.iter().map(|i| &shares[usize::from(*i)]); - let mut outputs = vec![]; - for (i, share) in (0..).zip(participants_shares) { - let party = simulation.add_party(); - let mut party_rng = rng.fork(); - - #[cfg(feature = "hd-wallet")] - let derivation_path = derivation_path.clone(); - - outputs.push(async move { - let signing = cggmp21::signing(eid, i, participants, share); + let sig = + round_based::simulation::run_with_setup(participants_shares, |i, party, share| { + let mut party_rng = rng.fork(); #[cfg(feature = "hd-wallet")] - let signing = if let Some(derivation_path) = derivation_path { - signing - .set_derivation_path_with_algo::(derivation_path) - .unwrap() - } else { - signing - }; - - signing.sign(&mut party_rng, party, message_to_sign).await - }); - } - - let signatures = futures::future::try_join_all(outputs) - .await - .expect("signing failed"); + let derivation_path = derivation_path.clone(); + + async move { + let signing = cggmp21::signing(eid, i, participants, share); + + #[cfg(feature = "hd-wallet")] + let signing = if let Some(derivation_path) = derivation_path { + signing + .set_derivation_path_with_algo::(derivation_path) + .unwrap() + } else { + signing + }; + + signing.sign(&mut party_rng, party, message_to_sign).await + } + }) + .unwrap() + .expect_ok() + .expect_eq(); #[cfg(feature = "hd-wallet")] let public_key = if let Some(path) = &derivation_path { @@ -183,11 +162,8 @@ mod generic { #[cfg(not(feature = "hd-wallet"))] let public_key = shares[0].shared_public_key; - signatures[0] - .verify(&public_key, &message_to_sign) + sig.verify(&public_key, &message_to_sign) .expect("signature is not valid"); - - assert!(signatures.iter().all(|s_i| signatures[0] == *s_i)); } #[instantiate_tests()] diff --git a/tests/tests/it/signing.rs b/tests/tests/it/signing.rs index 0a6af3b..54142e3 100644 --- a/tests/tests/it/signing.rs +++ b/tests/tests/it/signing.rs @@ -5,15 +5,14 @@ use generic_ec::{coords::HasAffineX, Curve, Point}; use rand::seq::SliceRandom; use rand::{Rng, RngCore}; use rand_dev::DevRng; -use round_based::simulation::{Simulation, SimulationSync}; use sha2::Sha256; use cggmp21::key_share::AnyKeyShare; -use cggmp21::signing::{msg::Msg, DataToSign}; +use cggmp21::signing::DataToSign; use cggmp21::{security_level::SecurityLevel128, ExecutionId}; cggmp21_tests::test_suite! { - async_test = signing_works, + test = signing_works, generics = all_curves, suites = [ n2(None, 2, false, false), @@ -32,7 +31,7 @@ cggmp21_tests::test_suite! { ] } -async fn signing_works(t: Option, n: u16, reliable_broadcast: bool, hd_wallet: bool) +fn signing_works(t: Option, n: u16, reliable_broadcast: bool, hd_wallet: bool) where E: Curve + cggmp21_tests::CurveParams, Point: HasAffineX, @@ -46,8 +45,6 @@ where .get_shares::(t, n, hd_wallet) .expect("retrieve cached shares"); - let mut simulation = Simulation::>::new(); - let eid: [u8; 32] = rng.gen(); let eid = ExecutionId::new(&eid); @@ -70,34 +67,26 @@ where println!("Signers: {participants:?}"); let participants_shares = participants.iter().map(|i| &shares[usize::from(*i)]); - let mut outputs = vec![]; - for (i, share) in (0..).zip(participants_shares) { - let party = simulation.add_party(); + let sig = round_based::simulation::run_with_setup(participants_shares, |i, party, share| { let mut party_rng = rng.fork(); - #[cfg(feature = "hd-wallet")] - let derivation_path = derivation_path.clone(); - - outputs.push(async move { - let signing = cggmp21::signing(eid, i, participants, share) - .enforce_reliable_broadcast(reliable_broadcast); + let signing = cggmp21::signing(eid, i, participants, share) + .enforce_reliable_broadcast(reliable_broadcast); - #[cfg(feature = "hd-wallet")] - let signing = if let Some(derivation_path) = derivation_path { - signing - .set_derivation_path_with_algo::(derivation_path) - .unwrap() - } else { - signing - }; - - signing.sign(&mut party_rng, party, message_to_sign).await - }); - } + #[cfg(feature = "hd-wallet")] + let signing = if let Some(derivation_path) = derivation_path.clone() { + signing + .set_derivation_path_with_algo::(derivation_path) + .unwrap() + } else { + signing + }; - let signatures = futures::future::try_join_all(outputs) - .await - .expect("signing failed"); + async move { signing.sign(&mut party_rng, party, message_to_sign).await } + }) + .unwrap() + .expect_ok() + .expect_eq(); #[cfg(feature = "hd-wallet")] let public_key = if let Some(path) = &derivation_path { @@ -114,18 +103,15 @@ where #[cfg(not(feature = "hd-wallet"))] let public_key = shares[0].shared_public_key; - signatures[0] - .verify(&public_key, &message_to_sign) + sig.verify(&public_key, &message_to_sign) .expect("signature is not valid"); - assert!(signatures.iter().all(|s_i| signatures[0] == *s_i)); - - E::ExVerifier::verify(&public_key, &signatures[0], &original_message_to_sign) + E::ExVerifier::verify(&public_key, &sig, &original_message_to_sign) .expect("external verification failed") } cggmp21_tests::test_suite! { - async_test = signing_with_presigs, + test = signing_with_presigs, generics = all_curves, suites = [ t3n5(Some(3), 5, false), @@ -134,7 +120,7 @@ cggmp21_tests::test_suite! { ] } -async fn signing_with_presigs(t: Option, n: u16, hd_wallet: bool) +fn signing_with_presigs(t: Option, n: u16, hd_wallet: bool) where E: Curve + cggmp21_tests::CurveParams, Point: HasAffineX, @@ -148,8 +134,6 @@ where .get_shares::(t, n, hd_wallet) .expect("retrieve cached shares"); - let mut simulation = Simulation::>::new(); - let eid: [u8; 32] = rng.gen(); let eid = ExecutionId::new(&eid); @@ -162,21 +146,19 @@ where let participants_shares = participants.iter().map(|i| &shares[usize::from(*i)]); - let mut outputs = vec![]; - for (i, share) in (0..).zip(participants_shares) { - let party = simulation.add_party(); - let mut party_rng = rng.fork(); - - outputs.push(async move { - cggmp21::signing(eid, i, participants, share) - .generate_presignature(&mut party_rng, party) - .await - }); - } + let presigs = + round_based::simulation::run_with_setup(participants_shares, |i, party, share| { + let mut party_rng = rng.fork(); - let presignatures = futures::future::try_join_all(outputs) - .await - .expect("signing failed"); + async move { + cggmp21::signing(eid, i, participants, share) + .generate_presignature(&mut party_rng, party) + .await + } + }) + .unwrap() + .expect_ok() + .into_vec(); // Now, that we have presignatures generated, we learn (generate) a messages to sign // and the derivation path (if hd is enabled) @@ -191,7 +173,7 @@ where None }; - let partial_signatures = presignatures + let partial_signatures = presigs .into_iter() .map(|presig| { #[cfg(feature = "hd-wallet")] @@ -289,7 +271,7 @@ where .take(n.into()) .collect::>(); - let mut simulation = SimulationSync::with_capacity(n); + let mut simulation = round_based::simulation::Simulation::with_capacity(n); for ((i, share), signer_rng) in (0..).zip(participants_shares).zip(&mut signer_rng) { simulation.add_party({ @@ -308,12 +290,7 @@ where }) } - let signatures = simulation - .run() - .unwrap() - .into_iter() - .collect::, _>>() - .unwrap(); + let sig = simulation.run().unwrap().expect_ok().expect_eq(); #[cfg(feature = "hd-wallet")] let public_key = if let Some(path) = &derivation_path { @@ -330,12 +307,9 @@ where #[cfg(not(feature = "hd-wallet"))] let public_key = shares[0].shared_public_key; - signatures[0] - .verify(&public_key, &message_to_sign) + sig.verify(&public_key, &message_to_sign) .expect("signature is not valid"); - assert!(signatures.iter().all(|s_i| signatures[0] == *s_i)); - - E::ExVerifier::verify(&public_key, &signatures[0], &original_message_to_sign) + E::ExVerifier::verify(&public_key, &sig, &original_message_to_sign) .expect("external verification failed") } diff --git a/tests/tests/it/stark_prehashed.rs b/tests/tests/it/stark_prehashed.rs index 410a0e2..dcc3aab 100644 --- a/tests/tests/it/stark_prehashed.rs +++ b/tests/tests/it/stark_prehashed.rs @@ -1,13 +1,11 @@ -use cggmp21::{key_share::AnyKeyShare, security_level::SecurityLevel128, signing::msg::Msg}; +use cggmp21::{key_share::AnyKeyShare, security_level::SecurityLevel128}; use cggmp21_tests::{convert_from_stark_scalar, convert_stark_scalar}; use generic_ec::{coords::HasAffineX, curves::Stark}; use rand::{seq::SliceRandom, Rng}; use rand_dev::DevRng; -use round_based::simulation::Simulation; -use sha2::Sha256; -#[tokio::test] -async fn sign_transaction() { +#[test] +fn sign_transaction() { let mut rng = DevRng::new(); let t = Some(2); let n = 3; @@ -16,8 +14,6 @@ async fn sign_transaction() { .get_shares::(t, n, false) .expect("retrieve cached shares"); - let mut simulation = Simulation::>::new(); - let eid: [u8; 32] = rng.gen(); let eid = cggmp21::ExecutionId::new(&eid); @@ -74,33 +70,28 @@ async fn sign_transaction() { println!("Signers: {participants:?}"); let participants_shares = participants.iter().map(|i| &shares[usize::from(*i)]); - let mut outputs = vec![]; - for (i, share) in (0..).zip(participants_shares) { - let party = simulation.add_party(); + let sig = round_based::simulation::run_with_setup(participants_shares, |i, party, share| { let mut party_rng = rng.fork(); - outputs.push(async move { + async move { cggmp21::signing(eid, i, participants, share) .sign(&mut party_rng, party, cggmp_transaction_hash) .await - }); - } - - let signatures = futures::future::try_join_all(outputs) - .await - .expect("signing failed"); + } + }) + .unwrap() + .expect_ok() + .expect_eq(); // verify with our lib - signatures[0] - .verify(&shares[0].core.shared_public_key, &cggmp_transaction_hash) + sig.verify(&shares[0].core.shared_public_key, &cggmp_transaction_hash) .expect("signature is not valid"); - assert!(signatures.iter().all(|s_i| signatures[0] == *s_i)); // verify with starknet lib let public_key_x = shares[0].core.shared_public_key.x().unwrap().to_scalar(); let public_key = convert_stark_scalar(&public_key_x).unwrap(); - let r = convert_stark_scalar(&signatures[0].r).unwrap(); - let s = convert_stark_scalar(&signatures[0].s).unwrap(); + let r = convert_stark_scalar(&sig.r).unwrap(); + let s = convert_stark_scalar(&sig.s).unwrap(); let r = starknet_crypto::verify(&public_key, &transaction_hash, &r, &s).unwrap(); assert!(r, "failed to verify signature"); From 5ce7126c3edf7553b5653c48c36aa7eb3e9d2492 Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Wed, 27 Nov 2024 16:48:08 +0100 Subject: [PATCH 13/19] Migrate all tests to use the new macro Signed-off-by: Denis Varlakov --- Cargo.lock | 39 +--- tests/Cargo.toml | 4 - tests/tests/it/key_refresh.rs | 363 ++++++++++++++++--------------- tests/tests/it/keygen.rs | 303 ++++++++++++++------------ tests/tests/it/pipeline.rs | 326 ++++++++++++++------------- tests/tests/it/trusted_dealer.rs | 132 ++++++----- 6 files changed, 565 insertions(+), 602 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9df0848..649b6ab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -325,7 +325,6 @@ dependencies = [ "ciborium", "futures", "generic-ec", - "generic-tests", "hex", "include_dir", "lazy_static", @@ -341,7 +340,6 @@ dependencies = [ "starknet-crypto", "starknet-providers", "starknet-signers", - "test-case", "url", ] @@ -1815,7 +1813,7 @@ dependencies = [ [[package]] name = "round-based" version = "0.4.0" -source = "git+https://github.com/LFDT-Lockness/round-based?branch=impr-sim#e662e7142eb3c5d96f3202c6cc7f853a2db0486b" +source = "git+https://github.com/LFDT-Lockness/round-based?branch=impr-sim#687132f4e29f51b0d29405174c6e7485c303451f" dependencies = [ "displaydoc", "futures-util", @@ -1828,7 +1826,7 @@ dependencies = [ [[package]] name = "round-based-derive" version = "0.2.2" -source = "git+https://github.com/LFDT-Lockness/round-based?branch=impr-sim#e662e7142eb3c5d96f3202c6cc7f853a2db0486b" +source = "git+https://github.com/LFDT-Lockness/round-based?branch=impr-sim#687132f4e29f51b0d29405174c6e7485c303451f" dependencies = [ "proc-macro2", "quote", @@ -2326,39 +2324,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "test-case" -version = "3.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb2550dd13afcd286853192af8601920d959b14c401fcece38071d53bf0768a8" -dependencies = [ - "test-case-macros", -] - -[[package]] -name = "test-case-core" -version = "3.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcb7fd841cd518e279be3d5a3eb0636409487998a4aff22f3de87b81e88384f" -dependencies = [ - "cfg-if", - "proc-macro2", - "quote", - "syn 2.0.32", -] - -[[package]] -name = "test-case-macros" -version = "3.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.32", - "test-case-core", -] - [[package]] name = "thiserror" version = "1.0.48" diff --git a/tests/Cargo.toml b/tests/Cargo.toml index 3efa9bb..4d49453 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -39,10 +39,6 @@ starknet-providers = { version = "0.6" } starknet-signers = { version = "0.4" } url = "2.4" -[dev-dependencies] -generic-tests = "0.1" -test-case = "3" - [features] hd-wallet = ["cggmp21/hd-wallet", "cggmp21/hd-slip10", "cggmp21/hd-stark"] diff --git a/tests/tests/it/key_refresh.rs b/tests/tests/it/key_refresh.rs index 46c5b30..d2af2d6 100644 --- a/tests/tests/it/key_refresh.rs +++ b/tests/tests/it/key_refresh.rs @@ -1,195 +1,196 @@ -#[generic_tests::define(attrs(tokio::test, test_case::case))] -mod generic { - use generic_ec::Point; - use rand::seq::SliceRandom; - use rand::Rng; - use sha2::Sha256; - - use cggmp21::{ - key_share::{DirtyKeyShare, Validate}, - security_level::SecurityLevel128, - ExecutionId, - }; - - #[test_case::case(3, false; "n3")] - #[test_case::case(5, false; "n5")] - #[test_case::case(5, true; "n5-reliable")] - fn key_refresh_works(n: u16, reliable_broadcast: bool) - where - Point: generic_ec::coords::HasAffineX, - { - let mut rng = rand_dev::DevRng::new(); - - let shares = cggmp21_tests::CACHED_SHARES - .get_shares::(None, n, true) - .expect("retrieve cached shares"); - - #[cfg(feature = "hd-wallet")] - assert!(shares[0].chain_code.is_some()); - - let mut primes = cggmp21_tests::CACHED_PRIMES.iter::(); - - // Perform refresh - - let eid: [u8; 32] = rng.gen(); - let eid = ExecutionId::new(&eid); - - let key_shares = round_based::simulation::run_with_setup(&shares, |_i, party, share| { - let mut party_rng = rng.fork(); - let pregenerated_data = primes.next().expect("Can't fetch primes"); - async move { - cggmp21::key_refresh(eid, share, pregenerated_data) - .enforce_reliable_broadcast(reliable_broadcast) - .start(&mut party_rng, party) - .await - } - }) - .unwrap() - .expect_ok() - .into_vec(); - - // validate key shares - - for (i, key_share) in key_shares.iter().enumerate() { - let i = i as u16; - assert_eq!(i, key_share.core.i); - assert_eq!( - key_share.core.shared_public_key, - key_shares[0].core.shared_public_key - ); - assert_eq!( - key_share.core.public_shares, - key_shares[0].core.public_shares - ); - assert_eq!( - Point::::generator() * &key_share.core.x, - key_share.core.public_shares[usize::from(i)] - ); +use generic_ec::Point; +use rand::seq::SliceRandom; +use rand::Rng; +use sha2::Sha256; + +use cggmp21::{ + key_share::{DirtyKeyShare, Validate}, + security_level::SecurityLevel128, + ExecutionId, +}; + +cggmp21_tests::test_suite! { + test = key_refresh_works, + generics = all_curves, + suites = [ + n3(3, false), + n5(5, false), + n5_reliable(5, true), + ] +} +fn key_refresh_works(n: u16, reliable_broadcast: bool) +where + Point: generic_ec::coords::HasAffineX, +{ + let mut rng = rand_dev::DevRng::new(); + + let shares = cggmp21_tests::CACHED_SHARES + .get_shares::(None, n, true) + .expect("retrieve cached shares"); + + #[cfg(feature = "hd-wallet")] + assert!(shares[0].chain_code.is_some()); + + let mut primes = cggmp21_tests::CACHED_PRIMES.iter::(); + + // Perform refresh + + let eid: [u8; 32] = rng.gen(); + let eid = ExecutionId::new(&eid); + + let key_shares = round_based::simulation::run_with_setup(&shares, |_i, party, share| { + let mut party_rng = rng.fork(); + let pregenerated_data = primes.next().expect("Can't fetch primes"); + async move { + cggmp21::key_refresh(eid, share, pregenerated_data) + .enforce_reliable_broadcast(reliable_broadcast) + .start(&mut party_rng, party) + .await } + }) + .unwrap() + .expect_ok() + .into_vec(); + + // validate key shares + + for (i, key_share) in key_shares.iter().enumerate() { + let i = i as u16; + assert_eq!(i, key_share.core.i); assert_eq!( - key_shares[0].core.shared_public_key, - key_shares[0].core.public_shares.iter().sum::>() + key_share.core.shared_public_key, + key_shares[0].core.shared_public_key ); - for key_share in &key_shares { - assert_eq!( - key_share.core.shared_public_key, - shares[0].core.shared_public_key - ); - } + assert_eq!( + key_share.core.public_shares, + key_shares[0].core.public_shares + ); + assert_eq!( + Point::::generator() * &key_share.core.x, + key_share.core.public_shares[usize::from(i)] + ); + } + assert_eq!( + key_shares[0].core.shared_public_key, + key_shares[0].core.public_shares.iter().sum::>() + ); + for key_share in &key_shares { + assert_eq!( + key_share.core.shared_public_key, + shares[0].core.shared_public_key + ); + } - #[cfg(feature = "hd-wallet")] - for key_share in &key_shares { - assert_eq!(key_share.chain_code, shares[0].chain_code); - } + #[cfg(feature = "hd-wallet")] + for key_share in &key_shares { + assert_eq!(key_share.chain_code, shares[0].chain_code); + } - // attempt to sign with new shares and verify the signature + // attempt to sign with new shares and verify the signature - let eid: [u8; 32] = rng.gen(); - let eid = ExecutionId::new(&eid); + let eid: [u8; 32] = rng.gen(); + let eid = ExecutionId::new(&eid); - let message_to_sign = cggmp21::signing::DataToSign::digest::(&[42; 100]); - let participants = &(0..n).collect::>(); - let sig = round_based::simulation::run_with_setup(&key_shares, |_i, party, share| { - let mut party_rng = rng.fork(); - async move { - cggmp21::signing(eid, share.core.i, participants, share) - .enforce_reliable_broadcast(reliable_broadcast) - .sign(&mut party_rng, party, message_to_sign) - .await - } - }) - .unwrap() - .expect_ok() - .expect_eq(); + let message_to_sign = cggmp21::signing::DataToSign::digest::(&[42; 100]); + let participants = &(0..n).collect::>(); + let sig = round_based::simulation::run_with_setup(&key_shares, |_i, party, share| { + let mut party_rng = rng.fork(); + async move { + cggmp21::signing(eid, share.core.i, participants, share) + .enforce_reliable_broadcast(reliable_broadcast) + .sign(&mut party_rng, party, message_to_sign) + .await + } + }) + .unwrap() + .expect_ok() + .expect_eq(); - sig.verify(&key_shares[0].core.shared_public_key, &message_to_sign) - .expect("signature is not valid"); - } + sig.verify(&key_shares[0].core.shared_public_key, &message_to_sign) + .expect("signature is not valid"); +} - #[test_case::case(2, 3, false; "t2n3")] - #[test_case::case(3, 5, false; "t3n5")] - #[test_case::case(3, 5, true; "t3n5-reliable")] - fn aux_gen_works(t: u16, n: u16, reliable_broadcast: bool) - where - Point: generic_ec::coords::HasAffineX, - { - let mut rng = rand_dev::DevRng::new(); - - let shares = cggmp21_tests::CACHED_SHARES - .get_shares::(Some(t), n, false) - .expect("retrieve cached shares"); - let mut primes = cggmp21_tests::CACHED_PRIMES.iter::(); - - // Perform refresh - - let eid: [u8; 32] = rng.gen(); - let eid = ExecutionId::new(&eid); - - let aux_infos = round_based::simulation::run(n, |i, party| { - let mut party_rng = rng.fork(); - let pregenerated_data = primes.next().expect("Can't fetch primes"); - async move { - cggmp21::aux_info_gen(eid, i, n, pregenerated_data) - .enforce_reliable_broadcast(reliable_broadcast) - .start(&mut party_rng, party) - .await +cggmp21_tests::test_suite! { + test = aux_gen_works, + generics = all_curves, + suites = [ + t2n3(2, 3, false), + t3n5(3, 5, false), + t3n5_reliable(3, 5, true), + ] +} +fn aux_gen_works(t: u16, n: u16, reliable_broadcast: bool) +where + Point: generic_ec::coords::HasAffineX, +{ + let mut rng = rand_dev::DevRng::new(); + + let shares = cggmp21_tests::CACHED_SHARES + .get_shares::(Some(t), n, false) + .expect("retrieve cached shares"); + let mut primes = cggmp21_tests::CACHED_PRIMES.iter::(); + + // Perform refresh + + let eid: [u8; 32] = rng.gen(); + let eid = ExecutionId::new(&eid); + + let aux_infos = round_based::simulation::run(n, |i, party| { + let mut party_rng = rng.fork(); + let pregenerated_data = primes.next().expect("Can't fetch primes"); + async move { + cggmp21::aux_info_gen(eid, i, n, pregenerated_data) + .enforce_reliable_broadcast(reliable_broadcast) + .start(&mut party_rng, party) + .await + } + }) + .unwrap() + .expect_ok() + .into_vec(); + + // validate key shares + + let key_shares = shares + .into_iter() + .zip(aux_infos.into_iter()) + .map(|(share, aux)| { + DirtyKeyShare { + core: share.into_inner().core, + aux: aux.into_inner(), } - }) - .unwrap() - .expect_ok() - .into_vec(); - - // validate key shares - - let key_shares = shares - .into_iter() - .zip(aux_infos.into_iter()) - .map(|(share, aux)| { - DirtyKeyShare { - core: share.into_inner().core, - aux: aux.into_inner(), - } - .validate() - .unwrap() - }) - .collect::>(); - - // attempt to sign with new shares and verify the signature - - let eid: [u8; 32] = rng.gen(); - let eid = ExecutionId::new(&eid); - - let message_to_sign = cggmp21::signing::DataToSign::digest::(&[42; 100]); - - // choose t participants - let mut participants = (0..n).collect::>(); - participants.shuffle(&mut rng); - let participants = &participants[..usize::from(t)]; - println!("Signers: {participants:?}"); - let participants_shares = participants.iter().map(|i| &key_shares[usize::from(*i)]); - - let sig = - round_based::simulation::run_with_setup(participants_shares, |i, party, share| { - let mut party_rng = rng.fork(); - async move { - cggmp21::signing(eid, i, participants, share) - .enforce_reliable_broadcast(reliable_broadcast) - .sign(&mut party_rng, party, message_to_sign) - .await - } - }) + .validate() .unwrap() - .expect_ok() - .expect_eq(); + }) + .collect::>(); - sig.verify(&key_shares[0].core.shared_public_key, &message_to_sign) - .expect("signature is not valid"); - } + // attempt to sign with new shares and verify the signature + + let eid: [u8; 32] = rng.gen(); + let eid = ExecutionId::new(&eid); + + let message_to_sign = cggmp21::signing::DataToSign::digest::(&[42; 100]); + + // choose t participants + let mut participants = (0..n).collect::>(); + participants.shuffle(&mut rng); + let participants = &participants[..usize::from(t)]; + println!("Signers: {participants:?}"); + let participants_shares = participants.iter().map(|i| &key_shares[usize::from(*i)]); + + let sig = round_based::simulation::run_with_setup(participants_shares, |i, party, share| { + let mut party_rng = rng.fork(); + async move { + cggmp21::signing(eid, i, participants, share) + .enforce_reliable_broadcast(reliable_broadcast) + .sign(&mut party_rng, party, message_to_sign) + .await + } + }) + .unwrap() + .expect_ok() + .expect_eq(); - #[instantiate_tests()] - mod secp256r1 {} - #[instantiate_tests()] - mod secp256k1 {} - #[instantiate_tests()] - mod stark {} + sig.verify(&key_shares[0].core.shared_public_key, &message_to_sign) + .expect("signature is not valid"); } diff --git a/tests/tests/it/keygen.rs b/tests/tests/it/keygen.rs index 6ea83e1..cc77e9d 100644 --- a/tests/tests/it/keygen.rs +++ b/tests/tests/it/keygen.rs @@ -1,167 +1,182 @@ -#[generic_tests::define(attrs(tokio::test, test_case::case, cfg_attr))] -mod generic { - use std::iter; - - use generic_ec::{Curve, Point}; - use rand::{seq::SliceRandom, Rng}; - use rand_dev::DevRng; - - use cggmp21::{key_share::reconstruct_secret_key, ExecutionId}; - - #[test_case::case(3, false, false; "n3")] - #[test_case::case(5, false, false; "n5")] - #[test_case::case(7, false, false; "n7")] - #[test_case::case(10, false, false; "n10")] - #[test_case::case(10, true, false; "n10-reliable")] - #[cfg_attr(feature = "hd-wallet", test_case::case(3, false, true; "n3-hd"))] - #[cfg_attr(feature = "hd-wallet", test_case::case(5, false, true; "n5-hd"))] - #[cfg_attr(feature = "hd-wallet", test_case::case(7, false, true; "n7-hd"))] - #[cfg_attr(feature = "hd-wallet", test_case::case(10, false, true; "n10-hd"))] - fn keygen_works(n: u16, reliable_broadcast: bool, hd_wallet: bool) { - #[cfg(not(feature = "hd-wallet"))] - assert!(!hd_wallet); - - let mut rng = DevRng::new(); - - let eid: [u8; 32] = rng.gen(); - let eid = ExecutionId::new(&eid); - - let key_shares = round_based::simulation::run(n, |i, party| { - let mut party_rng = rng.fork(); - - async move { - let keygen = - cggmp21::keygen::(eid, i, n).enforce_reliable_broadcast(reliable_broadcast); - - #[cfg(feature = "hd-wallet")] - let keygen = keygen.hd_wallet(hd_wallet); - - keygen.start(&mut party_rng, party).await - } - }) - .unwrap() - .expect_ok() - .into_vec(); - - validate_keygen_output(&mut rng, &key_shares, hd_wallet); - } - - #[test_case::case(2, 3, false, false; "t2n3")] - #[test_case::case(3, 5, false, false; "t3n5")] - #[test_case::case(3, 5, true, false; "t3n5-reliable")] - #[cfg_attr(feature = "hd-wallet", test_case::case(2, 3, false, true; "t2n3-hd"))] - #[cfg_attr(feature = "hd-wallet", test_case::case(3, 5, false, true; "t3n5-hd"))] - fn threshold_keygen_works(t: u16, n: u16, reliable_broadcast: bool, hd_wallet: bool) { - #[cfg(not(feature = "hd-wallet"))] - assert!(!hd_wallet); +use std::iter; + +use generic_ec::{Curve, Point}; +use rand::{seq::SliceRandom, Rng}; +use rand_dev::DevRng; + +use cggmp21::{key_share::reconstruct_secret_key, ExecutionId}; + +cggmp21_tests::test_suite! { + test = keygen_works, + generics = all_curves, + suites = [ + n3(3, false, false), + n5(5, false, false), + n7(7, false, false), + n10(10, false, false), + n10_reliable(10, true, false), + #[cfg(feature = "hd-wallet")] + n3_hd(3, false, true), + #[cfg(feature = "hd-wallet")] + n5_hd(5, false, true), + #[cfg(feature = "hd-wallet")] + n7_hd(7, false, true), + #[cfg(feature = "hd-wallet")] + n10_hd(10, false, true), + ] +} +fn keygen_works(n: u16, reliable_broadcast: bool, hd_wallet: bool) { + #[cfg(not(feature = "hd-wallet"))] + assert!(!hd_wallet); - let mut rng = DevRng::new(); + let mut rng = DevRng::new(); - let eid: [u8; 32] = rng.gen(); - let eid = ExecutionId::new(&eid); + let eid: [u8; 32] = rng.gen(); + let eid = ExecutionId::new(&eid); - let key_shares = round_based::simulation::run(n, |i, party| { - let mut party_rng = rng.fork(); + let key_shares = round_based::simulation::run(n, |i, party| { + let mut party_rng = rng.fork(); - async move { - let keygen = cggmp21::keygen::(eid, i, n) - .enforce_reliable_broadcast(reliable_broadcast) - .set_threshold(t); + async move { + let keygen = + cggmp21::keygen::(eid, i, n).enforce_reliable_broadcast(reliable_broadcast); - #[cfg(feature = "hd-wallet")] - let keygen = keygen.hd_wallet(hd_wallet); + #[cfg(feature = "hd-wallet")] + let keygen = keygen.hd_wallet(hd_wallet); - keygen.start(&mut party_rng, party).await - } - }) - .unwrap() - .expect_ok() - .into_vec(); + keygen.start(&mut party_rng, party).await + } + }) + .unwrap() + .expect_ok() + .into_vec(); - validate_keygen_output(&mut rng, &key_shares, hd_wallet); - } + validate_keygen_output(&mut rng, &key_shares, hd_wallet); +} - #[test_case::case(3, 5, false; "t3n5")] - #[cfg_attr(feature = "hd-wallet", test_case::case(3, 5, true; "t3n5-hd"))] - fn threshold_keygen_sync_works(t: u16, n: u16, hd_wallet: bool) { - #[cfg(not(feature = "hd-wallet"))] - assert!(!hd_wallet); +cggmp21_tests::test_suite! { + test = threshold_keygen_works, + generics = all_curves, + suites = [ + t2n3(2, 3, false, false), + t3n5(3, 5, false, false), + t3n5_reliable(3, 5, true, false), + #[cfg(feature = "hd-wallet")] + t2n3_hd(2, 3, false, true), + #[cfg(feature = "hd-wallet")] + t3n5_hd(3, 5, false, true), + ] +} +fn threshold_keygen_works(t: u16, n: u16, reliable_broadcast: bool, hd_wallet: bool) { + #[cfg(not(feature = "hd-wallet"))] + assert!(!hd_wallet); - let mut rng = DevRng::new(); + let mut rng = DevRng::new(); - let eid: [u8; 32] = rng.gen(); - let eid = ExecutionId::new(&eid); + let eid: [u8; 32] = rng.gen(); + let eid = ExecutionId::new(&eid); - let mut party_rng = iter::repeat_with(|| rng.fork()) - .take(n.into()) - .collect::>(); + let key_shares = round_based::simulation::run(n, |i, party| { + let mut party_rng = rng.fork(); - let mut simulation = round_based::simulation::Simulation::with_capacity(n); - for (i, party_rng) in (0..).zip(&mut party_rng) { - simulation.add_party({ - let keygen = cggmp21::keygen::(eid, i, n).set_threshold(t); + async move { + let keygen = cggmp21::keygen::(eid, i, n) + .enforce_reliable_broadcast(reliable_broadcast) + .set_threshold(t); - #[cfg(feature = "hd-wallet")] - let keygen = keygen.hd_wallet(hd_wallet); + #[cfg(feature = "hd-wallet")] + let keygen = keygen.hd_wallet(hd_wallet); - keygen.into_state_machine(party_rng) - }) + keygen.start(&mut party_rng, party).await } - let key_shares = simulation - .run() - .unwrap() - .into_vec() - .into_iter() - .collect::, _>>() - .unwrap(); - validate_keygen_output(&mut rng, &key_shares, hd_wallet); - } + }) + .unwrap() + .expect_ok() + .into_vec(); - fn validate_keygen_output( - rng: &mut impl rand::RngCore, - key_shares: &[cggmp21::IncompleteKeyShare], - hd_wallet: bool, - ) { - #[cfg(not(feature = "hd-wallet"))] - assert!(!hd_wallet); - - for (i, key_share) in (0u16..).zip(key_shares) { - assert_eq!(key_share.i, i); - assert_eq!(key_share.shared_public_key, key_shares[0].shared_public_key); - assert_eq!(key_share.public_shares, key_shares[0].public_shares); - assert_eq!( - Point::::generator() * &key_share.x, - key_share.public_shares[usize::from(i)] - ); - } + validate_keygen_output(&mut rng, &key_shares, hd_wallet); +} +cggmp21_tests::test_suite! { + test = threshold_keygen_sync_works, + generics = all_curves, + suites = [ + t3n5(3, 5, false), #[cfg(feature = "hd-wallet")] - if hd_wallet { - assert!(key_shares[0].chain_code.is_some()); - for key_share in &key_shares[1..] { - assert_eq!(key_share.chain_code, key_shares[0].chain_code); - } - } else { - for key_share in key_shares { - assert_eq!(key_share.chain_code, None); - } - } + t3n5_hd(3, 5, true), + ] +} +fn threshold_keygen_sync_works(t: u16, n: u16, hd_wallet: bool) { + #[cfg(not(feature = "hd-wallet"))] + assert!(!hd_wallet); + + let mut rng = DevRng::new(); + + let eid: [u8; 32] = rng.gen(); + let eid = ExecutionId::new(&eid); + + let mut party_rng = iter::repeat_with(|| rng.fork()) + .take(n.into()) + .collect::>(); + + let mut simulation = round_based::simulation::Simulation::with_capacity(n); + for (i, party_rng) in (0..).zip(&mut party_rng) { + simulation.add_party({ + let keygen = cggmp21::keygen::(eid, i, n).set_threshold(t); + + #[cfg(feature = "hd-wallet")] + let keygen = keygen.hd_wallet(hd_wallet); - // Choose `t` random key shares and reconstruct a secret key - let t = key_shares[0].min_signers(); - let t_shares = key_shares - .choose_multiple(rng, t.into()) - .cloned() - .collect::>(); + keygen.into_state_machine(party_rng) + }) + } + let key_shares = simulation + .run() + .unwrap() + .into_vec() + .into_iter() + .collect::, _>>() + .unwrap(); + validate_keygen_output(&mut rng, &key_shares, hd_wallet); +} - let sk = reconstruct_secret_key(&t_shares).unwrap(); - assert_eq!(Point::generator() * sk, key_shares[0].shared_public_key); +fn validate_keygen_output( + rng: &mut impl rand::RngCore, + key_shares: &[cggmp21::IncompleteKeyShare], + hd_wallet: bool, +) { + #[cfg(not(feature = "hd-wallet"))] + assert!(!hd_wallet); + + for (i, key_share) in (0u16..).zip(key_shares) { + assert_eq!(key_share.i, i); + assert_eq!(key_share.shared_public_key, key_shares[0].shared_public_key); + assert_eq!(key_share.public_shares, key_shares[0].public_shares); + assert_eq!( + Point::::generator() * &key_share.x, + key_share.public_shares[usize::from(i)] + ); } - #[instantiate_tests()] - mod secp256k1 {} - #[instantiate_tests()] - mod secp256r1 {} - #[instantiate_tests()] - mod stark {} + #[cfg(feature = "hd-wallet")] + if hd_wallet { + assert!(key_shares[0].chain_code.is_some()); + for key_share in &key_shares[1..] { + assert_eq!(key_share.chain_code, key_shares[0].chain_code); + } + } else { + for key_share in key_shares { + assert_eq!(key_share.chain_code, None); + } + } + + // Choose `t` random key shares and reconstruct a secret key + let t = key_shares[0].min_signers(); + let t_shares = key_shares + .choose_multiple(rng, t.into()) + .cloned() + .collect::>(); + + let sk = reconstruct_secret_key(&t_shares).unwrap(); + assert_eq!(Point::generator() * sk, key_shares[0].shared_public_key); } diff --git a/tests/tests/it/pipeline.rs b/tests/tests/it/pipeline.rs index 6a4396f..7b163b2 100644 --- a/tests/tests/it/pipeline.rs +++ b/tests/tests/it/pipeline.rs @@ -1,175 +1,165 @@ -#[generic_tests::define(attrs(tokio::test, test_case::case, cfg_attr))] -mod generic { - use generic_ec::{Curve, Point}; - use rand::{seq::SliceRandom, Rng, RngCore}; - use rand_dev::DevRng; - use sha2::Sha256; - - use cggmp21::{ - key_share::{AnyKeyShare, IncompleteKeyShare, KeyShare}, - ExecutionId, - }; +use generic_ec::{Curve, Point}; +use rand::{seq::SliceRandom, Rng, RngCore}; +use rand_dev::DevRng; +use sha2::Sha256; + +use cggmp21::{ + key_share::{AnyKeyShare, IncompleteKeyShare, KeyShare}, + ExecutionId, +}; + +cggmp21_tests::test_suite! { + test = full_pipeline_works, + generics = all_curves, + suites = [ + t2n3(2, 3, false), + t3n5(3, 5, false), + #[cfg(feature = "hd-wallet")] + t3n5_hd(3, 5, true), + ] +} +fn full_pipeline_works(t: u16, n: u16, hd_enabled: bool) +where + E: Curve + cggmp21_tests::CurveParams, + Point: generic_ec::coords::HasAffineX, +{ + let mut rng = DevRng::new(); + let incomplete_shares = run_keygen(t, n, hd_enabled, &mut rng); + let shares = run_aux_gen(incomplete_shares, &mut rng); + run_signing(&shares, hd_enabled, &mut rng); +} - #[test_case::case(2, 3, false; "t2n3")] - #[test_case::case(3, 5, false; "t3n5")] - #[cfg_attr(feature = "hd-wallet", test_case::case(3, 5, true; "t3n5-hd"))] - fn full_pipeline_works(t: u16, n: u16, hd_enabled: bool) - where - E: Curve + cggmp21_tests::CurveParams, - Point: generic_ec::coords::HasAffineX, - { - let mut rng = DevRng::new(); - let incomplete_shares = run_keygen(t, n, hd_enabled, &mut rng); - let shares = run_aux_gen(incomplete_shares, &mut rng); - run_signing(&shares, hd_enabled, &mut rng); - } - - fn run_keygen( - t: u16, - n: u16, - hd_enabled: bool, - rng: &mut DevRng, - ) -> Vec> - where - E: Curve, - { - #[cfg(not(feature = "hd-wallet"))] - assert!(!hd_enabled); - - let eid: [u8; 32] = rng.gen(); - let eid = ExecutionId::new(&eid); - - round_based::simulation::run(n, |i, party| { - let mut party_rng = rng.fork(); - - async move { - let keygen = cggmp21::keygen(eid, i, n).set_threshold(t); - - #[cfg(feature = "hd-wallet")] - let keygen = keygen.hd_wallet(hd_enabled); - - keygen.start(&mut party_rng, party).await - } - }) - .unwrap() - .expect_ok() - .into_vec() - } - - fn run_aux_gen(shares: Vec>, rng: &mut DevRng) -> Vec> - where - E: Curve, - { - let mut primes = cggmp21_tests::CACHED_PRIMES.iter(); - let n = shares.len().try_into().unwrap(); - - let eid: [u8; 32] = rng.gen(); - let eid = ExecutionId::new(&eid); - - let aux_infos = round_based::simulation::run(n, |i, party| { - let mut party_rng = rng.fork(); - let pregenerated_data = primes.next().expect("Can't fetch primes"); - async move { - cggmp21::aux_info_gen(eid, i, n, pregenerated_data) - .start(&mut party_rng, party) - .await - } +fn run_keygen(t: u16, n: u16, hd_enabled: bool, rng: &mut DevRng) -> Vec> +where + E: Curve, +{ + #[cfg(not(feature = "hd-wallet"))] + assert!(!hd_enabled); + + let eid: [u8; 32] = rng.gen(); + let eid = ExecutionId::new(&eid); + + round_based::simulation::run(n, |i, party| { + let mut party_rng = rng.fork(); + + async move { + let keygen = cggmp21::keygen(eid, i, n).set_threshold(t); + + #[cfg(feature = "hd-wallet")] + let keygen = keygen.hd_wallet(hd_enabled); + + keygen.start(&mut party_rng, party).await + } + }) + .unwrap() + .expect_ok() + .into_vec() +} + +fn run_aux_gen(shares: Vec>, rng: &mut DevRng) -> Vec> +where + E: Curve, +{ + let mut primes = cggmp21_tests::CACHED_PRIMES.iter(); + let n = shares.len().try_into().unwrap(); + + let eid: [u8; 32] = rng.gen(); + let eid = ExecutionId::new(&eid); + + let aux_infos = round_based::simulation::run(n, |i, party| { + let mut party_rng = rng.fork(); + let pregenerated_data = primes.next().expect("Can't fetch primes"); + async move { + cggmp21::aux_info_gen(eid, i, n, pregenerated_data) + .start(&mut party_rng, party) + .await + } + }) + .unwrap() + .expect_ok() + .into_vec(); + + shares + .into_iter() + .zip(aux_infos.into_iter()) + .map(|(core, aux)| { + KeyShare::from_parts((core, aux)).expect("Couldn't make share from parts") }) - .unwrap() - .expect_ok() - .into_vec(); - - shares - .into_iter() - .zip(aux_infos.into_iter()) - .map(|(core, aux)| { - KeyShare::from_parts((core, aux)).expect("Couldn't make share from parts") - }) - .collect() - } - - fn run_signing(shares: &[KeyShare], random_derivation_path: bool, rng: &mut DevRng) - where - E: Curve + cggmp21_tests::CurveParams, - Point: generic_ec::coords::HasAffineX, - { - #[cfg(not(feature = "hd-wallet"))] - assert!(!random_derivation_path); - - let t = shares[0].min_signers(); - let n = shares.len().try_into().unwrap(); + .collect() +} - #[cfg(feature = "hd-wallet")] - let derivation_path = if random_derivation_path { - Some(cggmp21_tests::random_derivation_path(rng)) - } else { - None - }; - - let eid: [u8; 32] = rng.gen(); - let eid = ExecutionId::new(&eid); - - let mut original_message_to_sign = [0u8; 100]; - rng.fill_bytes(&mut original_message_to_sign); - let message_to_sign = - cggmp21::signing::DataToSign::digest::(&original_message_to_sign); - - // Choose `t` signers to perform signing - let mut participants = (0..n).collect::>(); - participants.shuffle(rng); - let participants = &participants[..usize::from(t)]; - println!("Signers: {participants:?}"); - let participants_shares = participants.iter().map(|i| &shares[usize::from(*i)]); - - let sig = - round_based::simulation::run_with_setup(participants_shares, |i, party, share| { - let mut party_rng = rng.fork(); - - #[cfg(feature = "hd-wallet")] - let derivation_path = derivation_path.clone(); - - async move { - let signing = cggmp21::signing(eid, i, participants, share); - - #[cfg(feature = "hd-wallet")] - let signing = if let Some(derivation_path) = derivation_path { - signing - .set_derivation_path_with_algo::(derivation_path) - .unwrap() - } else { - signing - }; - - signing.sign(&mut party_rng, party, message_to_sign).await - } - }) - .unwrap() - .expect_ok() - .expect_eq(); +fn run_signing(shares: &[KeyShare], random_derivation_path: bool, rng: &mut DevRng) +where + E: Curve + cggmp21_tests::CurveParams, + Point: generic_ec::coords::HasAffineX, +{ + #[cfg(not(feature = "hd-wallet"))] + assert!(!random_derivation_path); + + let t = shares[0].min_signers(); + let n = shares.len().try_into().unwrap(); + + #[cfg(feature = "hd-wallet")] + let derivation_path = if random_derivation_path { + Some(cggmp21_tests::random_derivation_path(rng)) + } else { + None + }; + + let eid: [u8; 32] = rng.gen(); + let eid = ExecutionId::new(&eid); + + let mut original_message_to_sign = [0u8; 100]; + rng.fill_bytes(&mut original_message_to_sign); + let message_to_sign = cggmp21::signing::DataToSign::digest::(&original_message_to_sign); + + // Choose `t` signers to perform signing + let mut participants = (0..n).collect::>(); + participants.shuffle(rng); + let participants = &participants[..usize::from(t)]; + println!("Signers: {participants:?}"); + let participants_shares = participants.iter().map(|i| &shares[usize::from(*i)]); + + let sig = round_based::simulation::run_with_setup(participants_shares, |i, party, share| { + let mut party_rng = rng.fork(); #[cfg(feature = "hd-wallet")] - let public_key = if let Some(path) = &derivation_path { - generic_ec::NonZero::from_point( - shares[0] - .derive_child_public_key::(path.iter().cloned()) + let derivation_path = derivation_path.clone(); + + async move { + let signing = cggmp21::signing(eid, i, participants, share); + + #[cfg(feature = "hd-wallet")] + let signing = if let Some(derivation_path) = derivation_path { + signing + .set_derivation_path_with_algo::(derivation_path) .unwrap() - .public_key, - ) - .unwrap() - } else { - shares[0].shared_public_key - }; - #[cfg(not(feature = "hd-wallet"))] - let public_key = shares[0].shared_public_key; - - sig.verify(&public_key, &message_to_sign) - .expect("signature is not valid"); - } - - #[instantiate_tests()] - mod secp256r1 {} - #[instantiate_tests()] - mod secp256k1 {} - #[instantiate_tests()] - mod stark {} + } else { + signing + }; + + signing.sign(&mut party_rng, party, message_to_sign).await + } + }) + .unwrap() + .expect_ok() + .expect_eq(); + + #[cfg(feature = "hd-wallet")] + let public_key = if let Some(path) = &derivation_path { + generic_ec::NonZero::from_point( + shares[0] + .derive_child_public_key::(path.iter().cloned()) + .unwrap() + .public_key, + ) + .unwrap() + } else { + shares[0].shared_public_key + }; + #[cfg(not(feature = "hd-wallet"))] + let public_key = shares[0].shared_public_key; + + sig.verify(&public_key, &message_to_sign) + .expect("signature is not valid"); } diff --git a/tests/tests/it/trusted_dealer.rs b/tests/tests/it/trusted_dealer.rs index de21c53..d99677e 100644 --- a/tests/tests/it/trusted_dealer.rs +++ b/tests/tests/it/trusted_dealer.rs @@ -1,78 +1,74 @@ -#[generic_tests::define] -mod test { - use cggmp21::{define_security_level, key_share::reconstruct_secret_key}; - use generic_ec::{Curve, NonZero, Point, Scalar, SecretScalar}; - use rand::{seq::SliceRandom, Rng}; - use rand_dev::DevRng; +use cggmp21::{define_security_level, key_share::reconstruct_secret_key}; +use generic_ec::{Curve, NonZero, Point, Scalar, SecretScalar}; +use rand::{seq::SliceRandom, Rng}; +use rand_dev::DevRng; - use cggmp21::trusted_dealer; +use cggmp21::trusted_dealer; - /// Dummy security level that enables fast key generation - #[derive(Clone)] - struct DummyLevel; - define_security_level!(DummyLevel { - security_bits = 32, - epsilon = 64, - ell = 128, - ell_prime = 128, - m = 128, - q = (cggmp21::rug::Integer::ONE.clone() << 128) - 1, - }); +/// Dummy security level that enables fast key generation +#[derive(Clone)] +struct DummyLevel; +define_security_level!(DummyLevel { + security_bits = 32, + epsilon = 64, + ell = 128, + ell_prime = 128, + m = 128, + q = (cggmp21::rug::Integer::ONE.clone() << 128) - 1, +}); - #[test] - fn trusted_dealer_generates_correct_shares() { - let mut rng = DevRng::new(); - let thresholds = [None, Some(2), Some(3), Some(5), Some(7), Some(10)]; +cggmp21_tests::test_suite! { + test = trusted_dealer_generates_correct_shares, + generics = all_curves, + suites = [ + test(), + ] +} +fn trusted_dealer_generates_correct_shares() { + let mut rng = DevRng::new(); + let thresholds = [None, Some(2), Some(3), Some(5), Some(7), Some(10)]; - for n in [2, 3, 7, 10] { - for &t in thresholds - .iter() - .filter(|t| t.map(|t| t <= n).unwrap_or(true)) - { - println!("t={t:?} n={n}"); - let sk = NonZero::>::random(&mut rng); - let shares = trusted_dealer::builder::(n) - .set_threshold(t) - .set_shared_secret_key(sk.clone()) - .generate_shares(&mut rng) - .unwrap(); + for n in [2, 3, 7, 10] { + for &t in thresholds + .iter() + .filter(|t| t.map(|t| t <= n).unwrap_or(true)) + { + println!("t={t:?} n={n}"); + let sk = NonZero::>::random(&mut rng); + let shares = trusted_dealer::builder::(n) + .set_threshold(t) + .set_shared_secret_key(sk.clone()) + .generate_shares(&mut rng) + .unwrap(); - // Choose `t` random key shares and reconstruct a secret key - let t = t.unwrap_or(n); - let t_shares = shares - .choose_multiple(&mut rng, t.into()) - .cloned() - .collect::>(); + // Choose `t` random key shares and reconstruct a secret key + let t = t.unwrap_or(n); + let t_shares = shares + .choose_multiple(&mut rng, t.into()) + .cloned() + .collect::>(); - let sk_reconstructed = reconstruct_secret_key(&t_shares).unwrap(); - assert_eq!( - { - let sk: &Scalar = sk.as_ref(); - sk - }, - sk_reconstructed.as_ref() - ); - assert_eq!( - Point::generator() * &sk_reconstructed, - shares[0].core.shared_public_key - ); + let sk_reconstructed = reconstruct_secret_key(&t_shares).unwrap(); + assert_eq!( + { + let sk: &Scalar = sk.as_ref(); + sk + }, + sk_reconstructed.as_ref() + ); + assert_eq!( + Point::generator() * &sk_reconstructed, + shares[0].core.shared_public_key + ); - // Check that `reconstruct_secret_key` works well with more than `t` shares - let k = rng.gen_range((n.min(t + 1))..=n); - let k_shares = shares - .choose_multiple(&mut rng, k.into()) - .cloned() - .collect::>(); - let sk_reconstructed2 = reconstruct_secret_key(&k_shares).unwrap(); - assert_eq!(sk_reconstructed.as_ref(), sk_reconstructed2.as_ref()); - } + // Check that `reconstruct_secret_key` works well with more than `t` shares + let k = rng.gen_range((n.min(t + 1))..=n); + let k_shares = shares + .choose_multiple(&mut rng, k.into()) + .cloned() + .collect::>(); + let sk_reconstructed2 = reconstruct_secret_key(&k_shares).unwrap(); + assert_eq!(sk_reconstructed.as_ref(), sk_reconstructed2.as_ref()); } } - - #[instantiate_tests()] - mod secp256r1 {} - #[instantiate_tests()] - mod secp256k1 {} - #[instantiate_tests()] - mod stark {} } From 1a1984d10914fa3fd7e3d8c3b1f6c1bcaea63225 Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Wed, 27 Nov 2024 16:49:27 +0100 Subject: [PATCH 14/19] Update wasm project Signed-off-by: Denis Varlakov --- wasm/no_std/Cargo.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/wasm/no_std/Cargo.toml b/wasm/no_std/Cargo.toml index 346d53c..b7c12a3 100644 --- a/wasm/no_std/Cargo.toml +++ b/wasm/no_std/Cargo.toml @@ -18,3 +18,7 @@ features = ["hd-wallet", "state-machine"] [patch.crates-io.hd-wallet] git = "https://github.com/LFDT-Lockness/hd-wallet" branch = "dt" + +[patch.crates-io.round-based] +git = "https://github.com/LFDT-Lockness/round-based" +branch = "impr-sim" From f623cea064b48f2c971856620483737b51d9b3f6 Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Fri, 6 Dec 2024 16:16:31 +0100 Subject: [PATCH 15/19] Update deps Signed-off-by: Denis Varlakov --- Cargo.lock | 92 +++++++++++++++++++------------ Cargo.toml | 7 --- cggmp21-keygen/Cargo.toml | 2 +- cggmp21/Cargo.toml | 2 +- tests/src/bin/measure_perf.rs | 37 ++++++------- tests/tests/it/key_refresh.rs | 8 +-- tests/tests/it/keygen.rs | 6 +- tests/tests/it/pipeline.rs | 6 +- tests/tests/it/signing.rs | 27 +++++---- tests/tests/it/stark_prehashed.rs | 2 +- wasm/no_std/Cargo.toml | 8 --- 11 files changed, 101 insertions(+), 96 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 25d1800..7a765cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -144,7 +144,7 @@ checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] @@ -263,7 +263,7 @@ checksum = "fdde5c9cd29ebd706ce1b35600920a33550e402fc998a2e53ad3b42c3c47a192" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] @@ -318,7 +318,7 @@ dependencies = [ "serde", "serde_with 2.3.3", "sha2", - "thiserror", + "thiserror 1.0.48", "udigest", ] @@ -338,7 +338,7 @@ dependencies = [ "serde", "serde_with 2.3.3", "sha2", - "thiserror", + "thiserror 1.0.48", "udigest", ] @@ -610,7 +610,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] @@ -678,7 +678,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] @@ -689,7 +689,7 @@ checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" dependencies = [ "darling_core", "quote", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] @@ -732,7 +732,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] @@ -818,7 +818,7 @@ dependencies = [ "serde_json", "sha2", "sha3", - "thiserror", + "thiserror 1.0.48", "uuid", ] @@ -859,7 +859,7 @@ dependencies = [ "rand_core", "rug", "serde", - "thiserror", + "thiserror 1.0.48", ] [[package]] @@ -1197,7 +1197,8 @@ checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" [[package]] name = "hd-wallet" version = "0.6.0" -source = "git+https://github.com/LFDT-Lockness/hd-wallet?branch=dt#158b65ce54ed6d0d031a9414890b4a9170dd4f11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d1e8b25f89c813ea3f4317b86c1e89ecc86843601ca8657448e47e4f68f69af" dependencies = [ "generic-array", "generic-ec", @@ -1507,7 +1508,7 @@ dependencies = [ "rand_core", "serde", "serde_with 2.3.3", - "thiserror", + "thiserror 1.0.48", "udigest", ] @@ -1648,7 +1649,7 @@ dependencies = [ "rug", "serde", "serde_with 3.0.0", - "thiserror", + "thiserror 1.0.48", "udigest", ] @@ -1827,18 +1828,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -2027,20 +2028,21 @@ dependencies = [ [[package]] name = "round-based" version = "0.4.0" -source = "git+https://github.com/LFDT-Lockness/round-based?branch=impr-sim#687132f4e29f51b0d29405174c6e7485c303451f" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "079e623c882b5ec9c1a4140cb077179ea89f5352f85a7ebd879428c33ce66399" dependencies = [ - "displaydoc", "futures-util", "phantom-type 0.3.1", "round-based-derive", - "thiserror", + "thiserror 2.0.4", "tracing", ] [[package]] name = "round-based-derive" version = "0.2.2" -source = "git+https://github.com/LFDT-Lockness/round-based?branch=impr-sim#687132f4e29f51b0d29405174c6e7485c303451f" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4afa4d5b318bcafae8a7ebc57c1cb7d4b2db7358293e34d71bfd605fd327cc13" dependencies = [ "proc-macro2", "quote", @@ -2212,7 +2214,7 @@ checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] @@ -2284,7 +2286,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] @@ -2296,7 +2298,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] @@ -2369,7 +2371,7 @@ dependencies = [ "starknet-core", "starknet-providers", "starknet-signers", - "thiserror", + "thiserror 1.0.48", ] [[package]] @@ -2418,7 +2420,7 @@ checksum = "af6527b845423542c8a16e060ea1bc43f67229848e7cd4c4d80be994a84220ce" dependencies = [ "starknet-curve", "starknet-ff", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] @@ -2460,7 +2462,7 @@ dependencies = [ "serde_json", "serde_with 2.3.3", "starknet-core", - "thiserror", + "thiserror 1.0.48", "url", ] @@ -2477,7 +2479,7 @@ dependencies = [ "rand", "starknet-core", "starknet-crypto", - "thiserror", + "thiserror 1.0.48", ] [[package]] @@ -2511,9 +2513,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.32" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -2553,7 +2555,16 @@ version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.48", +] + +[[package]] +name = "thiserror" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f49a1853cf82743e3b7950f77e0f4d622ca36cf4317cba00c767838bac8d490" +dependencies = [ + "thiserror-impl 2.0.4", ] [[package]] @@ -2564,7 +2575,18 @@ checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8381894bb3efe0c4acac3ded651301ceee58a15d47c2e34885ed1908ad667061" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] @@ -2741,7 +2763,7 @@ checksum = "d6132fb8382b1bdec1cd01062dbe1e88074610e8fe37c2d504043a45f6400108" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", ] [[package]] @@ -2869,7 +2891,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", "wasm-bindgen-shared", ] @@ -2903,7 +2925,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.90", "wasm-bindgen-backend", "wasm-bindgen-shared", ] diff --git a/Cargo.toml b/Cargo.toml index 263f06b..1b49f50 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,10 +45,3 @@ hd-wallet = { version = "0.6", default-features = false } generic-tests = "0.1" -[patch.crates-io.hd-wallet] -git = "https://github.com/LFDT-Lockness/hd-wallet" -branch = "dt" - -[patch.crates-io.round-based] -git = "https://github.com/LFDT-Lockness/round-based" -branch = "impr-sim" diff --git a/cggmp21-keygen/Cargo.toml b/cggmp21-keygen/Cargo.toml index 85b2b9e..de61f06 100644 --- a/cggmp21-keygen/Cargo.toml +++ b/cggmp21-keygen/Cargo.toml @@ -34,6 +34,6 @@ thiserror = { workspace = true, optional = true } [features] default = ["std"] -std = ["thiserror", "key-share/std", "udigest/std", "round-based/std"] +std = ["thiserror", "key-share/std", "udigest/std"] hd-wallet = ["dep:hd-wallet", "key-share/hd-wallet"] state-machine = ["round-based/state-machine"] diff --git a/cggmp21/Cargo.toml b/cggmp21/Cargo.toml index 5b9e99e..35c3e59 100644 --- a/cggmp21/Cargo.toml +++ b/cggmp21/Cargo.toml @@ -35,7 +35,7 @@ serde = { workspace = true, features = ["derive", "rc"] } serde_with = { workspace = true } hex = { workspace = true, default-features = false, features = ["serde"] } -hd-wallet = { workspace = true, optional = true, features = ["std"] } +hd-wallet = { workspace = true, optional = true } [dev-dependencies] round-based = { workspace = true, features = ["derive", "sim"] } diff --git a/tests/src/bin/measure_perf.rs b/tests/src/bin/measure_perf.rs index 494a5c4..ed81a00 100644 --- a/tests/src/bin/measure_perf.rs +++ b/tests/src/bin/measure_perf.rs @@ -86,7 +86,7 @@ fn do_becnhmarks(args: Args) { let eid: [u8; 32] = rng.gen(); let eid = ExecutionId::new(&eid); - let outputs = round_based::simulation::run(n, |i, party| { + let outputs = round_based::sim::run(n, |i, party| { let mut party_rng = rng.fork(); let mut profiler = PerfProfiler::new(); @@ -124,7 +124,7 @@ fn do_becnhmarks(args: Args) { let eid: [u8; 32] = rng.gen(); let eid = ExecutionId::new(&eid); - let outputs = round_based::simulation::run(n, |i, party| { + let outputs = round_based::sim::run(n, |i, party| { let mut party_rng = rng.fork(); let mut profiler = PerfProfiler::new(); @@ -161,7 +161,7 @@ fn do_becnhmarks(args: Args) { let mut primes = cggmp21_tests::CACHED_PRIMES.iter::(); - let outputs = round_based::simulation::run(n, |i, party| { + let outputs = round_based::sim::run(n, |i, party| { let mut party_rng = rng.fork(); let pregen = primes.next().expect("Can't get pregenerated prime"); @@ -242,24 +242,23 @@ fn do_becnhmarks(args: Args) { let message_to_sign = b"Dfns rules!"; let message_to_sign = DataToSign::digest::(message_to_sign); - let perf_reports = - round_based::simulation::run_with_setup(&shares, |i, party, share| { - let mut party_rng = rng.fork(); + let perf_reports = round_based::sim::run_with_setup(&shares, |i, party, share| { + let mut party_rng = rng.fork(); - let mut profiler = PerfProfiler::new(); + let mut profiler = PerfProfiler::new(); - async move { - let _signature = cggmp21::signing(eid, i, signers_indexes_at_keygen, share) - .set_progress_tracer(&mut profiler) - .sign(&mut party_rng, party, message_to_sign) - .await - .context("signing failed")?; - profiler.get_report().context("get perf report") - } - }) - .unwrap() - .expect_ok() - .into_vec(); + async move { + let _signature = cggmp21::signing(eid, i, signers_indexes_at_keygen, share) + .set_progress_tracer(&mut profiler) + .sign(&mut party_rng, party, message_to_sign) + .await + .context("signing failed")?; + profiler.get_report().context("get perf report") + } + }) + .unwrap() + .expect_ok() + .into_vec(); println!("Signing protocol"); println!("{}", perf_reports[0].clone().display_io(false)); diff --git a/tests/tests/it/key_refresh.rs b/tests/tests/it/key_refresh.rs index d2af2d6..2151c51 100644 --- a/tests/tests/it/key_refresh.rs +++ b/tests/tests/it/key_refresh.rs @@ -38,7 +38,7 @@ where let eid: [u8; 32] = rng.gen(); let eid = ExecutionId::new(&eid); - let key_shares = round_based::simulation::run_with_setup(&shares, |_i, party, share| { + let key_shares = round_based::sim::run_with_setup(&shares, |_i, party, share| { let mut party_rng = rng.fork(); let pregenerated_data = primes.next().expect("Can't fetch primes"); async move { @@ -93,7 +93,7 @@ where let message_to_sign = cggmp21::signing::DataToSign::digest::(&[42; 100]); let participants = &(0..n).collect::>(); - let sig = round_based::simulation::run_with_setup(&key_shares, |_i, party, share| { + let sig = round_based::sim::run_with_setup(&key_shares, |_i, party, share| { let mut party_rng = rng.fork(); async move { cggmp21::signing(eid, share.core.i, participants, share) @@ -135,7 +135,7 @@ where let eid: [u8; 32] = rng.gen(); let eid = ExecutionId::new(&eid); - let aux_infos = round_based::simulation::run(n, |i, party| { + let aux_infos = round_based::sim::run(n, |i, party| { let mut party_rng = rng.fork(); let pregenerated_data = primes.next().expect("Can't fetch primes"); async move { @@ -178,7 +178,7 @@ where println!("Signers: {participants:?}"); let participants_shares = participants.iter().map(|i| &key_shares[usize::from(*i)]); - let sig = round_based::simulation::run_with_setup(participants_shares, |i, party, share| { + let sig = round_based::sim::run_with_setup(participants_shares, |i, party, share| { let mut party_rng = rng.fork(); async move { cggmp21::signing(eid, i, participants, share) diff --git a/tests/tests/it/keygen.rs b/tests/tests/it/keygen.rs index cc77e9d..54a0bd3 100644 --- a/tests/tests/it/keygen.rs +++ b/tests/tests/it/keygen.rs @@ -34,7 +34,7 @@ fn keygen_works(n: u16, reliable_broadcast: bool, hd_wallet: bool) { let eid: [u8; 32] = rng.gen(); let eid = ExecutionId::new(&eid); - let key_shares = round_based::simulation::run(n, |i, party| { + let key_shares = round_based::sim::run(n, |i, party| { let mut party_rng = rng.fork(); async move { @@ -76,7 +76,7 @@ fn threshold_keygen_works(t: u16, n: u16, reliable_broadcast: bool, hd let eid: [u8; 32] = rng.gen(); let eid = ExecutionId::new(&eid); - let key_shares = round_based::simulation::run(n, |i, party| { + let key_shares = round_based::sim::run(n, |i, party| { let mut party_rng = rng.fork(); async move { @@ -119,7 +119,7 @@ fn threshold_keygen_sync_works(t: u16, n: u16, hd_wallet: bool) { .take(n.into()) .collect::>(); - let mut simulation = round_based::simulation::Simulation::with_capacity(n); + let mut simulation = round_based::sim::Simulation::with_capacity(n); for (i, party_rng) in (0..).zip(&mut party_rng) { simulation.add_party({ let keygen = cggmp21::keygen::(eid, i, n).set_threshold(t); diff --git a/tests/tests/it/pipeline.rs b/tests/tests/it/pipeline.rs index 7b163b2..ae9ab60 100644 --- a/tests/tests/it/pipeline.rs +++ b/tests/tests/it/pipeline.rs @@ -39,7 +39,7 @@ where let eid: [u8; 32] = rng.gen(); let eid = ExecutionId::new(&eid); - round_based::simulation::run(n, |i, party| { + round_based::sim::run(n, |i, party| { let mut party_rng = rng.fork(); async move { @@ -66,7 +66,7 @@ where let eid: [u8; 32] = rng.gen(); let eid = ExecutionId::new(&eid); - let aux_infos = round_based::simulation::run(n, |i, party| { + let aux_infos = round_based::sim::run(n, |i, party| { let mut party_rng = rng.fork(); let pregenerated_data = primes.next().expect("Can't fetch primes"); async move { @@ -120,7 +120,7 @@ where println!("Signers: {participants:?}"); let participants_shares = participants.iter().map(|i| &shares[usize::from(*i)]); - let sig = round_based::simulation::run_with_setup(participants_shares, |i, party, share| { + let sig = round_based::sim::run_with_setup(participants_shares, |i, party, share| { let mut party_rng = rng.fork(); #[cfg(feature = "hd-wallet")] diff --git a/tests/tests/it/signing.rs b/tests/tests/it/signing.rs index 54142e3..2a54384 100644 --- a/tests/tests/it/signing.rs +++ b/tests/tests/it/signing.rs @@ -67,7 +67,7 @@ where println!("Signers: {participants:?}"); let participants_shares = participants.iter().map(|i| &shares[usize::from(*i)]); - let sig = round_based::simulation::run_with_setup(participants_shares, |i, party, share| { + let sig = round_based::sim::run_with_setup(participants_shares, |i, party, share| { let mut party_rng = rng.fork(); let signing = cggmp21::signing(eid, i, participants, share) @@ -146,19 +146,18 @@ where let participants_shares = participants.iter().map(|i| &shares[usize::from(*i)]); - let presigs = - round_based::simulation::run_with_setup(participants_shares, |i, party, share| { - let mut party_rng = rng.fork(); + let presigs = round_based::sim::run_with_setup(participants_shares, |i, party, share| { + let mut party_rng = rng.fork(); - async move { - cggmp21::signing(eid, i, participants, share) - .generate_presignature(&mut party_rng, party) - .await - } - }) - .unwrap() - .expect_ok() - .into_vec(); + async move { + cggmp21::signing(eid, i, participants, share) + .generate_presignature(&mut party_rng, party) + .await + } + }) + .unwrap() + .expect_ok() + .into_vec(); // Now, that we have presignatures generated, we learn (generate) a messages to sign // and the derivation path (if hd is enabled) @@ -271,7 +270,7 @@ where .take(n.into()) .collect::>(); - let mut simulation = round_based::simulation::Simulation::with_capacity(n); + let mut simulation = round_based::sim::Simulation::with_capacity(n); for ((i, share), signer_rng) in (0..).zip(participants_shares).zip(&mut signer_rng) { simulation.add_party({ diff --git a/tests/tests/it/stark_prehashed.rs b/tests/tests/it/stark_prehashed.rs index dcc3aab..24ef3b4 100644 --- a/tests/tests/it/stark_prehashed.rs +++ b/tests/tests/it/stark_prehashed.rs @@ -70,7 +70,7 @@ fn sign_transaction() { println!("Signers: {participants:?}"); let participants_shares = participants.iter().map(|i| &shares[usize::from(*i)]); - let sig = round_based::simulation::run_with_setup(participants_shares, |i, party, share| { + let sig = round_based::sim::run_with_setup(participants_shares, |i, party, share| { let mut party_rng = rng.fork(); async move { diff --git a/wasm/no_std/Cargo.toml b/wasm/no_std/Cargo.toml index b7c12a3..f3b86bd 100644 --- a/wasm/no_std/Cargo.toml +++ b/wasm/no_std/Cargo.toml @@ -14,11 +14,3 @@ features = ["serde", "hd-wallet", "spof", "udigest"] path = "../../cggmp21-keygen" default-features = false features = ["hd-wallet", "state-machine"] - -[patch.crates-io.hd-wallet] -git = "https://github.com/LFDT-Lockness/hd-wallet" -branch = "dt" - -[patch.crates-io.round-based] -git = "https://github.com/LFDT-Lockness/round-based" -branch = "impr-sim" From d6378e658a07871d11dc1239d7ec1db69ca9f556 Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Fri, 6 Dec 2024 16:17:57 +0100 Subject: [PATCH 16/19] Update wasm's Cargo.lock Signed-off-by: Denis Varlakov --- wasm/no_std/Cargo.lock | 57 +++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/wasm/no_std/Cargo.lock b/wasm/no_std/Cargo.lock index 05f7039..905e2b1 100644 --- a/wasm/no_std/Cargo.lock +++ b/wasm/no_std/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "autocfg" @@ -108,7 +108,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.90", ] [[package]] @@ -132,7 +132,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.75", + "syn 2.0.90", ] [[package]] @@ -143,7 +143,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.75", + "syn 2.0.90", ] [[package]] @@ -173,7 +173,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.90", ] [[package]] @@ -198,7 +198,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.90", ] [[package]] @@ -305,7 +305,8 @@ dependencies = [ [[package]] name = "hd-wallet" version = "0.6.0" -source = "git+https://github.com/LFDT-Lockness/hd-wallet?branch=dt#158b65ce54ed6d0d031a9414890b4a9170dd4f11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d1e8b25f89c813ea3f4317b86c1e89ecc86843601ca8657448e47e4f68f69af" dependencies = [ "generic-ec", ] @@ -430,9 +431,9 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -465,14 +466,14 @@ dependencies = [ [[package]] name = "round-based" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55f473f56ecfa6457a75c0922c4e51ad036d4a1d27b0a697ac3a9b26f74acc3b" +checksum = "079e623c882b5ec9c1a4140cb077179ea89f5352f85a7ebd879428c33ce66399" dependencies = [ - "displaydoc", "futures-util", "phantom-type 0.3.1", "round-based-derive", + "thiserror", "tracing", ] @@ -525,7 +526,7 @@ checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.90", ] [[package]] @@ -564,7 +565,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.90", ] [[package]] @@ -603,15 +604,35 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.75" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6af063034fc1935ede7be0122941bafa9bacb949334d090b77ca98b5817c7d9" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "thiserror" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f49a1853cf82743e3b7950f77e0f4d622ca36cf4317cba00c767838bac8d490" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8381894bb3efe0c4acac3ded651301ceee58a15d47c2e34885ed1908ad667061" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "time" version = "0.3.36" @@ -671,7 +692,7 @@ checksum = "d6132fb8382b1bdec1cd01062dbe1e88074610e8fe37c2d504043a45f6400108" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.90", ] [[package]] @@ -703,5 +724,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.90", ] From 582d92e7e068fd76c5e61a5641401a271930d77e Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Fri, 6 Dec 2024 16:19:06 +0100 Subject: [PATCH 17/19] clippy fix Signed-off-by: Denis Varlakov --- tests/tests/it/key_refresh.rs | 2 +- tests/tests/it/pipeline.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/tests/it/key_refresh.rs b/tests/tests/it/key_refresh.rs index 2151c51..894603b 100644 --- a/tests/tests/it/key_refresh.rs +++ b/tests/tests/it/key_refresh.rs @@ -153,7 +153,7 @@ where let key_shares = shares .into_iter() - .zip(aux_infos.into_iter()) + .zip(aux_infos) .map(|(share, aux)| { DirtyKeyShare { core: share.into_inner().core, diff --git a/tests/tests/it/pipeline.rs b/tests/tests/it/pipeline.rs index ae9ab60..8dab5ce 100644 --- a/tests/tests/it/pipeline.rs +++ b/tests/tests/it/pipeline.rs @@ -81,7 +81,7 @@ where shares .into_iter() - .zip(aux_infos.into_iter()) + .zip(aux_infos) .map(|(core, aux)| { KeyShare::from_parts((core, aux)).expect("Couldn't make share from parts") }) From 6026e037483151b84312f6437ad30f430d3b735e Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Fri, 6 Dec 2024 16:31:15 +0100 Subject: [PATCH 18/19] Update macro syntax Signed-off-by: Denis Varlakov --- tests/src/lib.rs | 29 +++++++++++++++++------------ tests/tests/it/key_refresh.rs | 12 ++++++------ tests/tests/it/keygen.rs | 32 ++++++++++++++++---------------- tests/tests/it/pipeline.rs | 6 +++--- tests/tests/it/signing.rs | 30 +++++++++++++++--------------- tests/tests/it/trusted_dealer.rs | 2 +- 6 files changed, 58 insertions(+), 53 deletions(-) diff --git a/tests/src/lib.rs b/tests/src/lib.rs index ebd3e9e..2c07a68 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -213,18 +213,18 @@ macro_rules! test_suite { $crate::test_suite! { $(async_test = $async_test,)? $(test = $test,)? - generics = [ - secp256k1 = , - secp256r1 = , - stark = , - ], + generics = { + secp256k1: , + secp256r1: , + stark: , + }, suites = [$($suites)*] } }; ( $(async_test = $async_test:ident,)? $(test = $test:ident,)? - generics = [$($gmod:ident = <$($generic:path),*>),+$(,)?], + generics = {$($gmod:ident: <$($generic:path),*>),+$(,)?}, suites = [$($suites:tt)*] $(,)? ) => { @@ -233,7 +233,7 @@ macro_rules! test_suite { $crate::test_suite_traverse! { $(async_test = $async_test,)? $(test = $test,)? - generics = [$($gmod = <$($generic),+>),+], + generics = {$($gmod: <$($generic),+>),+}, suites = [$($suites)*] } } @@ -248,7 +248,10 @@ macro_rules! test_suite_traverse { $(async_test = $async_test:ident,)? $(test = $test:ident,)? // we traverse over `generics` - generics = [$gmod:ident = <$($generic:path),*>$(, $($generics_rest:tt)*)?], + generics = { + $gmod:ident: <$($generic:path),*> + $(, $($generics_rest:tt)*)? + }, suites = [$($suites:tt)*] ) => { mod $gmod { @@ -263,7 +266,9 @@ macro_rules! test_suite_traverse { $crate::test_suite_traverse! { $(async_test = $async_test,)? $(test = $test,)? - generics = [$($($generics_rest)*)?], + generics = { + $($($generics_rest)*)? + }, suites = [$($suites)*] } }; @@ -271,7 +276,7 @@ macro_rules! test_suite_traverse { $(async_test = $async_test:ident,)? $(test = $test:ident,)? // generics list is empty - nothing to traverse - generics = [], + generics = {}, suites = [$($suites:tt)*] ) => {}; @@ -281,7 +286,7 @@ macro_rules! test_suite_traverse { // we traverse async suites suites = [ $(#[$attr:meta])* - $suite_name:ident($($args:tt)*) + $suite_name:ident: ($($args:tt)*) $(, $($rest:tt)*)? ] ) => { @@ -303,7 +308,7 @@ macro_rules! test_suite_traverse { // we traverse sync suites suites = [ $(#[$attr:meta])* - $suite_name:ident($($args:tt)*) + $suite_name:ident: ($($args:tt)*) $(, $($rest:tt)*)? ] ) => { diff --git a/tests/tests/it/key_refresh.rs b/tests/tests/it/key_refresh.rs index 894603b..09bd926 100644 --- a/tests/tests/it/key_refresh.rs +++ b/tests/tests/it/key_refresh.rs @@ -13,9 +13,9 @@ cggmp21_tests::test_suite! { test = key_refresh_works, generics = all_curves, suites = [ - n3(3, false), - n5(5, false), - n5_reliable(5, true), + n3: (3, false), + n5: (5, false), + n5_reliable: (5, true), ] } fn key_refresh_works(n: u16, reliable_broadcast: bool) @@ -114,9 +114,9 @@ cggmp21_tests::test_suite! { test = aux_gen_works, generics = all_curves, suites = [ - t2n3(2, 3, false), - t3n5(3, 5, false), - t3n5_reliable(3, 5, true), + t2n3: (2, 3, false), + t3n5: (3, 5, false), + t3n5_reliable: (3, 5, true), ] } fn aux_gen_works(t: u16, n: u16, reliable_broadcast: bool) diff --git a/tests/tests/it/keygen.rs b/tests/tests/it/keygen.rs index 54a0bd3..f17571d 100644 --- a/tests/tests/it/keygen.rs +++ b/tests/tests/it/keygen.rs @@ -10,19 +10,19 @@ cggmp21_tests::test_suite! { test = keygen_works, generics = all_curves, suites = [ - n3(3, false, false), - n5(5, false, false), - n7(7, false, false), - n10(10, false, false), - n10_reliable(10, true, false), + n3: (3, false, false), + n5: (5, false, false), + n7: (7, false, false), + n10: (10, false, false), + n10_reliable: (10, true, false), #[cfg(feature = "hd-wallet")] - n3_hd(3, false, true), + n3_hd: (3, false, true), #[cfg(feature = "hd-wallet")] - n5_hd(5, false, true), + n5_hd: (5, false, true), #[cfg(feature = "hd-wallet")] - n7_hd(7, false, true), + n7_hd: (7, false, true), #[cfg(feature = "hd-wallet")] - n10_hd(10, false, true), + n10_hd: (10, false, true), ] } fn keygen_works(n: u16, reliable_broadcast: bool, hd_wallet: bool) { @@ -58,13 +58,13 @@ cggmp21_tests::test_suite! { test = threshold_keygen_works, generics = all_curves, suites = [ - t2n3(2, 3, false, false), - t3n5(3, 5, false, false), - t3n5_reliable(3, 5, true, false), + t2n3: (2, 3, false, false), + t3n5: (3, 5, false, false), + t3n5_reliable: (3, 5, true, false), #[cfg(feature = "hd-wallet")] - t2n3_hd(2, 3, false, true), + t2n3_hd: (2, 3, false, true), #[cfg(feature = "hd-wallet")] - t3n5_hd(3, 5, false, true), + t3n5_hd: (3, 5, false, true), ] } fn threshold_keygen_works(t: u16, n: u16, reliable_broadcast: bool, hd_wallet: bool) { @@ -101,9 +101,9 @@ cggmp21_tests::test_suite! { test = threshold_keygen_sync_works, generics = all_curves, suites = [ - t3n5(3, 5, false), + t3n5: (3, 5, false), #[cfg(feature = "hd-wallet")] - t3n5_hd(3, 5, true), + t3n5_hd: (3, 5, true), ] } fn threshold_keygen_sync_works(t: u16, n: u16, hd_wallet: bool) { diff --git a/tests/tests/it/pipeline.rs b/tests/tests/it/pipeline.rs index 8dab5ce..f53451f 100644 --- a/tests/tests/it/pipeline.rs +++ b/tests/tests/it/pipeline.rs @@ -12,10 +12,10 @@ cggmp21_tests::test_suite! { test = full_pipeline_works, generics = all_curves, suites = [ - t2n3(2, 3, false), - t3n5(3, 5, false), + t2n3: (2, 3, false), + t3n5: (3, 5, false), #[cfg(feature = "hd-wallet")] - t3n5_hd(3, 5, true), + t3n5_hd: (3, 5, true), ] } fn full_pipeline_works(t: u16, n: u16, hd_enabled: bool) diff --git a/tests/tests/it/signing.rs b/tests/tests/it/signing.rs index 2a54384..a0a037b 100644 --- a/tests/tests/it/signing.rs +++ b/tests/tests/it/signing.rs @@ -15,19 +15,19 @@ cggmp21_tests::test_suite! { test = signing_works, generics = all_curves, suites = [ - n2(None, 2, false, false), - n2_reliable(None, 2, true, false), - t2n2(Some(2), 2, false, false), - n3(None, 3, false, false), - t2n3(Some(2), 3, false, false), - t3n3(Some(3), 3, false, false), + n2: (None, 2, false, false), + n2_reliable: (None, 2, true, false), + t2n2: (Some(2), 2, false, false), + n3: (None, 3, false, false), + t2n3: (Some(2), 3, false, false), + t3n3: (Some(3), 3, false, false), #[cfg(feature = "hd-wallet")] - n3_hd(None, 3, false, true), + n3_hd: (None, 3, false, true), #[cfg(feature = "hd-wallet")] - t2n3_hd(Some(2), 3, false, true), + t2n3_hd: (Some(2), 3, false, true), #[cfg(feature = "hd-wallet")] - t3n3_hd(Some(3), 3, false, true), + t3n3_hd: (Some(3), 3, false, true), ] } @@ -114,9 +114,9 @@ cggmp21_tests::test_suite! { test = signing_with_presigs, generics = all_curves, suites = [ - t3n5(Some(3), 5, false), + t3n5: (Some(3), 5, false), #[cfg(feature = "hd-wallet")] - t3n5_hd(Some(3), 5, false), + t3n5_hd: (Some(3), 5, false), ] } @@ -221,12 +221,12 @@ cggmp21_tests::test_suite! { test = signing_sync, generics = all_curves, suites = [ - n3(None, 3, false), - t3n5(Some(3), 5, false), + n3: (None, 3, false), + t3n5: (Some(3), 5, false), #[cfg(feature = "hd-wallet")] - n3_hd(None, 3, true), + n3_hd: (None, 3, true), #[cfg(feature = "hd-wallet")] - t3n5_hd(Some(3), 5, true), + t3n5_hd: (Some(3), 5, true), ] } diff --git a/tests/tests/it/trusted_dealer.rs b/tests/tests/it/trusted_dealer.rs index d99677e..13f9036 100644 --- a/tests/tests/it/trusted_dealer.rs +++ b/tests/tests/it/trusted_dealer.rs @@ -21,7 +21,7 @@ cggmp21_tests::test_suite! { test = trusted_dealer_generates_correct_shares, generics = all_curves, suites = [ - test(), + test: (), ] } fn trusted_dealer_generates_correct_shares() { From 35bce8977c6e46b7215d4b3e8d0bfce5e1b5804d Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Mon, 9 Dec 2024 12:43:08 +0100 Subject: [PATCH 19/19] Update macro syntax Signed-off-by: Denis Varlakov --- tests/src/lib.rs | 100 +++++++++++++++---------------- tests/tests/it/key_refresh.rs | 16 ++--- tests/tests/it/keygen.rs | 24 ++++---- tests/tests/it/pipeline.rs | 8 +-- tests/tests/it/signing.rs | 24 ++++---- tests/tests/it/trusted_dealer.rs | 8 +-- 6 files changed, 90 insertions(+), 90 deletions(-) diff --git a/tests/src/lib.rs b/tests/src/lib.rs index 2c07a68..596f368 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -204,37 +204,37 @@ impl CurveParams for cggmp21::supported_curves::Stark { #[macro_export] macro_rules! test_suite { ( - $(async_test = $async_test:ident,)? - $(test = $test:ident,)? - generics = all_curves, - suites = [$($suites:tt)*] + $(async_test: $async_test:ident,)? + $(test: $test:ident,)? + generics: all_curves, + suites: {$($suites:tt)*} $(,)? ) => { $crate::test_suite! { - $(async_test = $async_test,)? - $(test = $test,)? - generics = { + $(async_test: $async_test,)? + $(test: $test,)? + generics: { secp256k1: , secp256r1: , stark: , }, - suites = [$($suites)*] + suites: {$($suites)*} } }; ( - $(async_test = $async_test:ident,)? - $(test = $test:ident,)? - generics = {$($gmod:ident: <$($generic:path),*>),+$(,)?}, - suites = [$($suites:tt)*] + $(async_test: $async_test:ident,)? + $(test: $test:ident,)? + generics: {$($gmod:ident: <$($generic:path),*>),+$(,)?}, + suites: {$($suites:tt)*} $(,)? ) => { mod $($test)? $($async_test)? { use super::$($test)? $($async_test)?; $crate::test_suite_traverse! { - $(async_test = $async_test,)? - $(test = $test,)? - generics = {$($gmod: <$($generic),+>),+}, - suites = [$($suites)*] + $(async_test: $async_test,)? + $(test: $test,)? + generics: {$($gmod: <$($generic),+>),+}, + suites: {$($suites)*} } } }; @@ -245,50 +245,50 @@ macro_rules! test_suite { macro_rules! test_suite_traverse { ( // Either `$async_test` or `$test` must be present, but not at the same time - $(async_test = $async_test:ident,)? - $(test = $test:ident,)? + $(async_test: $async_test:ident,)? + $(test: $test:ident,)? // we traverse over `generics` - generics = { + generics: { $gmod:ident: <$($generic:path),*> $(, $($generics_rest:tt)*)? }, - suites = [$($suites:tt)*] + suites: {$($suites:tt)*} ) => { mod $gmod { use super::$($test)? $($async_test)?; $crate::test_suite_traverse! { - $(async_test = $async_test,)? - $(test = $test,)? - generics = <$($generic),+>, - suites = [$($suites)*] + $(async_test: $async_test,)? + $(test: $test,)? + generics: <$($generic),+>, + suites: {$($suites)*} } } $crate::test_suite_traverse! { - $(async_test = $async_test,)? - $(test = $test,)? - generics = { + $(async_test: $async_test,)? + $(test: $test,)? + generics: { $($($generics_rest)*)? }, - suites = [$($suites)*] + suites: {$($suites)*} } }; ( - $(async_test = $async_test:ident,)? - $(test = $test:ident,)? + $(async_test: $async_test:ident,)? + $(test: $test:ident,)? // generics list is empty - nothing to traverse - generics = {}, - suites = [$($suites:tt)*] + generics: {}, + suites: {$($suites:tt)*} ) => {}; ( - async_test = $test:ident, - generics = <$($generic:path),*>, + async_test: $test:ident, + generics: <$($generic:path),*>, // we traverse async suites - suites = [ + suites: { $(#[$attr:meta])* $suite_name:ident: ($($args:tt)*) $(, $($rest:tt)*)? - ] + } ) => { $(#[$attr])* #[tokio::test] @@ -297,20 +297,20 @@ macro_rules! test_suite_traverse { } $crate::test_suite_traverse! { - async_test = $test, - generics = <$($generic),*>, - suites = [$($($rest)*)?] + async_test: $test, + generics: <$($generic),*>, + suites: {$($($rest)*)?} } }; ( - test = $test:ident, - generics = <$($generic:path),*>, + test: $test:ident, + generics: <$($generic:path),*>, // we traverse sync suites - suites = [ + suites: { $(#[$attr:meta])* $suite_name:ident: ($($args:tt)*) $(, $($rest:tt)*)? - ] + } ) => { $(#[$attr])* #[test] @@ -319,16 +319,16 @@ macro_rules! test_suite_traverse { } $crate::test_suite_traverse! { - test = $test, - generics = <$($generic),*>, - suites = [$($($rest)*)?] + test: $test, + generics: <$($generic),*>, + suites: {$($($rest)*)?} } }; ( - $(async_test = $async_test:ident,)? - $(test = $test:ident,)? - generics = <$($generic:path),*>, + $(async_test: $async_test:ident,)? + $(test: $test:ident,)? + generics: <$($generic:path),*>, // suites list is empty - nothing to traverse - suites = [] + suites: {} ) => {}; } diff --git a/tests/tests/it/key_refresh.rs b/tests/tests/it/key_refresh.rs index 09bd926..21254d0 100644 --- a/tests/tests/it/key_refresh.rs +++ b/tests/tests/it/key_refresh.rs @@ -10,13 +10,13 @@ use cggmp21::{ }; cggmp21_tests::test_suite! { - test = key_refresh_works, - generics = all_curves, - suites = [ + test: key_refresh_works, + generics: all_curves, + suites: { n3: (3, false), n5: (5, false), n5_reliable: (5, true), - ] + } } fn key_refresh_works(n: u16, reliable_broadcast: bool) where @@ -111,13 +111,13 @@ where } cggmp21_tests::test_suite! { - test = aux_gen_works, - generics = all_curves, - suites = [ + test: aux_gen_works, + generics: all_curves, + suites: { t2n3: (2, 3, false), t3n5: (3, 5, false), t3n5_reliable: (3, 5, true), - ] + } } fn aux_gen_works(t: u16, n: u16, reliable_broadcast: bool) where diff --git a/tests/tests/it/keygen.rs b/tests/tests/it/keygen.rs index f17571d..6b238a4 100644 --- a/tests/tests/it/keygen.rs +++ b/tests/tests/it/keygen.rs @@ -7,9 +7,9 @@ use rand_dev::DevRng; use cggmp21::{key_share::reconstruct_secret_key, ExecutionId}; cggmp21_tests::test_suite! { - test = keygen_works, - generics = all_curves, - suites = [ + test: keygen_works, + generics: all_curves, + suites: { n3: (3, false, false), n5: (5, false, false), n7: (7, false, false), @@ -23,7 +23,7 @@ cggmp21_tests::test_suite! { n7_hd: (7, false, true), #[cfg(feature = "hd-wallet")] n10_hd: (10, false, true), - ] + } } fn keygen_works(n: u16, reliable_broadcast: bool, hd_wallet: bool) { #[cfg(not(feature = "hd-wallet"))] @@ -55,9 +55,9 @@ fn keygen_works(n: u16, reliable_broadcast: bool, hd_wallet: bool) { } cggmp21_tests::test_suite! { - test = threshold_keygen_works, - generics = all_curves, - suites = [ + test: threshold_keygen_works, + generics: all_curves, + suites: { t2n3: (2, 3, false, false), t3n5: (3, 5, false, false), t3n5_reliable: (3, 5, true, false), @@ -65,7 +65,7 @@ cggmp21_tests::test_suite! { t2n3_hd: (2, 3, false, true), #[cfg(feature = "hd-wallet")] t3n5_hd: (3, 5, false, true), - ] + } } fn threshold_keygen_works(t: u16, n: u16, reliable_broadcast: bool, hd_wallet: bool) { #[cfg(not(feature = "hd-wallet"))] @@ -98,13 +98,13 @@ fn threshold_keygen_works(t: u16, n: u16, reliable_broadcast: bool, hd } cggmp21_tests::test_suite! { - test = threshold_keygen_sync_works, - generics = all_curves, - suites = [ + test: threshold_keygen_sync_works, + generics: all_curves, + suites: { t3n5: (3, 5, false), #[cfg(feature = "hd-wallet")] t3n5_hd: (3, 5, true), - ] + } } fn threshold_keygen_sync_works(t: u16, n: u16, hd_wallet: bool) { #[cfg(not(feature = "hd-wallet"))] diff --git a/tests/tests/it/pipeline.rs b/tests/tests/it/pipeline.rs index f53451f..81eaa33 100644 --- a/tests/tests/it/pipeline.rs +++ b/tests/tests/it/pipeline.rs @@ -9,14 +9,14 @@ use cggmp21::{ }; cggmp21_tests::test_suite! { - test = full_pipeline_works, - generics = all_curves, - suites = [ + test: full_pipeline_works, + generics: all_curves, + suites: { t2n3: (2, 3, false), t3n5: (3, 5, false), #[cfg(feature = "hd-wallet")] t3n5_hd: (3, 5, true), - ] + } } fn full_pipeline_works(t: u16, n: u16, hd_enabled: bool) where diff --git a/tests/tests/it/signing.rs b/tests/tests/it/signing.rs index a0a037b..c7d8802 100644 --- a/tests/tests/it/signing.rs +++ b/tests/tests/it/signing.rs @@ -12,9 +12,9 @@ use cggmp21::signing::DataToSign; use cggmp21::{security_level::SecurityLevel128, ExecutionId}; cggmp21_tests::test_suite! { - test = signing_works, - generics = all_curves, - suites = [ + test: signing_works, + generics: all_curves, + suites: { n2: (None, 2, false, false), n2_reliable: (None, 2, true, false), t2n2: (Some(2), 2, false, false), @@ -28,7 +28,7 @@ cggmp21_tests::test_suite! { t2n3_hd: (Some(2), 3, false, true), #[cfg(feature = "hd-wallet")] t3n3_hd: (Some(3), 3, false, true), - ] + } } fn signing_works(t: Option, n: u16, reliable_broadcast: bool, hd_wallet: bool) @@ -111,13 +111,13 @@ where } cggmp21_tests::test_suite! { - test = signing_with_presigs, - generics = all_curves, - suites = [ + test: signing_with_presigs, + generics: all_curves, + suites: { t3n5: (Some(3), 5, false), #[cfg(feature = "hd-wallet")] t3n5_hd: (Some(3), 5, false), - ] + } } fn signing_with_presigs(t: Option, n: u16, hd_wallet: bool) @@ -218,16 +218,16 @@ where } cggmp21_tests::test_suite! { - test = signing_sync, - generics = all_curves, - suites = [ + test: signing_sync, + generics: all_curves, + suites: { n3: (None, 3, false), t3n5: (Some(3), 5, false), #[cfg(feature = "hd-wallet")] n3_hd: (None, 3, true), #[cfg(feature = "hd-wallet")] t3n5_hd: (Some(3), 5, true), - ] + } } fn signing_sync(t: Option, n: u16, hd_wallet: bool) diff --git a/tests/tests/it/trusted_dealer.rs b/tests/tests/it/trusted_dealer.rs index 13f9036..765049c 100644 --- a/tests/tests/it/trusted_dealer.rs +++ b/tests/tests/it/trusted_dealer.rs @@ -18,11 +18,11 @@ define_security_level!(DummyLevel { }); cggmp21_tests::test_suite! { - test = trusted_dealer_generates_correct_shares, - generics = all_curves, - suites = [ + test: trusted_dealer_generates_correct_shares, + generics: all_curves, + suites: { test: (), - ] + } } fn trusted_dealer_generates_correct_shares() { let mut rng = DevRng::new();