From 72bc05641930f6bbe065333cd2f8c1b3d4175e49 Mon Sep 17 00:00:00 2001 From: Octavian Oncescu Date: Sat, 15 Oct 2022 04:49:59 +0200 Subject: [PATCH] Add generate batch --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/main.rs | 30 +++++++++++++++++++++++++----- src/wallet.rs | 25 +++++++++++++++++-------- 4 files changed, 44 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e932dd4..2b6826c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -427,7 +427,7 @@ dependencies = [ [[package]] name = "purplecoincli" -version = "0.0.1" +version = "0.0.2" dependencies = [ "argon2rs", "bech32", diff --git a/Cargo.toml b/Cargo.toml index 6810d67..a68c6d5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "purplecoincli" -version = "0.0.1" +version = "0.0.2" edition = "2021" license = "MIT OR Apache-2.0" description = "Purplecoin CLI tools" diff --git a/src/main.rs b/src/main.rs index 016cbd1..0a1c240 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,14 +20,13 @@ struct Cli { enum Commands { /// Generate a simple encrypted wallet and print it to the screen GenSimpleWallet, + GenSimpleWalletBatch { batch_size: u64 }, } fn main() { let cli = Cli::parse(); - // You can check for the existence of subcommands, and if found use their - // matches just as you would the top level cmd match &cli.command { Some(Commands::GenSimpleWallet) => { let mut password = rpassword::prompt_password("Your password: ").unwrap(); @@ -38,11 +37,32 @@ fn main() { return; } - let (address, encrypted_key) = gen_encrypted_simple_wallet(&password); + let addresses = gen_encrypted_simple_wallet(&password, 1); password.zeroize(); confirm_password.zeroize(); - println!("Your address is: {}", address); - println!("Your encrypted key is: {}", encrypted_key); + println!("Your address is: {}", addresses[0].0); + println!("Your encrypted key is: {}", addresses[0].1); + } + Some(Commands::GenSimpleWalletBatch { batch_size }) => { + if batch_size > &100_000 { + println!("Max batch size is 100,000!"); + return; + } + + let mut password = rpassword::prompt_password("Your password: ").unwrap(); + let mut confirm_password = rpassword::prompt_password("Your password confirmation: ").unwrap(); + + if password != confirm_password { + println!("Password does not match password confirmation!"); + return; + } + + let batch = gen_encrypted_simple_wallet(&password, *batch_size); + password.zeroize(); + confirm_password.zeroize(); + for (address, encrypted_key) in batch.iter() { + println!("{} {}", address, encrypted_key); + } } None => { println!("No command given. Type \"purplecoincli help\" for a list of commands.") diff --git a/src/wallet.rs b/src/wallet.rs index 3096d31..25c64e3 100644 --- a/src/wallet.rs +++ b/src/wallet.rs @@ -18,10 +18,10 @@ use zeroize::Zeroize; const SEED_BYTES: usize = 64; -/// Generates a simple wallet consisting of an Address and encrypted private key. +/// Generates simple wallets consisting of an Address and encrypted private key. /// /// Returns them as a tuple of two strings. -pub fn gen_encrypted_simple_wallet(passphrase: &str) -> (String, String) { +pub fn gen_encrypted_simple_wallet(passphrase: &str, batch_size: u64) -> Vec<(String, String)> { // Generate random 64 byte seed let mut rng = rand::thread_rng(); let mut seed: [u8; SEED_BYTES] = [0; SEED_BYTES]; @@ -84,9 +84,19 @@ pub fn gen_encrypted_simple_wallet(passphrase: &str) -> (String, String) { 0x000000, ); - let mut next_internal = master_keypair_internal.derive_next(); - let address = next_internal.pub_key().to_address().to_bech32("pu"); - let encrypted_key = hex::encode(next_internal.secret_key.secret_key); + let batch = (0..batch_size) + .into_iter() + .map(|_| { + let mut next_internal = master_keypair_internal.derive_next(); + master_keypair_internal = next_internal.clone(); + let address = next_internal.pub_key().to_address().to_bech32("pu"); + let encrypted_key = hex::encode(next_internal.secret_key.secret_key); + + next_internal.zeroize(); + (address, encrypted_key) + }).collect(); + + seed.zeroize(); encryption_key.zeroize(); @@ -96,9 +106,8 @@ pub fn gen_encrypted_simple_wallet(passphrase: &str) -> (String, String) { passphrase_hash256.zeroize(); master_priv_hash512.zeroize(); master_keypair_internal.zeroize(); - next_internal.zeroize(); - (address, encrypted_key) + batch } @@ -195,7 +204,7 @@ pub struct XPriv { secret_key: [u8; 64], } -#[derive(Encode, Decode, Zeroize, Debug)] +#[derive(Encode, Decode, Zeroize, Debug, Clone)] pub struct XKeypair { pub pub_key: XPub, pub secret_key: XPriv,