diff --git a/Cargo.lock b/Cargo.lock index ecbf658..45b82de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1997,6 +1997,15 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "212ab92002354b4819390025006c897e8140934349e8635c9b077f47b4dcbd20" +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac 0.12.1", +] + [[package]] name = "hmac" version = "0.8.1" @@ -2509,6 +2518,7 @@ dependencies = [ "ark-std", "ckb-merkle-mountain-range", "etf-crypto-primitives 0.2.4 (git+https://github.com/ideal-lab5/etf-sdk/?branch=dev)", + "hkdf", "parity-scale-codec", "rand_chacha", "rand_core", @@ -2529,6 +2539,7 @@ dependencies = [ "ark-std", "ckb-merkle-mountain-range", "clap", + "hkdf", "murmur-core", "murmur-test-utils", "parity-scale-codec", diff --git a/core/Cargo.toml b/core/Cargo.toml index 727bb22..cee6b81 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -27,6 +27,7 @@ rand_chacha = { version = "0.3.1" } [dev-dependencies] rand_core = { version = "0.6.4", features = ["getrandom"], default-features = false } +hkdf = "0.12.4" [features] default = ["client"] diff --git a/core/src/murmur.rs b/core/src/murmur.rs index fb2e43c..8f32a4f 100644 --- a/core/src/murmur.rs +++ b/core/src/murmur.rs @@ -45,7 +45,9 @@ use w3f_bls::{DoublePublicKey, EngineBLS}; /// Error types for murmur wallet usage #[derive(Debug, PartialEq)] pub enum Error { + /// An error occurred when executing a call ExecuteError, + /// An error occurred when creating a murmur wallet MMRError, InconsistentStore, /// No leaf could be identified in the MMR at the specified position @@ -60,6 +62,8 @@ pub enum Error { InvalidSeed, /// The public key was invalid (could not be decoded) InvalidPubkey, + /// The key derivation failed + KeyDerivationFailed, } /// The murmur store contains minimal data required to use a murmur wallet @@ -271,10 +275,13 @@ mod tests { keypair.public.0, ); - let ephem_msk = [1; 32]; let seed = vec![1, 2, 3]; let schedule = vec![1, 2, 3]; + let hk = hkdf::Hkdf::::new(None, &seed); + let mut ephem_msk = [0u8; 32]; + hk.expand(b"ephemeral key", &mut ephem_msk).unwrap(); + let murmur_store = MurmurStore::new::( seed.clone(), schedule.clone(), @@ -295,7 +302,6 @@ mod tests { keypair.public.0, ); - let ephem_msk = [1; 32]; let seed = vec![1, 2, 3]; let schedule = vec![ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, @@ -303,6 +309,10 @@ mod tests { let aux_data = vec![2, 3, 4, 5]; + let hk = hkdf::Hkdf::::new(None, &seed); + let mut ephem_msk = [0u8; 32]; + hk.expand(b"ephemeral key", &mut ephem_msk).unwrap(); + let murmur_store = MurmurStore::new::( seed.clone(), schedule.clone(), @@ -349,12 +359,15 @@ mod tests { keypair.public.0, ); - let ephem_msk = [1; 32]; let seed = vec![1, 2, 3]; let schedule = vec![1, 2, 3, 4, 5]; let aux_data = vec![2, 3, 4, 5]; + let hk = hkdf::Hkdf::::new(None, &seed); + let mut ephem_msk = [0u8; 32]; + hk.expand(b"ephemeral key", &mut ephem_msk).unwrap(); + let murmur_store = MurmurStore::new::( seed.clone(), schedule.clone(), @@ -381,12 +394,15 @@ mod tests { keypair.public.0, ); - let ephem_msk = [1; 32]; let seed = vec![1, 2, 3]; let schedule = vec![1, 2, 3]; let aux_data = vec![2, 3, 4, 5]; + let hk = hkdf::Hkdf::::new(None, &seed); + let mut ephem_msk = [0u8; 32]; + hk.expand(b"ephemeral key", &mut ephem_msk).unwrap(); + let murmur_store = MurmurStore::new::( seed.clone(), schedule.clone(), @@ -432,13 +448,16 @@ mod tests { keypair.public.0, ); - let ephem_msk = [1; 32]; let seed = vec![1, 2, 3]; let schedule = vec![1, 2, 3]; let other_schedule = vec![1, 2, 3, 4, 5]; let aux_data = vec![2, 3, 4, 5]; + let hk = hkdf::Hkdf::::new(None, &seed); + let mut ephem_msk = [0u8; 32]; + hk.expand(b"ephemeral key", &mut ephem_msk).unwrap(); + let murmur_store = MurmurStore::new::( seed.clone(), schedule.clone(), diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 86873e9..b0df26f 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -37,7 +37,8 @@ ark-serialize = "0.4.0" w3f-bls = "0.1.3" murmur-core = { path = "../core/", features = ["client"] } zeroize = "1.8.1" +hkdf = "0.12.4" [dev-dependencies] -murmur-test-utils = { path = "../test-utils/" } \ No newline at end of file +murmur-test-utils = { path = "../test-utils/" } diff --git a/lib/src/bin/murmur/main.rs b/lib/src/bin/murmur/main.rs index 8f83c3c..59f99fa 100644 --- a/lib/src/bin/murmur/main.rs +++ b/lib/src/bin/murmur/main.rs @@ -86,7 +86,6 @@ pub const MMR_STORE_FILEPATH: &str = "mmr_store"; async fn main() -> Result<(), Box> { let cli = Cli::parse(); let before = Instant::now(); - let ephem_msk = [1; 32]; let (client, current_block_number, round_pubkey_bytes) = idn_connect().await?; @@ -105,7 +104,6 @@ async fn main() -> Result<(), Box> { // 2. create mmr let create_data = create( args.seed.as_bytes().to_vec(), - ephem_msk, schedule, round_pubkey_bytes, ) diff --git a/lib/src/lib.rs b/lib/src/lib.rs index f51935e..9d26338 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -15,6 +15,7 @@ */ use beefy::{known_payloads, Commitment, Payload}; +use hkdf::Hkdf; use murmur_core::types::{Identity, IdentityBuilder}; use serde::Serialize; use subxt::{ @@ -74,16 +75,20 @@ pub struct ProxyData { /// Create a new MMR and return the data needed to build a valid call for creating a murmur wallet. /// /// * `seed`: The seed used to generate otp codes -/// * `ephem_msk`: An ephemeral secret key TODO: replace with an hkdf? /// * `block_schedule`: A list of block numbers when the wallet will be executable /// * `round_pubkey_bytes`: The Ideal Network randomness beacon public key /// pub fn create( mut seed: Vec, - mut ephem_msk: [u8; 32], block_schedule: Vec, round_pubkey_bytes: Vec, ) -> Result { + // Derive ephem_msk from seed using HKDF + let hk = Hkdf::::new(None, &seed); + let mut ephem_msk = [0u8; 32]; + hk.expand(b"ephemeral key", &mut ephem_msk) + .map_err(|_| Error::KeyDerivationFailed)?; + let round_pubkey = DoublePublicKey::::from_bytes(&round_pubkey_bytes) .map_err(|_| Error::InvalidPubkey)?; let mmr_store = MurmurStore::new::( @@ -185,17 +190,19 @@ mod tests { #[test] pub fn it_can_create_an_mmr_store() { let seed = b"seed".to_vec(); - let ephem_msk = [1; 32]; let block_schedule = vec![1, 2, 3, 4, 5, 6, 7]; let double_public_bytes = murmur_test_utils::get_dummy_beacon_pubkey(); let create_data = create( seed.clone(), - ephem_msk, block_schedule.clone(), double_public_bytes.clone(), ) .unwrap(); + let hk = Hkdf::::new(None, &seed); + let mut ephem_msk = [0u8; 32]; + hk.expand(b"ephemeral key", &mut ephem_msk).unwrap(); + let mmr_store = MurmurStore::new::( seed, block_schedule, @@ -211,11 +218,10 @@ mod tests { #[test] pub fn it_can_prepare_valid_execution_call_data() { let seed = b"seed".to_vec(); - let ephem_msk = [1; 32]; let block_schedule = vec![1, 2, 3, 4, 5, 6, 7]; let double_public_bytes = murmur_test_utils::get_dummy_beacon_pubkey(); let create_data = - create(seed.clone(), ephem_msk, block_schedule, double_public_bytes).unwrap(); + create(seed.clone(), block_schedule, double_public_bytes).unwrap(); let bob = subxt_signer::sr25519::dev::bob().public_key(); let balance_transfer_call =