From 588f4825ed046047a754dd7979977d081ecc2f92 Mon Sep 17 00:00:00 2001 From: peg Date: Tue, 28 Nov 2023 14:21:23 +0100 Subject: [PATCH 1/6] entropy-protocol wasm api takes sr25519 secret key rather than seed --- crypto/protocol/src/user/wasm.rs | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/crypto/protocol/src/user/wasm.rs b/crypto/protocol/src/user/wasm.rs index 1ee197c9e..1f10f7ff8 100644 --- a/crypto/protocol/src/user/wasm.rs +++ b/crypto/protocol/src/user/wasm.rs @@ -1,6 +1,6 @@ //! Wrappers around functions to run dkg and signing protocols for JS use js_sys::Error; -use sp_core::{sr25519, Pair}; +use sp_core::sr25519; use subxt::utils::AccountId32; use wasm_bindgen::prelude::*; use wasm_bindgen_derive::TryFromJsValue; @@ -12,16 +12,19 @@ use crate::KeyParams; #[cfg_attr(feature = "wasm", wasm_bindgen)] pub async fn run_dkg_protocol( validators_info_js: ValidatorInfoArray, - user_signing_keypair_seed: Vec, + user_signing_secret_key: Vec, x25519_private_key_vec: Vec, ) -> Result { let validators_info = parse_validator_info(validators_info_js)?; let user_signing_keypair = { - let seed: [u8; 32] = user_signing_keypair_seed - .try_into() - .map_err(|_| Error::new("User signing keypair seed must be 32 bytes"))?; - sr25519::Pair::from_seed(&seed) + if user_signing_secret_key.len() != 64 { + return Err(Error::new("Secret key must be 64 bytes")); + } + let secret = schnorrkel::SecretKey::from_ed25519_bytes(user_signing_secret_key.as_slice()) + .map_err(|err| Error::new(&err.to_string()))?; + let public = secret.to_public(); + sr25519::Pair::from(schnorrkel::Keypair { secret, public }) }; let x25519_private_key: x25519_dalek::StaticSecret = { @@ -49,7 +52,7 @@ pub async fn run_signing_protocol( key_share: KeyShare, sig_uid: String, validators_info_js: ValidatorInfoArray, - user_signing_keypair_seed: Vec, + user_signing_secret_key: Vec, x25519_private_key_vec: Vec, ) -> Result { let validators_info = parse_validator_info(validators_info_js)?; @@ -64,10 +67,13 @@ pub async fn run_signing_protocol( }; let user_signing_keypair = { - let seed: [u8; 32] = user_signing_keypair_seed - .try_into() - .map_err(|_| Error::new("User signing keypair seed must be 32 bytes"))?; - sr25519::Pair::from_seed(&seed) + if user_signing_secret_key.len() != 64 { + return Err(Error::new("Secret key must be 64 bytes")); + } + let secret = schnorrkel::SecretKey::from_ed25519_bytes(user_signing_secret_key.as_slice()) + .map_err(|err| Error::new(&err.to_string()))?; + let public = secret.to_public(); + sr25519::Pair::from(schnorrkel::Keypair { secret, public }) }; let x25519_private_key: x25519_dalek::StaticSecret = { From bc01ffcd6901b714c7696f6111225258f42c73d8 Mon Sep 17 00:00:00 2001 From: peg Date: Tue, 28 Nov 2023 16:25:00 +0100 Subject: [PATCH 2/6] Add wasm-test feature flag for testing with sp-core keypairs --- crypto/protocol/Cargo.toml | 3 +++ crypto/protocol/Makefile | 4 ++++ crypto/protocol/src/user/wasm.rs | 36 ++++++++++++++++---------------- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/crypto/protocol/Cargo.toml b/crypto/protocol/Cargo.toml index cf57d5677..57bfd1f9c 100644 --- a/crypto/protocol/Cargo.toml +++ b/crypto/protocol/Cargo.toml @@ -67,5 +67,8 @@ wasm=[ "dep:schnorrkel", ] +# Use sp-core compatible sr25519 keypairs on wasm, rather then polkadot JS. For testing only +wasm-test=["wasm"] + [lib] crate-type=["cdylib", "rlib"] diff --git a/crypto/protocol/Makefile b/crypto/protocol/Makefile index 73ce5247b..0ce24ed19 100644 --- a/crypto/protocol/Makefile +++ b/crypto/protocol/Makefile @@ -11,6 +11,10 @@ build-web :: build-bundler :: wasm-pack build --target bundler . --no-default-features -F wasm +# Builds a JS Module for nodejs with testing features +build-nodejs-testing :: + wasm-pack build --target nodejs . --no-default-features -F wasm-test + # Cleans out build artifacts. clean :: rm -rf pkg/ nodejs-test/node_modules/ diff --git a/crypto/protocol/src/user/wasm.rs b/crypto/protocol/src/user/wasm.rs index 1f10f7ff8..fff29c84d 100644 --- a/crypto/protocol/src/user/wasm.rs +++ b/crypto/protocol/src/user/wasm.rs @@ -17,15 +17,7 @@ pub async fn run_dkg_protocol( ) -> Result { let validators_info = parse_validator_info(validators_info_js)?; - let user_signing_keypair = { - if user_signing_secret_key.len() != 64 { - return Err(Error::new("Secret key must be 64 bytes")); - } - let secret = schnorrkel::SecretKey::from_ed25519_bytes(user_signing_secret_key.as_slice()) - .map_err(|err| Error::new(&err.to_string()))?; - let public = secret.to_public(); - sr25519::Pair::from(schnorrkel::Keypair { secret, public }) - }; + let user_signing_keypair = sr25519_keypair_from_secret_key(user_signing_secret_key)?; let x25519_private_key: x25519_dalek::StaticSecret = { let x25519_private_key_raw: [u8; 32] = x25519_private_key_vec @@ -66,15 +58,7 @@ pub async fn run_signing_protocol( sig_hash_vec.try_into().map_err(|_| Error::new("Message hash must be 32 bytes"))? }; - let user_signing_keypair = { - if user_signing_secret_key.len() != 64 { - return Err(Error::new("Secret key must be 64 bytes")); - } - let secret = schnorrkel::SecretKey::from_ed25519_bytes(user_signing_secret_key.as_slice()) - .map_err(|err| Error::new(&err.to_string()))?; - let public = secret.to_public(); - sr25519::Pair::from(schnorrkel::Keypair { secret, public }) - }; + let user_signing_keypair = sr25519_keypair_from_secret_key(user_signing_secret_key)?; let x25519_private_key: x25519_dalek::StaticSecret = { let x25519_private_key_raw: [u8; 32] = x25519_private_key_vec @@ -231,3 +215,19 @@ impl KeyShare { self.0.party_index().as_usize() } } + +fn sr25519_keypair_from_secret_key(secret_key: Vec) -> Result { + if secret_key.len() != 64 { + return Err(Error::new("Secret key must be 64 bytes")); + } + + let secret = if cfg!(feature = "wasm-test") { + schnorrkel::SecretKey::from_bytes(secret_key.as_slice()) + } else { + schnorrkel::SecretKey::from_ed25519_bytes(secret_key.as_slice()) + } + .map_err(|err| Error::new(&err.to_string()))?; + + let public = secret.to_public(); + Ok(sr25519::Pair::from(schnorrkel::Keypair { secret, public })) +} From 8b9895b3404355b1fd6f7f1c4a5136c76f11a45f Mon Sep 17 00:00:00 2001 From: peg Date: Tue, 28 Nov 2023 16:25:27 +0100 Subject: [PATCH 3/6] Update CI script --- .circleci/then.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/then.yml b/.circleci/then.yml index bd66ccf06..336b540d4 100644 --- a/.circleci/then.yml +++ b/.circleci/then.yml @@ -109,7 +109,7 @@ jobs: name: Build entropy-protocol nodejs package. command: | cd crypto/protocol - make build-nodejs + make build-nodejs-testing cd nodejs-test yarn cd ../../.. From 4261234875b594507cd0565040c0c1f7c58fbf43 Mon Sep 17 00:00:00 2001 From: peg Date: Tue, 28 Nov 2023 16:28:07 +0100 Subject: [PATCH 4/6] Comment --- crypto/protocol/src/user/wasm.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crypto/protocol/src/user/wasm.rs b/crypto/protocol/src/user/wasm.rs index fff29c84d..b9975ebcf 100644 --- a/crypto/protocol/src/user/wasm.rs +++ b/crypto/protocol/src/user/wasm.rs @@ -216,6 +216,8 @@ impl KeyShare { } } +// Make a sr25519 keypair given a secret key, using sp-core compatible key generation if +// in test mode, polkadot-js compatible otherwise fn sr25519_keypair_from_secret_key(secret_key: Vec) -> Result { if secret_key.len() != 64 { return Err(Error::new("Secret key must be 64 bytes")); From 7280d995905497ebcc1865969ab4b99db917c400 Mon Sep 17 00:00:00 2001 From: peg Date: Tue, 28 Nov 2023 17:49:21 +0100 Subject: [PATCH 5/6] Use from_ed25519_bytes when testing --- crypto/protocol/src/user/wasm.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crypto/protocol/src/user/wasm.rs b/crypto/protocol/src/user/wasm.rs index b9975ebcf..416de2143 100644 --- a/crypto/protocol/src/user/wasm.rs +++ b/crypto/protocol/src/user/wasm.rs @@ -224,9 +224,9 @@ fn sr25519_keypair_from_secret_key(secret_key: Vec) -> Result Date: Tue, 28 Nov 2023 22:06:00 +0100 Subject: [PATCH 6/6] Update test --- crypto/protocol/nodejs-test/index.js | 4 ++-- crypto/protocol/src/user/wasm.rs | 4 ++-- crypto/server/tests/protocol_wasm.rs | 34 +++++++++++----------------- 3 files changed, 17 insertions(+), 25 deletions(-) diff --git a/crypto/protocol/nodejs-test/index.js b/crypto/protocol/nodejs-test/index.js index aa940a867..b74bc836b 100644 --- a/crypto/protocol/nodejs-test/index.js +++ b/crypto/protocol/nodejs-test/index.js @@ -33,7 +33,7 @@ try { switch(process.argv[2].toLowerCase()) { case 'register': - protocol.run_dkg_protocol(input.validators_info, input.user_sig_req_seed, input.x25519_private_key).then((keyShare) => { + protocol.run_dkg_protocol(input.validators_info, input.user_sig_req_secret_key, input.x25519_private_key).then((keyShare) => { console.log(keyShare.toString()) }).catch((err) => { console.error('ERR', err) @@ -41,7 +41,7 @@ switch(process.argv[2].toLowerCase()) { break case 'sign': let keyShare = protocol.KeyShare.fromString(input.key_share) - protocol.run_signing_protocol(keyShare, input.sig_uid, input.validators_info, input.user_sig_req_seed, input.x25519_private_key).then((output) => { + protocol.run_signing_protocol(keyShare, input.sig_uid, input.validators_info, input.user_sig_req_secret_key, input.x25519_private_key).then((output) => { console.log(output) }).catch((err) => { console.error('ERR', err) diff --git a/crypto/protocol/src/user/wasm.rs b/crypto/protocol/src/user/wasm.rs index 416de2143..b9975ebcf 100644 --- a/crypto/protocol/src/user/wasm.rs +++ b/crypto/protocol/src/user/wasm.rs @@ -224,9 +224,9 @@ fn sr25519_keypair_from_secret_key(secret_key: Vec) -> Result, + user_sig_req_secret_key: Vec, x25519_private_key: Vec, sig_uid: String, key_share: String, @@ -265,7 +257,7 @@ struct UserParticipatesInSigningProtocolArgs { #[derive(Debug, Clone, Serialize, Deserialize)] struct UserParticipatesInDkgProtocolArgs { - user_sig_req_seed: Vec, + user_sig_req_secret_key: Vec, x25519_private_key: Vec, validators_info: Vec, } @@ -283,12 +275,12 @@ async fn spawn_user_participates_in_signing_protocol( key_share: &KeyShare, sig_uid: &str, validators_info: Vec, - user_sig_req_seed: [u8; 32], + user_sig_req_secret_key: Vec, x25519_private_key: &x25519_dalek::StaticSecret, ) -> String { let args = UserParticipatesInSigningProtocolArgs { sig_uid: sig_uid.to_string(), - user_sig_req_seed: user_sig_req_seed.to_vec(), + user_sig_req_secret_key, validators_info: validators_info .into_iter() .map(|validator_info| ValidatorInfoParsed { @@ -309,11 +301,11 @@ async fn spawn_user_participates_in_signing_protocol( /// the protocol runnning parameters as JSON as a command line argument async fn spawn_user_participates_in_dkg_protocol( validators_info: Vec, - user_sig_req_seed: [u8; 32], + user_sig_req_secret_key: Vec, x25519_private_key: &x25519_dalek::StaticSecret, ) -> String { let args = UserParticipatesInDkgProtocolArgs { - user_sig_req_seed: user_sig_req_seed.to_vec(), + user_sig_req_secret_key, validators_info: validators_info .into_iter() .map(|validator_info| ValidatorInfoParsed {