From b3c0e13ca840da5e4837ba8dfc4fb2c4d1b2bc28 Mon Sep 17 00:00:00 2001 From: Nicolas80 <nicolas.pmail@protonmail.com> Date: Wed, 1 Jan 2025 18:36:53 +0100 Subject: [PATCH] * Added a test to verify we don't need the nacl::sign::Keypair to handle cesium v1 (we can keep using scrypt to retrieve the seed and then sp_core::ed25519::Pair) ** This means we could remove some code linked to that and possibly the `nacl` dependency. --- src/keys.rs | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 3 deletions(-) diff --git a/src/keys.rs b/src/keys.rs index e71dc79..bdcd1ee 100644 --- a/src/keys.rs +++ b/src/keys.rs @@ -183,10 +183,16 @@ pub fn pair_from_predefined(deriv: &str) -> Result<Sr25519Pair, GcliError> { /// get keypair from Cesium id/pwd pub fn pair_from_cesium(id: String, pwd: String) -> nacl::sign::Keypair { + let seed = seed_from_cesium(&id, &pwd); + nacl::sign::generate_keypair(&seed) +} + +/// get seed from Cesium id/pwd +fn seed_from_cesium(id: &str, pwd: &str) -> [u8; 32] { let params = scrypt::Params::new(12u8, 16u32, 1u32, 32).unwrap(); - let seed = &mut [0u8; 32]; - scrypt::scrypt(&pwd.into_bytes(), &id.into_bytes(), ¶ms, seed).unwrap(); - nacl::sign::generate_keypair(seed) + let mut seed = [0u8; 32]; + scrypt::scrypt(&pwd.as_bytes(), &id.as_bytes(), ¶ms, &mut seed).unwrap(); + seed } /// ask user to input a secret @@ -576,6 +582,8 @@ mod tests { let cesium_id = "test_cesium_id".to_string(); let cesium_pwd = "test_cesium_pwd".to_string(); + let expected_cesium_v1_ss58_address: String = "5ET2jhgJFoNQUpgfdSkdwftK8DKWdqZ1FKm5GKWdPfMWhPr4".to_string(); + let cesium_keypair = pair_from_cesium(cesium_id, cesium_pwd); println!( @@ -589,6 +597,8 @@ mod tests { let cesium_v1_address: AccountId = cesium_keypair.pkey.into(); println!("SS58 Address: '{}'", cesium_v1_address); + assert_eq!(expected_cesium_v1_ss58_address, cesium_v1_address.to_string()); + //ed25519 seed **seems** to be the first 32 bytes of the secret key from nacl keypair let mut seed: [u8; 32] = [0; 32]; seed.copy_from_slice(&cesium_keypair.skey[0..32]); @@ -660,5 +670,59 @@ mod tests { derived_ed25519_address_from_suri.to_string() ); } + + /// Test which verifies that it's possible to directly use a cesium v1 seed retrieved using scryt + /// as seed or suri to instantiate an ed25519 keypair - keeping the same resulting SS58 Address as when using nacl::sign::Keypair + /// + /// Using subkey command with **ed25519** scheme to show the seed/suri and associated SS58 Address + /// + /// ``` + /// subkey inspect --scheme ed25519 + /// URI: + /// Secret Key URI `0x2101d2bc68de9ad149c06293bfe489c8608de576c88927aa5439a81be17aae84` is account: + /// Network ID: substrate + /// Secret seed: 0x2101d2bc68de9ad149c06293bfe489c8608de576c88927aa5439a81be17aae84 + /// Public key (hex): 0x697f6bd16ddebf142384e503fd3f3efc39fe5c7be7c693bd98d982403bb6eb74 + /// Account ID: 0x697f6bd16ddebf142384e503fd3f3efc39fe5c7be7c693bd98d982403bb6eb74 + /// Public key (SS58): 5ET2jhgJFoNQUpgfdSkdwftK8DKWdqZ1FKm5GKWdPfMWhPr4 + /// SS58 Address: 5ET2jhgJFoNQUpgfdSkdwftK8DKWdqZ1FKm5GKWdPfMWhPr4 + /// ``` + #[test] + fn test_cesium_v1_seed_using_scrypt() { + let cesium_id = "test_cesium_id".to_string(); + let cesium_pwd = "test_cesium_pwd".to_string(); + + let expected_cesium_v1_ss58_address: String = "5ET2jhgJFoNQUpgfdSkdwftK8DKWdqZ1FKm5GKWdPfMWhPr4".to_string(); + + // retrieving seed using scrypt + let seed = seed_from_cesium(&cesium_id, &cesium_pwd); + + println!("seed value from scrypt: '0x{}'", hex::encode(&seed)); + + let ed25519_pair_from_seed = sp_core::ed25519::Pair::from_seed(&seed); + + println!(); + println!( + "ed25519 keypair from seed : public:'0x{}' raw_vec:'0x{}'", + hex::encode(ed25519_pair_from_seed.public().0), + hex::encode(ed25519_pair_from_seed.to_raw_vec().as_slice()) + ); + let ed25519_address_from_seed: AccountId = ed25519_pair_from_seed.public().into(); + println!( + "ed25519 keypair from seed : public SS58 Address:'{}'", + ed25519_address_from_seed + ); + assert_eq!(expected_cesium_v1_ss58_address, ed25519_address_from_seed.to_string()); + + let root_suri = "0x".to_string() + &hex::encode(seed); + let ed25519_pair_from_suri = + sp_core::ed25519::Pair::from_string(&root_suri, None).unwrap(); + let ed25519_address_from_suri: AccountId = ed25519_pair_from_suri.public().into(); + println!( + "ed25519 keypair from suri : public SS58 Address:'{}'", + ed25519_address_from_suri + ); + assert_eq!(expected_cesium_v1_ss58_address, ed25519_address_from_suri.to_string()); + } } } -- GitLab