Skip to content

Commit

Permalink
Merge pull request #17 from robertDurst/uppercase-inputs-decouple-pk-…
Browse files Browse the repository at this point in the history
…sk-keygen

uppercase inputs and decouple key gen from encoding
  • Loading branch information
Robert Durst authored Aug 21, 2019
2 parents 9fc3d49 + c5b69dc commit 3ee0f68
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 42 deletions.
31 changes: 23 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ extern crate clap;
extern crate stellar_vanity;

use clap::{App, Arg};
use stellar_vanity::vanity_key::AddressGenerator;
use stellar_vanity::vanity_key::{AddressGenerator, deserialize_public_key, deserialize_private_key};

fn main() {
let matches = App::new("Stellar Vanity Address Generator")
Expand All @@ -29,28 +29,43 @@ fn main() {
if postfix_option.is_none() && prefix_option.is_none() {
eprintln!("\n Please, provide prefix or postfix");
::std::process::exit(1);
}
}

// since we match on uppercase, convert input values to uppercase
let target_string = if let Some(postfix) = postfix_option {
postfix
} else if let Some(prefix) = prefix_option{
prefix
} else {
// impossible case
""
}.to_uppercase();


let mut generator: AddressGenerator = Default::default();

println!("\nSEARCHING INITIATED");

let (public_key, private_key) = generator
.find(|(pk, _)| {
let keypair = generator
.find(|key| {
let mut found = true;
let pk = deserialize_public_key(key);
let key_str = pk.as_str();

if let Some(postfix) = postfix_option {
found &= key_str.ends_with(postfix);
if postfix_option.is_some() {
found &= key_str.ends_with(&target_string);
}

if let Some(prefix) = prefix_option {
found &= key_str[2..].starts_with(prefix);
if prefix_option.is_some() {
found &= key_str[2..].starts_with(&target_string);
}

found
})
.unwrap();

let public_key = deserialize_public_key(&keypair);
let private_key = deserialize_private_key(&keypair);

println!(
"\nSUCCESS!\nPublic Key: {:?}\nSecret Key: {:?}",
Expand Down
77 changes: 43 additions & 34 deletions src/vanity_key/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ use rand::{CryptoRng, Rng};
/// <h3> Sample Code: </h3>
///
/// ````
/// use stellar_vanity::vanity_key::generate_vanity_key;
/// use stellar_vanity::vanity_key::AddressGenerator, deserialize_public_key};;
///
/// let mut generator: AddressGenerator = Default::default();
/// let (public_key, private_key) = generator.find(|public, private| {
/// let keypair = generator.find(|key| {
/// let public = deserialize_public_key(key);
/// // any conditions go here
/// public.as_str().ends_with("RUST") // e.g. find address with the "RUST" suffix
/// });
Expand All @@ -36,39 +37,11 @@ where
AddressGenerator { rng }
}

fn generate_random_key(&mut self) -> (String, String) {
fn generate_random_keypair(&mut self) -> Keypair {
// Generate ED25519 key pair
let keypair: Keypair = Keypair::generate(&mut self.rng);

// ************** Encode the public key ***************** //
const VERSION_BYTE_ACCOUNT_ID: u8 = 6 << 3;
let mut bytes_public = vec![VERSION_BYTE_ACCOUNT_ID];
// Combine the byte version and the ED25519 raw public key bytes array
&bytes_public.extend_from_slice(&keypair.public.to_bytes());
// Calculate checksum
let checksum_public = State::<XMODEM>::calculate(&bytes_public);
// Create a buffer to combine byte version : ED25519 raw key : checksum
let mut bytes_buffer_public = BytesMut::with_capacity(1024);
bytes_buffer_public.put(&bytes_public);
bytes_buffer_public.put_u16_le(checksum_public);
// Base 32 encode the public key
let public_key = encode(RFC4648 { padding: false }, &bytes_buffer_public);

// ************** Encode the private key ***************** //
const VERSION_BYTE_SEED: u8 = 18 << 3;
let mut bytes_private = vec![VERSION_BYTE_SEED];
// Combine the byte version and the ED25519 raw private key bytes array
&bytes_private.extend_from_slice(&keypair.secret.to_bytes());
// Calculate checksum
let check_sum_private = State::<XMODEM>::calculate(&bytes_private);
// Create a buffer to combine byte version : ED25519 raw key : checksum
let mut bytes_buffer_private = BytesMut::with_capacity(1024);
bytes_buffer_private.put(&bytes_private);
bytes_buffer_private.put_u16_le(check_sum_private);
// Base 32 encode the private key
let private_key = encode(RFC4648 { padding: false }, &bytes_buffer_private);

(public_key, private_key)
keypair
}
}

Expand All @@ -84,9 +57,45 @@ impl<T> Iterator for AddressGenerator<T>
where
T: Rng + CryptoRng,
{
type Item = (String, String);
type Item = Keypair;

fn next(&mut self) -> Option<Self::Item> {
Some(self.generate_random_key())
Some(self.generate_random_keypair())
}
}

pub fn deserialize_public_key(keypair: &Keypair) -> String {
// ************** Encode the public key ***************** //
const VERSION_BYTE_ACCOUNT_ID: u8 = 6 << 3;
let mut bytes_public = vec![VERSION_BYTE_ACCOUNT_ID];
// Combine the byte version and the ED25519 raw public key bytes array
&bytes_public.extend_from_slice(&keypair.public.to_bytes());
// Calculate checksum
let checksum_public = State::<XMODEM>::calculate(&bytes_public);
// Create a buffer to combine byte version : ED25519 raw key : checksum
let mut bytes_buffer_public = BytesMut::with_capacity(1024);
bytes_buffer_public.put(&bytes_public);
bytes_buffer_public.put_u16_le(checksum_public);
// Base 32 encode the public key
let public_key = encode(RFC4648 { padding: false }, &bytes_buffer_public);

public_key
}

pub fn deserialize_private_key(keypair: &Keypair) -> String {
// ************** Encode the private key ***************** //
const VERSION_BYTE_SEED: u8 = 18 << 3;
let mut bytes_private = vec![VERSION_BYTE_SEED];
// Combine the byte version and the ED25519 raw private key bytes array
&bytes_private.extend_from_slice(&keypair.secret.to_bytes());
// Calculate checksum
let check_sum_private = State::<XMODEM>::calculate(&bytes_private);
// Create a buffer to combine byte version : ED25519 raw key : checksum
let mut bytes_buffer_private = BytesMut::with_capacity(1024);
bytes_buffer_private.put(&bytes_private);
bytes_buffer_private.put_u16_le(check_sum_private);
// Base 32 encode the private key
let private_key = encode(RFC4648 { padding: false }, &bytes_buffer_private);

private_key
}

0 comments on commit 3ee0f68

Please sign in to comment.