diff --git a/Cargo.lock b/Cargo.lock index d9439d9..c9ceef2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1539,33 +1539,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "etf-crypto-primitives" -version = "0.2.4" -source = "git+https://github.com/ideal-lab5/etf-sdk/?branch=dev#e2b3615e0936c2cdd1ab8673e15208bef880b040" -dependencies = [ - "aes-gcm", - "ark-bls12-377", - "ark-bls12-381", - "ark-ec", - "ark-ff", - "ark-poly", - "ark-serialize", - "ark-std", - "array-bytes", - "chacha20poly1305", - "generic-array", - "parity-scale-codec", - "rand_chacha", - "scale-info", - "serde", - "serde_cbor", - "serde_json", - "sha2 0.10.8", - "sha3", - "w3f-bls", -] - [[package]] name = "etf-crypto-primitives" version = "0.2.4" @@ -2555,12 +2528,12 @@ dependencies = [ "ark-transcript 0.0.2 (git+https://github.com/w3f/ring-vrf.git)", "ckb-merkle-mountain-range", "dleq_vrf 0.0.2 (git+https://github.com/w3f/ring-vrf.git)", - "etf-crypto-primitives 0.2.4 (git+https://github.com/ideal-lab5/etf-sdk/?branch=dev)", "parity-scale-codec", "rand_chacha", "rand_core", "serde", "sha3", + "tle", "totp-rs", "w3f-bls", "zeroize", @@ -4921,6 +4894,34 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tle" +version = "0.1.0" +source = "git+https://github.com/ideal-lab5/tle.git?branch=feat/tle-monorepo#1a50d569cdda608df56d4951b7141e43cc067cef" +dependencies = [ + "aes-gcm", + "ark-bls12-377", + "ark-bls12-381", + "ark-ec", + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "array-bytes", + "chacha20poly1305", + "generic-array", + "parity-scale-codec", + "rand_chacha", + "rand_core", + "scale-info", + "serde", + "serde_cbor", + "serde_json", + "sha2 0.10.8", + "sha3", + "w3f-bls", +] + [[package]] name = "tokio" version = "1.40.0" @@ -5273,9 +5274,9 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "w3f-bls" -version = "0.1.4" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c5da5fa2c6afa2c9158eaa7cd9aee249765eb32b5fb0c63ad8b9e79336a47ec" +checksum = "7335e4c132c28cc43caef6adb339789e599e39adbe78da0c4d547fad48cbc331" dependencies = [ "ark-bls12-377", "ark-bls12-381", diff --git a/core/Cargo.toml b/core/Cargo.toml index c0cfa29..8e43997 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -21,14 +21,14 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] totp-rs = { version = "5.5.1", default-features = false, optional = true } codec = { package = "parity-scale-codec", version = "3.6.12", features = ["derive"], default-features = false } -etf-crypto-primitives = { git = "https://github.com/ideal-lab5/etf-sdk/", branch = "dev", default-features = false } +tle = { package = "tle", default-features = false, git = "https://github.com/ideal-lab5/tle.git", branch = "feat/tle-monorepo"} ckb-merkle-mountain-range = { version = "0.5.2", default-features = false } sha3 = { version = "0.10.8", default-features = false } serde = { version = "1.0.188", features = ["alloc", "derive"], default-features = false } ark-bls12-377 = { version = "0.4.0", default-features = false } ark-std = { version = "0.4.0", default-features = false } ark-serialize = { version = "0.4.0", default-features = false } -w3f-bls = { version = "0.1.3", default-features = false } +w3f-bls = { version = "=0.1.3", default-features = false } zeroize = { version = "1.8.1", default-features = false } ark-ec = { version = "0.4", default-features = false } ark-ff = { version = "0.4", default-features = false } @@ -52,7 +52,7 @@ std = [ "w3f-bls/std", "serde/std", "codec/std", - "etf-crypto-primitives/std", + "tle/std", "sha3/std", "ckb-merkle-mountain-range/std", "zeroize/std", diff --git a/core/src/murmur.rs b/core/src/murmur.rs index 382158b..d34c4e4 100644 --- a/core/src/murmur.rs +++ b/core/src/murmur.rs @@ -39,13 +39,19 @@ use ckb_merkle_mountain_range::{ use codec::{Decode, Encode}; use core::marker::PhantomData; use dleq_vrf::{EcVrfVerifier, PublicKey, SecretKey}; -use etf_crypto_primitives::{encryption::tlock::*, ibe::fullident::Identity}; use sha3::Digest; +use tle::{ + ibe::fullident::Identity, + stream_ciphers::{AESGCMStreamCipherProvider, AESOutput, StreamCipherProvider}, + tlock::*, +}; use w3f_bls::{DoublePublicKey, EngineBLS}; -/// The Murmur protocol label for domain separation in transcripts +/// The base Murmur protocol label pub const MURMUR_PROTO: &[u8] = b"Murmur://"; +/// The Murmur protocol label used for transcripts used while generation/encryption OTP codes pub const MURMUR_PROTO_OTP: &[u8] = b"MurmurOTP://"; +/// The Murmur protocol label used for generating DLEQ proofs pub const MURMUR_PROTO_VRF: &[u8] = b"MurmurVRF://"; /// The size of a 32-bit buffer pub const ALLOCATED_BUFFER_BYTES: usize = 32; @@ -72,6 +78,8 @@ pub enum Error { InvalidSeed, /// The public key was invalid (could not be decoded) InvalidPubkey, + /// The ciphertext could not be deserialized to a TLECiphertext + CiphertextDeserializationFailed, } pub trait ProtocolEngine { @@ -80,7 +88,6 @@ pub trait ProtocolEngine { } /// The supported protocols -#[cfg(feature = "client")] #[derive(Clone, serde::Serialize, serde::Deserialize, Encode, Decode)] pub enum ProtocolId { /// small signatures, SignatureGroup = G1 (48 bytes), PublicKeyGroup = G2 (96 bytes) @@ -124,7 +131,7 @@ impl MurmurStore

{ /// * `block_schedule`: The blocks for which OTP codes will be generated /// * `ephemeral_msk`: Any 32 bytes /// * `round_public_key`: The IDN beacon's public key - pub fn new, R>( + pub fn new, R, S>( mut seed: Vec, block_schedule: Vec, nonce: u64, @@ -132,7 +139,8 @@ impl MurmurStore

{ rng: &mut R, ) -> Result where - R: Rng + CryptoRng + SeedableRng + Sized, + R: Rng + CryptoRng + Sized, + S: Rng + CryptoRng + SeedableRng + Sized, { let mut transcript = Transcript::new_labeled(MURMUR_PROTO); transcript.write_bytes(&seed); @@ -172,8 +180,6 @@ impl MurmurStore

{ seed.zeroize(); - // let t: [u8;32] = transcript_otp.challenge(b"ok").read_byte_array(); - // panic!("{:?}", t); for &i in &block_schedule { let mut otp_code = totp.generate(i as u64); let identity = I::build_identity(i); @@ -184,13 +190,9 @@ impl MurmurStore

{ .challenge(b"ephemeral_msk") .read_byte_array(); - // if i == 10 { - // panic!("{:?}", ephemeral_msk); - // } + let ephem_rng = S::from_seed(ephemeral_msk); - let ephem_rng = R::from_seed(ephemeral_msk); - - let ct_bytes = timelock_encrypt::( + let ct_bytes = timelock_encrypt::( identity, round_public_key.1, ephemeral_msk, @@ -232,13 +234,8 @@ impl MurmurStore

{ call_data: Vec, ) -> Result<(MerkleProof, Vec, Ciphertext, u64), Error> { if let Some(ciphertext) = self.metadata.get(&when) { - - let commitment = self.commit( - seed.clone(), - ciphertext.clone(), - &call_data.clone(), - when, - )?; + let commitment = + self.commit(seed.clone(), ciphertext.clone(), &call_data.clone(), when)?; seed.zeroize(); @@ -276,7 +273,7 @@ impl MurmurStore

{ .read_byte_array(); seed.zeroize(); - let mut otp_code = aes_decrypt::(ciphertext, ephemeral_msk.as_slice().to_vec())?; + let mut otp_code = aes_decrypt::(ciphertext, ephemeral_msk)?; ephemeral_msk.zeroize(); let mut hasher = sha3::Sha3_256::default(); @@ -301,7 +298,41 @@ impl MurmurStore

{ } } -/// A helper function to perform timelock encryption +#[cfg(feature = "client")] +impl MurmurStore

{ + // Serialize MurmurStore without the PhantomData + pub fn encode(&self) -> Vec { + (self.nonce, &self.metadata, &self.root, &self.proof, &self.public_key, &self.protocol_id) + .encode() + } + + pub fn decode(data: Vec) -> Result, Error> { + // Decode fields from `data` without `_phantom` + let (nonce, metadata, root, proof, public_key, protocol_id): ( + u64, + BTreeMap, + Leaf, + Vec, + Vec, + ProtocolId, + ) = Decode::decode(&mut &data[..]).unwrap(); + + match protocol_id { + ProtocolId::TinyBLS377 => Ok(MurmurStore { + nonce, + metadata, + root, + proof, + public_key, + protocol_id, + _phantom: PhantomData, + }), + } + } +} + +/// A helper function to perform timelock encryption. +/// NOTE: this function is opionated to use AES_GCM /// /// * `identity`: The identity to encrypt for /// * `pk`: The public key of the randomness beacon @@ -317,7 +348,8 @@ fn timelock_encrypt( rng: R, ) -> Result, Error> { let ciphertext = - tle::(pk, ephemeral_msk, message, identity, rng).map_err(|_| Error::TlockFailed)?; + tle::(pk, ephemeral_msk, message, identity, rng) + .map_err(|_| Error::TlockFailed)?; let mut ct_bytes = Vec::new(); ciphertext @@ -328,19 +360,28 @@ fn timelock_encrypt( } /// Use a secret key to decrypt the ciphertext before the beacon outputs -/// This uses AES_GCM decryption. It returns the plaintext if decryption is successful, else an error +/// This uses AES_GCM decryption. It returns the plaintext if decryption is successful, else an +/// error /// /// * `ciphertext_bytes`: The ciphertext to decrypt /// * `secret`: A decryption key (32 bytes) -/// #[cfg(feature = "client")] -fn aes_decrypt(ciphertext_bytes: Vec, secret: Vec) -> Result, Error> { +fn aes_decrypt( + ciphertext_bytes: Vec, + secret: [u8; 32], +) -> Result, Error> { + // TODO handle errors let ciphertext: TLECiphertext = - TLECiphertext::deserialize_compressed(&mut &ciphertext_bytes[..]).unwrap(); + TLECiphertext::deserialize_compressed(&mut &ciphertext_bytes[..]) + .map_err(|_| Error::CiphertextDeserializationFailed)?; + + let aes_ct = + AESOutput::deserialize_compressed(&mut &ciphertext.message_ciphertext[..]).unwrap(); - let plaintext = ciphertext.aes_decrypt(secret).map_err(|_| Error::AesDecryptFailed)?; + let plaintext = + AESGCMStreamCipherProvider::decrypt(aes_ct, secret).map_err(|_| Error::AesDecryptFailed)?; - Ok(plaintext.message) + Ok(plaintext) } /// Functions for verifying execution and update requests @@ -358,11 +399,11 @@ pub mod verifier { UnserializablePubkey, } - /// Verify the correctness of execution parameters by checking that the Merkle proof, `Proof`, and hash `H` - /// are valid. The function outputs true if both conditions are true: + /// Verify the correctness of execution parameters by checking that the Merkle proof, `Proof`, + /// and hash `H` are valid. The function outputs true if both conditions are true: /// - /// 1. Proof.Verify(root, [(pos, Leaf(ciphertext))]) - /// 2. H == Sha256(otp || aux_data) + /// 1. Proof.Verify(root, [(pos, Leaf(ciphertext))]) + /// 2. H == Sha256(otp || aux_data) //// /// It outputs false otherwise. /// @@ -373,7 +414,6 @@ pub mod verifier { /// * `otp`: The OTP /// * `aux_data`: The expected aux data used to generate the commitment /// * `pos`: The position of the Ciphertext within the MMR - /// pub fn verify_execute( root: Leaf, proof: MerkleProof, @@ -404,7 +444,6 @@ pub mod verifier { /// * `serialized_proof`: The serialized proof /// * `serialized_pubkey`: The serialized public key /// * `nonce`: A nonce value - /// pub fn verify_update( serialized_proof: Vec, serialized_pubkey: Vec, @@ -463,13 +502,11 @@ mod tests { let seed = vec![1, 2, 3]; - let murmur_store = MurmurStore::::new::( - seed.clone(), - BLOCK_SCHEDULE.to_vec(), - 0, - double_public, - &mut rng, - ) + let murmur_store = MurmurStore::::new::< + DummyIdBuilder, + ChaCha20Rng, + ChaCha20Rng, + >(seed.clone(), BLOCK_SCHEDULE.to_vec(), 0, double_public, &mut rng) .unwrap(); assert!(murmur_store.metadata.keys().len() == BLOCK_SCHEDULE.len()); @@ -489,22 +526,18 @@ mod tests { let seed = vec![1, 2, 3]; let aux_data = vec![2, 3, 4, 5]; - let murmur_store = MurmurStore::::new::( - seed.clone(), - BLOCK_SCHEDULE.to_vec(), - 0, - double_public, - &mut rng, - ) + let murmur_store = MurmurStore::::new::< + DummyIdBuilder, + ChaCha20Rng, + ChaCha20Rng, + >(seed.clone(), BLOCK_SCHEDULE.to_vec(), 0, double_public, &mut rng) .unwrap(); let root = murmur_store.root.clone(); let (proof, commitment, ciphertext, pos) = murmur_store.execute(seed.clone(), WHEN, aux_data.clone()).unwrap(); - assert!( - verifier::verify_execute(root, proof, commitment, ciphertext, OTP, &aux_data, pos) - ); + assert!(verifier::verify_execute(root, proof, commitment, ciphertext, OTP, &aux_data, pos)); } #[cfg(feature = "client")] @@ -517,13 +550,11 @@ mod tests { let seed = vec![1, 2, 3]; - let murmur_store = MurmurStore::::new::( - seed.clone(), - BLOCK_SCHEDULE.to_vec(), - 0, - double_public, - &mut rng, - ) + let murmur_store = MurmurStore::::new::< + DummyIdBuilder, + ChaCha20Rng, + ChaCha20Rng, + >(seed.clone(), BLOCK_SCHEDULE.to_vec(), 0, double_public, &mut rng) .unwrap(); let aux_data = vec![2, 3, 4, 5]; @@ -545,13 +576,11 @@ mod tests { let seed = vec![1, 2, 3]; let aux_data = vec![2, 3, 4, 5]; - let murmur_store = MurmurStore::::new::( - seed.clone(), - BLOCK_SCHEDULE.to_vec(), - 0, - double_public, - &mut rng, - ) + let murmur_store = MurmurStore::::new::< + DummyIdBuilder, + ChaCha20Rng, + ChaCha20Rng, + >(seed.clone(), BLOCK_SCHEDULE.to_vec(), 0, double_public, &mut rng) .unwrap(); let root = murmur_store.root.clone(); @@ -580,17 +609,15 @@ mod tests { let seed = vec![1, 2, 3]; let other_seed = vec![2, 3, 4]; - let murmur_store = MurmurStore::::new::( - seed.clone(), - BLOCK_SCHEDULE.to_vec(), - 0, - double_public, - &mut rng, - ) + let murmur_store = MurmurStore::::new::< + DummyIdBuilder, + ChaCha20Rng, + ChaCha20Rng, + >(seed.clone(), BLOCK_SCHEDULE.to_vec(), 0, double_public, &mut rng) .unwrap(); let other_murmur_store = - MurmurStore::::new::( + MurmurStore::::new::( other_seed.clone(), BLOCK_SCHEDULE.to_vec(), 0, @@ -603,9 +630,8 @@ mod tests { // the block number when this would execute let root = murmur_store.root.clone(); - let (proof, commitment, ciphertext, pos) = other_murmur_store - .execute(other_seed.clone(), WHEN, aux_data.clone()) - .unwrap(); + let (proof, commitment, ciphertext, pos) = + other_murmur_store.execute(other_seed.clone(), WHEN, aux_data.clone()).unwrap(); assert!(!verifier::verify_execute( root, proof, commitment, ciphertext, OTP, &aux_data, pos, @@ -626,13 +652,11 @@ mod tests { let seed = vec![1, 2, 3]; - let murmur_store = MurmurStore::::new::( - seed.clone(), - BLOCK_SCHEDULE.to_vec(), - 0, - double_public, - &mut rng, - ) + let murmur_store = MurmurStore::::new::< + DummyIdBuilder, + ChaCha20Rng, + ChaCha20Rng, + >(seed.clone(), BLOCK_SCHEDULE.to_vec(), 0, double_public, &mut rng) .unwrap(); let proof = murmur_store.proof; @@ -642,7 +666,7 @@ mod tests { let mut not_same_rng = ChaCha20Rng::seed_from_u64(1); let another_murmur_store = - MurmurStore::::new::( + MurmurStore::::new::( seed.clone(), BLOCK_SCHEDULE.to_vec(), 1, @@ -668,13 +692,11 @@ mod tests { let seed = vec![1, 2, 3]; - let murmur_store = MurmurStore::::new::( - seed.clone(), - BLOCK_SCHEDULE.to_vec(), - 0, - double_public, - &mut rng, - ) + let murmur_store = MurmurStore::::new::< + DummyIdBuilder, + ChaCha20Rng, + ChaCha20Rng, + >(seed.clone(), BLOCK_SCHEDULE.to_vec(), 0, double_public, &mut rng) .unwrap(); let proof = murmur_store.proof; diff --git a/core/src/types.rs b/core/src/types.rs index 4145723..abdb059 100644 --- a/core/src/types.rs +++ b/core/src/types.rs @@ -19,7 +19,7 @@ use ckb_merkle_mountain_range::{Merge, Result as MMRResult}; use codec::{Decode, Encode}; use sha3::Digest; -pub use etf_crypto_primitives::ibe::fullident::Identity; +pub use tle::ibe::fullident::Identity; /// The type to represent a block number pub type BlockNumber = u32; diff --git a/lib/src/bin/murmur/main.rs b/lib/src/bin/murmur/main.rs index 3e6d5fa..877ac58 100644 --- a/lib/src/bin/murmur/main.rs +++ b/lib/src/bin/murmur/main.rs @@ -15,10 +15,11 @@ */ use clap::{Parser, Subcommand}; -use murmur_lib::{create, etf, prepare_execute, BlockNumber, BoundedVec, MurmurStore, RuntimeCall}; +use murmur_lib::{ + create, etf, prepare_execute, BlockNumber, BoundedVec, EngineTinyBLS377, MurmurStore, + RuntimeCall, +}; -use rand_chacha::ChaCha20Rng; -use rand_core::{OsRng, SeedableRng}; use sp_core::crypto::Ss58Codec; use std::{fs::File, time::Instant}; use subxt::{backend::rpc::RpcClient, client::OnlineClient, config::SubstrateConfig}; @@ -102,16 +103,13 @@ async fn main() -> Result<(), Box> { let before = Instant::now(); let (client, current_block_number, round_pubkey_bytes) = idn_connect().await?; - let mut rng = ChaCha20Rng::from_rng(&mut OsRng).unwrap(); match &cli.commands { - Commands::New(args) => { - handle_create(args, client, current_block_number, round_pubkey_bytes, rng).await? - }, - Commands::Update(args) => { - handle_update(args, client, current_block_number, round_pubkey_bytes, rng).await? - }, - Commands::Execute(args) => handle_execute(args, client, current_block_number, rng).await?, + Commands::New(args) => + handle_create(args, client, current_block_number, round_pubkey_bytes).await?, + Commands::Update(args) => + handle_update(args, client, current_block_number, round_pubkey_bytes).await?, + Commands::Execute(args) => handle_execute(args, client, current_block_number).await?, } println!("Elapsed time: {:.2?}", before.elapsed()); @@ -124,9 +122,19 @@ async fn handle_create( client: OnlineClient, current_block_number: BlockNumber, round_pubkey_bytes: Vec, - rng: ChaCha20Rng, ) -> Result<(), Box> { - let mmr_store = build_mmr_store(args, current_block_number, round_pubkey_bytes, rng)?; + let mmr_store = build_mmr_store(args, current_block_number, round_pubkey_bytes, 0)?; + + // sanity check + let b: bool = murmur_core::murmur::verifier::verify_update::( + mmr_store.proof.clone(), + mmr_store.public_key.clone(), + 0, + ).unwrap(); + assert!(b == true); + + println!("the proof looks good! ok ... proof bytes {:?}, public kye bytes {:?}", mmr_store.proof.clone(), mmr_store.public_key.clone()); + let call = etf::tx().murmur().create( BoundedVec(args.name.as_bytes().to_vec()), BoundedVec(mmr_store.root.0), @@ -138,7 +146,6 @@ async fn handle_create( client.tx().sign_and_submit_then_watch_default(&call, &dev::alice()).await?; println!("✅ Murmur Proxy Creation: Successful!"); - Ok(()) } @@ -148,9 +155,13 @@ async fn handle_update( client: OnlineClient, current_block_number: BlockNumber, round_pubkey_bytes: Vec, - rng: ChaCha20Rng, ) -> Result<(), Box> { - let mmr_store = build_mmr_store(args, current_block_number, round_pubkey_bytes, rng)?; + // existing mmr_store, we only need this to get the nonce + // note that there are many other ways to get this as well (e.g. query the runtime) + let store: MurmurStore = load_mmr_store(MMR_STORE_FILEPATH)?; + + let mmr_store = + build_mmr_store(args, current_block_number, round_pubkey_bytes, store.nonce + 1)?; let call = etf::tx().murmur().update( BoundedVec(args.name.as_bytes().to_vec()), @@ -166,41 +177,38 @@ async fn handle_update( Ok(()) } -/// Build a new Murmur store for each block from `current_block_number + 2` to `current_block_number + args.validity` +/// Build a new Murmur store for each block from `current_block_number + 2` to `current_block_number +/// + args.validity` fn build_mmr_store( args: &WalletCreationDetails, current_block_number: BlockNumber, round_pubkey_bytes: Vec, - mut rng: ChaCha20Rng, -) -> Result> { + nonce: u64, +) -> Result, Box> { println!("🏗️ Murmur: Generating Merkle mountain range"); - // 1. prepare block schedule let mut schedule: Vec = Vec::new(); for i in 2..args.validity + 2 { - // wallet is 'active' in 2 blocks + // the wallet is 'active' 2 blocks from the current block let next_block_number: BlockNumber = current_block_number + i; schedule.push(next_block_number); } - // 2. create mmr - let mmr_store = - create(args.seed.as_bytes().to_vec(), 0, schedule, round_pubkey_bytes, &mut rng) + let mmr_store: MurmurStore = + create(args.seed.as_bytes().to_vec(), nonce, schedule, round_pubkey_bytes) .map_err(|_| CLIError::MurmurCreationFailed)?; - // 3. add to storage - write_mmr_store(mmr_store.clone(), MMR_STORE_FILEPATH); + write_mmr_store(mmr_store.encode(), MMR_STORE_FILEPATH); Ok(mmr_store) } -/// This function executes a call from the Murmur proxy at block after the provided `current_block_height` -/// note that this does not guarantee execution. If the transaction is not included in a block in the upcoming block -/// then it will never be executed +/// This function executes a call from the Murmur proxy at block after the provided +/// `current_block_height` note that this does not guarantee execution. If the transaction is not +/// included in a block in the upcoming block then it will never be executed async fn handle_execute( args: &WalletExecuteDetails, client: OnlineClient, current_block_number: BlockNumber, - mut rng: ChaCha20Rng, ) -> Result<(), Box> { // 1. build proxied call let from_ss58 = sp_core::crypto::AccountId32::from_ss58check(&args.to) @@ -214,7 +222,7 @@ async fn handle_execute( }); // 2. load the MMR store - let store: MurmurStore = load_mmr_store(MMR_STORE_FILEPATH)?; + let store: MurmurStore = load_mmr_store(MMR_STORE_FILEPATH)?; println!("💾 Recovered Murmur store from local file"); // 3. get the proxy data @@ -223,7 +231,6 @@ async fn handle_execute( current_block_number + 1, store, &balance_transfer_call, - &mut rng, ) .map_err(|_| CLIError::MurmurExecutionFailed)?; @@ -272,15 +279,17 @@ async fn idn_connect( } /// read an MMR from a file -fn load_mmr_store(path: &str) -> Result { +fn load_mmr_store(path: &str) -> Result, CLIError> { let mmr_store_file = File::open(path).expect("Unable to open file"); - let data: MurmurStore = + let data: Vec = serde_cbor::from_reader(mmr_store_file).map_err(|_| CLIError::CorruptedMurmurStore)?; - Ok(data) + // TODO: create new error type + let mmr_store = MurmurStore::::decode(data).unwrap(); + Ok(mmr_store) } /// Write the MMR data to a file -fn write_mmr_store(mmr_store: MurmurStore, path: &str) { +fn write_mmr_store(mmr_store_data: Vec, path: &str) { let mmr_store_file = File::create(path).expect("It should create the file"); - serde_cbor::to_writer(mmr_store_file, &mmr_store).unwrap(); + serde_cbor::to_writer(mmr_store_file, &mmr_store_data).unwrap(); } diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 000e5c3..55df634 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -16,6 +16,7 @@ use beefy::{known_payloads, Commitment, Payload}; use murmur_core::types::{Identity, IdentityBuilder}; +use rand_core::OsRng; use serde::Serialize; use w3f_bls::{DoublePublicKey, SerializableToBytes, TinyBLS377}; use zeroize::Zeroize; @@ -24,7 +25,7 @@ pub use etf::runtime_types::{ bounded_collections::bounded_vec::BoundedVec, node_template_runtime::RuntimeCall, }; pub use murmur_core::{ - murmur::{Error, MurmurStore, EngineTinyBLS377}, + murmur::{EngineTinyBLS377, Error, MurmurStore}, types::BlockNumber, }; use rand_chacha::ChaCha20Rng; @@ -46,7 +47,7 @@ impl IdentityBuilder for BasicIdBuilder { validator_set_id: 0, /* TODO: how to ensure correct validator set ID is used? could * just always set to 1 for now, else set input param. */ }; - Identity::new(&commitment.encode()) + Identity::new(b"", vec![commitment.encode()]) } } @@ -74,17 +75,16 @@ pub fn create( nonce: u64, block_schedule: Vec, round_pubkey_bytes: Vec, - rng: &mut ChaCha20Rng, -) -> Result { +) -> Result, Error> { let round_pubkey = DoublePublicKey::::from_bytes(&round_pubkey_bytes) .map_err(|_| Error::InvalidPubkey)?; - let mmr_store = MurmurStore::::new::( + let mmr_store = MurmurStore::::new::( seed.clone(), block_schedule.clone(), nonce, round_pubkey, - rng, + &mut OsRng, )?; seed.zeroize(); Ok(mmr_store) @@ -106,12 +106,10 @@ pub fn create( pub fn prepare_execute( mut seed: Vec, when: BlockNumber, - store: MurmurStore, + store: MurmurStore, call: &RuntimeCall, - rng: &mut ChaCha20Rng, ) -> Result { - let (proof, commitment, ciphertext, pos) = - store.execute(seed.clone(), when, call.encode(), rng)?; + let (proof, commitment, ciphertext, pos) = store.execute(seed.clone(), when, call.encode())?; seed.zeroize(); let size = proof.mmr_size(); let proof_items: Vec> = @@ -181,14 +179,8 @@ mod tests { let when = 1; - let proxy_data = prepare_execute( - seed.clone(), - when, - mmr_store.clone(), - &balance_transfer_call, - &mut rng, - ) - .unwrap(); + let proxy_data = + prepare_execute(seed.clone(), when, mmr_store.clone(), &balance_transfer_call).unwrap(); // let (proof, commitment, ciphertext, _pos) = create_data.mmr_store // .execute(seed.clone(), when, balance_transfer_call_2.encode(), &mut rng) diff --git a/test-utils/src/lib.rs b/test-utils/src/lib.rs index 76b7cc5..089d60a 100644 --- a/test-utils/src/lib.rs +++ b/test-utils/src/lib.rs @@ -19,17 +19,13 @@ //! various utilities helpful for testing use alloc::vec::Vec; -use ark_ec::CurveGroup; use ark_serialize::CanonicalSerialize; -use dleq_vrf::SecretKey; use rand_core::OsRng; use w3f_bls::{DoublePublicKey, DoublePublicKeyScheme, TinyBLS377}; extern crate alloc; -pub use murmur_core::otp::BOTPGenerator; - -pub use murmur_core::murmur::MurmurStore; +pub use murmur_core::{murmur::MurmurStore, otp::BOTPGenerator}; pub fn get_dummy_beacon_pubkey() -> Vec { let keypair = w3f_bls::KeypairVT::::generate(&mut OsRng);