From 593d9af16de1ca3fd859b92c31a0107ec712e1cb Mon Sep 17 00:00:00 2001 From: Niko Date: Mon, 12 Jun 2023 16:50:40 +0300 Subject: [PATCH] create wallet and open wallet working from all apps --- Cargo.lock | 16 ++ ng-app/src-tauri/Cargo.toml | 1 + ng-app/src-tauri/src/lib.rs | 49 ++++- ng-app/src/App.svelte | 2 +- ng-app/src/api.ts | 6 +- ng-app/src/lib/Greet.svelte | 3 +- ng-app/src/routes/Grid.svelte | 335 ++++++++++++++++++++++++++++------ ng-app/src/styles.css | 21 +++ ng-sdk-js/Cargo.toml | 1 + ng-sdk-js/src/lib.rs | 72 +++++++- ng-wallet/Cargo.toml | 4 +- ng-wallet/src/lib.rs | 181 +++++++++++++----- ng-wallet/src/types.rs | 61 +++++++ p2p-repo/Cargo.toml | 3 +- p2p-repo/src/utils.rs | 2 +- 15 files changed, 628 insertions(+), 129 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 575a96c..992307a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2488,6 +2488,7 @@ version = "0.1.0" dependencies = [ "async-std", "debug_print", + "ng-wallet", "p2p-net", "p2p-repo", "serde", @@ -2506,6 +2507,7 @@ dependencies = [ "getrandom 0.1.16", "gloo-timers", "js-sys", + "ng-wallet", "p2p-client-ws", "p2p-net", "p2p-repo", @@ -2527,6 +2529,7 @@ version = "0.1.0" dependencies = [ "aes-gcm-siv", "argon2", + "async-std", "base64-url", "chacha20poly1305", "debug_print", @@ -2540,6 +2543,7 @@ dependencies = [ "serde-big-array", "serde_bare", "serde_bytes", + "web-time", ] [[package]] @@ -2842,6 +2846,7 @@ dependencies = [ "serde", "serde_bare", "serde_bytes", + "web-time", ] [[package]] @@ -5056,6 +5061,17 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19353897b48e2c4d849a2d73cb0aeb16dc2be4e00c565abfc11eb65a806e47de" +dependencies = [ + "js-sys", + "once_cell", + "wasm-bindgen", +] + [[package]] name = "webkit2gtk" version = "0.19.2" diff --git a/ng-app/src-tauri/Cargo.toml b/ng-app/src-tauri/Cargo.toml index b3b03b6..b54f3b0 100644 --- a/ng-app/src-tauri/Cargo.toml +++ b/ng-app/src-tauri/Cargo.toml @@ -23,6 +23,7 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" p2p-repo = { path = "../../p2p-repo" } p2p-net = { path = "../../p2p-net" } +ng-wallet = { path = "../../ng-wallet" } async-std = { version = "1.12.0", features = ["attributes","unstable"] } [features] diff --git a/ng-app/src-tauri/src/lib.rs b/ng-app/src-tauri/src/lib.rs index 6c323cb..c9d9b19 100644 --- a/ng-app/src-tauri/src/lib.rs +++ b/ng-app/src-tauri/src/lib.rs @@ -7,6 +7,8 @@ // notice may not be copied, modified, or distributed except // according to those terms. use async_std::stream::StreamExt; +use ng_wallet::types::*; +use ng_wallet::*; use p2p_net::broker::*; use p2p_net::log; use p2p_net::utils::{spawn_and_log_error, Receiver, ResultSend}; @@ -21,10 +23,10 @@ pub use mobile::*; pub type SetupHook = Box Result<(), Box> + Send>; // Learn more about Tauri commands at https://tauri.app/v1/guides/features/command -#[tauri::command(rename_all = "snake_case")] -fn greet(name: &str) -> String { - format!("Hello, {}! You've been greeted from Rust!", name) -} +// #[tauri::command(rename_all = "snake_case")] +// fn greet(name: &str) -> String { +// format!("Hello, {}! You've been greeted from Rust!", name) +// } #[tauri::command(rename_all = "snake_case")] async fn test() -> Result<(), ()> { @@ -33,9 +35,34 @@ async fn test() -> Result<(), ()> { } #[tauri::command(rename_all = "snake_case")] -async fn create_wallet(name: &str) -> Result { - log!("create wallet from rust {}", name); - Ok(format!("create wallet from rust {}", name)) +async fn wallet_gen_shuffle_for_pazzle_opening(pazzle_length: u8) -> Result { + log!( + "wallet_gen_shuffle_for_pazzle_opening from rust {}", + pazzle_length + ); + Ok(gen_shuffle_for_pazzle_opening(pazzle_length)) +} + +#[tauri::command(rename_all = "snake_case")] +async fn wallet_gen_shuffle_for_pin() -> Result, ()> { + log!("wallet_gen_shuffle_for_pin from rust"); + Ok(gen_shuffle_for_pin()) +} + +#[tauri::command(rename_all = "snake_case")] +async fn wallet_open_wallet_with_pazzle( + wallet: Wallet, + pazzle: Vec, + pin: [u8; 4], +) -> Result { + log!("wallet_open_wallet_with_pazzle from rust {:?}", pazzle); + open_wallet_with_pazzle(wallet, pazzle, pin).map_err(|e| e.to_string()) +} + +#[tauri::command(rename_all = "snake_case")] +async fn wallet_create_wallet(params: CreateWalletV0) -> Result { + log!("wallet_create_wallet from rust {:?}", params); + create_wallet_v0(params).await.map_err(|e| e.to_string()) } #[tauri::command(rename_all = "snake_case")] @@ -138,11 +165,13 @@ impl AppBuilder { }) .invoke_handler(tauri::generate_handler![ test, - greet, - create_wallet, doc_sync_branch, cancel_doc_sync_branch, - doc_get_file_from_store_with_object_ref + doc_get_file_from_store_with_object_ref, + wallet_gen_shuffle_for_pazzle_opening, + wallet_gen_shuffle_for_pin, + wallet_open_wallet_with_pazzle, + wallet_create_wallet, ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/ng-app/src/App.svelte b/ng-app/src/App.svelte index 7b581f0..1427e6b 100644 --- a/ng-app/src/App.svelte +++ b/ng-app/src/App.svelte @@ -11,7 +11,7 @@ -
- {#each [0, 1, 2, 3, 4] as row} -
- {#each emojis2[display]?.slice(0 + row * 3, 3 + row * 3) || [] as emoji} -
- -
- {/each} -
- {/each} -
+{#if step == "pazzle"} +
+ {#each [0, 1, 2, 3, 4] as row} +
+ {#each emojis2[display]?.slice(0 + row * 3, 3 + row * 3) || [] as emoji, i} +
select(row * 3 + i)} + on:keypress={() => select(row * 3 + i)} + > + +
+ {/each} +
+ {/each} +
+{:else if step == "order"} + +
+ {#each [0, 1, 2] as row} +
+ {#each selection.slice(0 + row * 3, 3 + row * 3) || [] as emoji, i} + {#if !emoji.sel} +
select_order(emoji, row * 3 + i)} + on:keypress={() => select_order(emoji, row * 3 + i)} + > + +
+ {:else} +
+ + {emoji.sel} +
+ {/if} + {/each} +
+ {/each} +
+{:else if step == "pin"} +
+ {#each [0, 1] as row} +
+ {#each shuffle_pin.slice(0 + row * 5, 5 + row * 5) as num, i} +
await pin(num)} + on:keypress={async () => await pin(num)} + > + {num} +
+ {/each} +
+ {/each} +
+{:else if step == "end"}{/if} diff --git a/ng-app/src/styles.css b/ng-app/src/styles.css index 2ffc78a..451396f 100644 --- a/ng-app/src/styles.css +++ b/ng-app/src/styles.css @@ -30,8 +30,29 @@ margin-left: auto; } +.pin { + cursor: pointer; + text-align: center; +} + +.sel { + position: relative; + top: -56%; + font-size: 100px; + left: 30%; + font-weight: 700; +} + +.sel-emoji { + overflow: hidden; +} + .emoji { cursor: pointer; + /* padding: 0; + margin: 0; + border: 0; + box-shadow: none; */ } .container2 { diff --git a/ng-sdk-js/Cargo.toml b/ng-sdk-js/Cargo.toml index 1db92b6..f992d0e 100644 --- a/ng-sdk-js/Cargo.toml +++ b/ng-sdk-js/Cargo.toml @@ -19,6 +19,7 @@ ws_stream_wasm = "0.7" p2p-net = { path = "../p2p-net" } p2p-repo = { path = "../p2p-repo" } p2p-client-ws = { path = "../p2p-client-ws" } +ng-wallet = { path = "../ng-wallet" } async-std = { version = "1.12.0", features = ["attributes","unstable"] } futures = "0.3.24" pharos = "0.5" diff --git a/ng-sdk-js/src/lib.rs b/ng-sdk-js/src/lib.rs index 5dcf796..9e850ff 100644 --- a/ng-sdk-js/src/lib.rs +++ b/ng-sdk-js/src/lib.rs @@ -15,6 +15,8 @@ use async_std::task; use async_std::stream::StreamExt; #[cfg(target_arch = "wasm32")] use js_sys::Uint8Array; +use ng_wallet::types::*; +use ng_wallet::*; #[cfg(target_arch = "wasm32")] use p2p_client_ws::remote_ws_wasm::ConnectionWebSocket; use p2p_net::broker::*; @@ -31,9 +33,68 @@ use std::sync::Arc; use wasm_bindgen::prelude::*; use wasm_bindgen_futures::{future_to_promise, JsFuture}; +#[cfg(target_arch = "wasm32")] #[wasm_bindgen] -extern "C" { - pub fn alert(s: &str); +pub fn wallet_gen_shuffle_for_pazzle_opening(pazzle_length: u8) -> JsValue { + let res = gen_shuffle_for_pazzle_opening(pazzle_length); + serde_wasm_bindgen::to_value(&res).unwrap() +} + +#[cfg(target_arch = "wasm32")] +#[wasm_bindgen] +pub fn wallet_gen_shuffle_for_pin() -> Vec { + gen_shuffle_for_pin() +} + +#[cfg(target_arch = "wasm32")] +#[wasm_bindgen] +pub fn wallet_open_wallet_with_pazzle( + js_wallet: JsValue, + pazzle: Vec, + js_pin: JsValue, +) -> Result { + let wallet = serde_wasm_bindgen::from_value::(js_wallet) + .map_err(|_| "Deserialization error of wallet")?; + let pin = serde_wasm_bindgen::from_value::<[u8; 4]>(js_pin) + .map_err(|_| "Deserialization error of pin")?; + let res = open_wallet_with_pazzle(wallet, pazzle, pin); + match res { + Ok(r) => Ok(serde_wasm_bindgen::to_value(&r).unwrap()), + Err(e) => Err(e.to_string().into()), + } +} + +#[cfg(target_arch = "wasm32")] +#[wasm_bindgen] +pub async fn wallet_create_wallet(js_params: JsValue) -> Result { + let params = serde_wasm_bindgen::from_value::(js_params) + .map_err(|_| "Deserialization error of args")?; + + let res = create_wallet_v0(params).await; + match res { + Ok(r) => Ok(serde_wasm_bindgen::to_value(&r).unwrap()), + Err(e) => Err(e.to_string().into()), + } +} + +#[cfg(target_arch = "wasm32")] +#[wasm_bindgen] +pub fn test_create_wallet() -> JsValue { + let pin = [5, 2, 9, 1]; + let r = CreateWalletV0::new( + vec![50u8; 20], + " know yourself ".to_string(), + pin, + 9, + None, + false, + PubKey::Ed25519PubKey([ + 119, 251, 253, 29, 135, 199, 254, 50, 134, 67, 1, 208, 117, 196, 167, 107, 2, 113, 98, + 243, 49, 90, 7, 0, 157, 58, 14, 187, 14, 3, 116, 86, + ]), + 0, + ); + serde_wasm_bindgen::to_value(&r).unwrap() } #[cfg(wasmpack_target = "nodejs")] @@ -48,13 +109,6 @@ extern "C" { fn random(max: usize) -> usize; } -#[cfg(target_arch = "wasm32")] -#[wasm_bindgen] -pub async fn create_wallet(s: String) -> String { - log!("create wallet {} {}", s, BROKER.read().await.test()); - format!("create wallet from js {}", s) -} - #[cfg(target_arch = "wasm32")] #[wasm_bindgen] pub async fn test() { diff --git a/ng-wallet/Cargo.toml b/ng-wallet/Cargo.toml index 860659a..b9536a7 100644 --- a/ng-wallet/Cargo.toml +++ b/ng-wallet/Cargo.toml @@ -24,4 +24,6 @@ chacha20poly1305 = "0.10.1" argon2 = "0.5.0" safe-transmute = "0.11.2" aes-gcm-siv = {version = "0.11.1", features = ["aes","heapless","getrandom","std"] } -base64-url = "2.0.0" \ No newline at end of file +base64-url = "2.0.0" +async-std = { version = "1.12.0", features = ["attributes","unstable"] } +web-time = "0.2.0" \ No newline at end of file diff --git a/ng-wallet/src/lib.rs b/ng-wallet/src/lib.rs index 63e070c..36220f5 100644 --- a/ng-wallet/src/lib.rs +++ b/ng-wallet/src/lib.rs @@ -12,6 +12,8 @@ #[macro_use] extern crate p2p_net; +use p2p_net::log; + pub mod types; pub mod bip39; @@ -32,7 +34,7 @@ use safe_transmute::transmute_to_bytes; use p2p_repo::types::{PubKey, Site, SiteType, Timestamp}; use p2p_repo::utils::{generate_keypair, now_timestamp, sign, verify}; -use rand::{thread_rng, Rng}; +use rand::prelude::*; use serde_bare::{from_slice, to_vec}; pub fn enc_master_key( @@ -167,12 +169,20 @@ pub fn derive_key_from_pass(pass: Vec, salt: [u8; 16], wallet_id: WalletId) argon.hash_password_into(&pass, &salt, &mut out).unwrap(); out } +use web_time::Instant; pub fn open_wallet_with_pazzle( wallet: Wallet, pazzle: Vec, pin: [u8; 4], ) -> Result { + // each digit shouldnt be greater than 9 + if pin[0] > 9 || pin[1] > 9 || pin[2] > 9 || pin[3] > 9 { + return Err(NgWalletError::InvalidPin); + } + + let opening_pazzle = Instant::now(); + verify(&wallet.content_as_bytes(), wallet.sig(), wallet.id()) .map_err(|e| NgWalletError::InvalidSignature)?; @@ -191,6 +201,11 @@ pub fn open_wallet_with_pazzle( v0.id, )?; + log!( + "opening of wallet with pazzle took: {} ms", + opening_pazzle.elapsed().as_millis() + ); + Ok(EncryptedWallet::V0(dec_encrypted_block( v0.content.encrypted, master_key, @@ -246,65 +261,106 @@ pub fn display_mnemonic(mnemonic: &[u16; 12]) -> Vec { res } +pub fn display_pazzle(pazzle: Vec) -> Vec { + // let res: Vec = pazzle + // .into_iter() + // .map(|i| String::from(bip39_wordlist[*i as usize])) + // .collect(); + // res + unimplemented!(); +} + +pub fn gen_shuffle_for_pazzle_opening(pazzle_length: u8) -> ShuffledPazzle { + let mut rng = rand::thread_rng(); + let mut category_indices: Vec = (0..pazzle_length).collect(); + //log!("{:?}", category_indices); + category_indices.shuffle(&mut rng); + //log!("{:?}", category_indices); + + let mut emoji_indices: Vec> = Vec::with_capacity(pazzle_length.into()); + for _ in 0..pazzle_length { + let mut idx: Vec = (0..15).collect(); + //log!("{:?}", idx); + idx.shuffle(&mut rng); + //log!("{:?}", idx); + emoji_indices.push(idx) + } + ShuffledPazzle { + category_indices, + emoji_indices, + } +} + +pub fn gen_shuffle_for_pin() -> Vec { + let mut rng = rand::thread_rng(); + let mut digits: Vec = (0..10).collect(); + //log!("{:?}", digits); + digits.shuffle(&mut rng); + //log!("{:?}", digits); + digits +} + /// creates a Wallet from a pin, a security text and image (with option to send the bootstrap and wallet to nextgraph.one) /// and returns the Wallet, the pazzle and the mnemonic -pub fn create_wallet_v0( - security_img: Vec, - security_txt: String, - pin: [u8; 4], - pazzle_length: u8, - send_bootstrap: Option<&Bootstrap>, - send_wallet: bool, - peer_id: PubKey, - nonce: u64, -) -> Result<(Wallet, Vec, [u16; 12]), NgWalletError> { +pub async fn create_wallet_v0( + params: CreateWalletV0, +) -> Result { // TODO : use some automatically zeroed variable for the 2 first arguments, and for the returned values + let creating_pazzle = Instant::now(); + // pazzle_length can only be 9, 12, or 15 - if (pazzle_length != 9 && pazzle_length != 12 && pazzle_length != 15) { + if (params.pazzle_length != 9 && params.pazzle_length != 12 && params.pazzle_length != 15) { return Err(NgWalletError::InvalidPazzleLength); } // cannot submit wallet if we don't submit also the bootstrap - if send_bootstrap.is_none() && send_wallet { + if params.send_bootstrap.is_none() && params.send_wallet { return Err(NgWalletError::SubmissionError); } // check validity of PIN // shouldn't start with 0 - if pin[0] == 0 { + if params.pin[0] == 0 { return Err(NgWalletError::InvalidPin); } // each digit shouldnt be greater than 9 - if pin[0] > 9 || pin[1] > 9 || pin[2] > 9 || pin[3] > 9 { + if params.pin[0] > 9 || params.pin[1] > 9 || params.pin[2] > 9 || params.pin[3] > 9 { return Err(NgWalletError::InvalidPin); } // check for uniqueness of each digit - if pin[1] == pin[0] - || pin[1] == pin[2] - || pin[1] == pin[3] - || pin[2] == pin[0] - || pin[2] == pin[3] - || pin[3] == pin[0] + if params.pin[1] == params.pin[0] + || params.pin[1] == params.pin[2] + || params.pin[1] == params.pin[3] + || params.pin[2] == params.pin[0] + || params.pin[2] == params.pin[3] + || params.pin[3] == params.pin[0] { return Err(NgWalletError::InvalidPin); } // check for ascending series - if pin[1] == pin[0] + 1 && pin[2] == pin[1] + 1 && pin[3] == pin[2] + 1 { + if params.pin[1] == params.pin[0] + 1 + && params.pin[2] == params.pin[1] + 1 + && params.pin[3] == params.pin[2] + 1 + { return Err(NgWalletError::InvalidPin); } // check for descending series - if pin[3] >= 3 && pin[2] == pin[3] - 1 && pin[1] == pin[2] - 1 && pin[0] == pin[1] - 1 { + if params.pin[3] >= 3 + && params.pin[2] == params.pin[3] - 1 + && params.pin[1] == params.pin[2] - 1 + && params.pin[0] == params.pin[1] - 1 + { return Err(NgWalletError::InvalidPin); } // check validity of security text - let words: Vec<_> = security_txt.split_whitespace().collect(); + let words: Vec<_> = params.security_txt.split_whitespace().collect(); let new_string = words.join(" "); let count = new_string.chars().count(); if count < 10 || count > 100 { @@ -312,7 +368,7 @@ pub fn create_wallet_v0( } // check validity of image - let decoded_img = ImageReader::new(Cursor::new(security_img)) + let decoded_img = ImageReader::new(Cursor::new(params.security_img)) .with_guessed_format() .map_err(|e| NgWalletError::InvalidSecurityImage)? .decode() @@ -339,10 +395,14 @@ pub fn create_wallet_v0( // let mut pazzle_random = vec![0u8; pazzle_length.into()]; // getrandom::getrandom(&mut pazzle_random).map_err(|e| NgWalletError::InternalError)?; - let mut pazzle = vec![0u8; pazzle_length.into()]; let mut ran = thread_rng(); - for i in &mut pazzle { - *i = ran.gen_range(0, 16); + + let mut category_indices: Vec = (0..params.pazzle_length).collect(); + category_indices.shuffle(&mut ran); + + let mut pazzle = vec![0u8; params.pazzle_length.into()]; + for (ix, i) in pazzle.iter_mut().enumerate() { + *i = ran.gen_range(0, 15) + (category_indices[ix] << 4); } //println!("pazzle {:?}", pazzle); @@ -361,7 +421,7 @@ pub fn create_wallet_v0( let encrypted_block = EncryptedWalletV0 { pazzle: pazzle.clone(), mnemonic, - pin, + pin: params.pin, sites: vec![site], }; @@ -375,13 +435,13 @@ pub fn create_wallet_v0( //println!("salt_mnemonic {:?}", salt_mnemonic); let pazzle_key = derive_key_from_pass( - [pazzle.clone(), pin.to_vec()].concat(), + [pazzle.clone(), params.pin.to_vec()].concat(), salt_pazzle, wallet_id, ); let mnemonic_key = derive_key_from_pass( - [transmute_to_bytes(&mnemonic), &pin].concat(), + [transmute_to_bytes(&mnemonic), ¶ms.pin].concat(), salt_mnemonic, wallet_id, ); @@ -394,11 +454,12 @@ pub fn create_wallet_v0( let enc_master_key_mnemonic = enc_master_key(master_key, mnemonic_key, 0, wallet_id)?; let timestamp = now_timestamp(); + let encrypted = enc_encrypted_block( &encrypted_block, master_key, - peer_id, - nonce, + params.peer_id, + params.nonce, timestamp, wallet_id, )?; @@ -412,12 +473,13 @@ pub fn create_wallet_v0( enc_master_key_mnemonic, master_nonce: 0, timestamp, - peer_id, - nonce, + peer_id: params.peer_id, + nonce: params.nonce, encrypted, }; let ser_wallet = serde_bare::to_vec(&wallet_content).unwrap(); + let sig = sign(wallet_key, wallet_id, &ser_wallet).unwrap(); let wallet_v0 = WalletV0 { @@ -442,7 +504,16 @@ pub fn create_wallet_v0( // TODO send bootstrap (if) // TODO send wallet (if) - Ok((Wallet::V0(wallet_v0), pazzle, mnemonic)) + log!( + "creating of wallet took: {} ms", + creating_pazzle.elapsed().as_millis() + ); + + Ok(CreateWalletResultV0 { + wallet: Wallet::V0(wallet_v0), + pazzle, + mnemonic, + }) } #[cfg(test)] @@ -456,7 +527,19 @@ mod tests { use std::time::Instant; #[test] - fn create_wallet() { + fn test_gen_shuffle() { + let shuffle = gen_shuffle_for_pazzle_opening(9); + log!("{:?}", shuffle); + let shuffle = gen_shuffle_for_pazzle_opening(12); + log!("{:?}", shuffle); + let shuffle = gen_shuffle_for_pazzle_opening(15); + log!("{:?}", shuffle); + let digits = gen_shuffle_for_pin(); + let digits = gen_shuffle_for_pin(); + } + + #[async_std::test] + async fn create_wallet() { // loading an image file from disk let f = File::open("tests/valid_security_image.jpg") .expect("open of tests/valid_security_image.jpg"); @@ -471,7 +554,7 @@ mod tests { let creation = Instant::now(); - let res = create_wallet_v0( + let res = create_wallet_v0(CreateWalletV0::new( img_buffer, " know yourself ".to_string(), pin, @@ -483,7 +566,8 @@ mod tests { 98, 243, 49, 90, 7, 0, 157, 58, 14, 187, 14, 3, 116, 86, ]), 0, - ) + )) + .await .expect("create_wallet_v0"); log!( @@ -492,18 +576,19 @@ mod tests { ); log!("-----------------------------"); - let (wallet, pazzle, mnemonic) = res; - let mut file = File::create("tests/wallet.ngw").expect("open wallet write file"); - let ser_wallet = to_vec(&NgFile::V0(NgFileV0::Wallet(wallet.clone()))).unwrap(); + let ser_wallet = to_vec(&NgFile::V0(NgFileV0::Wallet(res.wallet.clone()))).unwrap(); file.write_all(&ser_wallet); - log!("wallet id: {:?}", base64_url::encode(&wallet.id().slice())); - log!("pazzle {:?}", pazzle); - log!("mnemonic {:?}", display_mnemonic(&mnemonic)); + log!( + "wallet id: {:?}", + base64_url::encode(&res.wallet.id().slice()) + ); + log!("pazzle {:?}", res.pazzle); + log!("mnemonic {:?}", display_mnemonic(&res.mnemonic)); log!("pin {:?}", pin); - if let Wallet::V0(v0) = wallet { + if let Wallet::V0(v0) = res.wallet { log!("security text: {:?}", v0.content.security_txt); let mut file = @@ -523,7 +608,7 @@ mod tests { let opening_mnemonic = Instant::now(); - let w = open_wallet_with_mnemonic(Wallet::V0(v0.clone()), mnemonic, pin) + let w = open_wallet_with_mnemonic(Wallet::V0(v0.clone()), res.mnemonic, pin) .expect("open with mnemonic"); //println!("encrypted part {:?}", w); @@ -533,7 +618,7 @@ mod tests { ); let opening_pazzle = Instant::now(); - let w = open_wallet_with_pazzle(Wallet::V0(v0.clone()), pazzle, pin) + let w = open_wallet_with_pazzle(Wallet::V0(v0.clone()), res.pazzle, pin) .expect("open with pazzle"); //println!("encrypted part {:?}", w); diff --git a/ng-wallet/src/types.rs b/ng-wallet/src/types.rs index ad76d5d..15ff87b 100644 --- a/ng-wallet/src/types.rs +++ b/ng-wallet/src/types.rs @@ -7,6 +7,8 @@ // notice may not be copied, modified, or distributed except // according to those terms. +use std::fmt; + use serde::{Deserialize, Serialize}; use serde_big_array::BigArray; @@ -209,9 +211,56 @@ impl AddWallet { } } +/// Create Wallet Version 0, used by the API create_wallet_v0 +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct CreateWalletV0 { + #[serde(with = "serde_bytes")] + pub security_img: Vec, + + pub security_txt: String, + pub pin: [u8; 4], + pub pazzle_length: u8, + pub send_bootstrap: Option, + pub send_wallet: bool, + pub peer_id: PubKey, + pub nonce: u64, +} + +impl CreateWalletV0 { + pub fn new( + security_img: Vec, + security_txt: String, + pin: [u8; 4], + pazzle_length: u8, + send_bootstrap: Option, + send_wallet: bool, + peer_id: PubKey, + nonce: u64, + ) -> Self { + CreateWalletV0 { + security_img, + security_txt, + pin, + pazzle_length, + send_bootstrap, + send_wallet, + peer_id, + nonce, + } + } +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct CreateWalletResultV0 { + pub wallet: Wallet, + pub pazzle: Vec, + pub mnemonic: [u16; 12], +} + #[derive(Debug, Eq, PartialEq, Clone)] pub enum NgWalletError { InvalidPin, + InvalidPazzle, InvalidPazzleLength, InvalidSecurityImage, InvalidSecurityText, @@ -222,6 +271,12 @@ pub enum NgWalletError { InvalidSignature, } +impl fmt::Display for NgWalletError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}", self) + } +} + #[derive(Clone, Debug, Serialize, Deserialize)] pub enum NgFileV0 { Wallet(Wallet), @@ -231,3 +286,9 @@ pub enum NgFileV0 { pub enum NgFile { V0(NgFileV0), } + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct ShuffledPazzle { + pub category_indices: Vec, + pub emoji_indices: Vec>, +} diff --git a/p2p-repo/Cargo.toml b/p2p-repo/Cargo.toml index 9b89be7..2b20d42 100644 --- a/p2p-repo/Cargo.toml +++ b/p2p-repo/Cargo.toml @@ -19,4 +19,5 @@ fastbloom-rs = "0.5.3" debug_print = "1.0.0" hex = "0.4.3" futures = "0.3.24" -base64-url = "2.0.0" \ No newline at end of file +base64-url = "2.0.0" +web-time = "0.2.0" \ No newline at end of file diff --git a/p2p-repo/src/utils.rs b/p2p-repo/src/utils.rs index 82bd741..46952da 100644 --- a/p2p-repo/src/utils.rs +++ b/p2p-repo/src/utils.rs @@ -15,7 +15,7 @@ use crate::types::*; use ed25519_dalek::*; use futures::channel::mpsc; use rand::rngs::OsRng; -use std::time::{SystemTime, UNIX_EPOCH}; +use web_time::{SystemTime, UNIX_EPOCH}; pub fn generate_null_keypair() -> (PrivKey, PubKey) { let master_key: [u8; 32] = [0; 32];