rusty-diceware

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit ad78d15d5e27b0eedb39e61e15e775495486815b
parent 4f74bb7ec561b0406d84c54c6ef293400031dd8b
Author: Yuval Langer <yuval.langer@gmail.com>
Date:   Tue, 16 Jun 2015 23:14:49 +0300

Adding a proper command line interface

Also adding methods to get the entropy of the passphrase with its own flag.

Diffstat:
Mbuild.rs | 6++++++
Msrc/diceware.rs | 33+++++++++++++++++++++++++++++++++
Msrc/main.rs | 103+++++++++++++++++++++++++++++--------------------------------------------------
3 files changed, 77 insertions(+), 65 deletions(-)

diff --git a/build.rs b/build.rs @@ -22,6 +22,8 @@ fn make_minilock_wordlist(contents: &str) -> Vec<&str> { fn make_beale_struct(wordlist: Vec<&str>) -> std::string::String { let mut output = std::string::String::new(); + + // 7776 words = 6*6*6*6*6; five 6 faced dice throws. output.push_str("const BEALE_WORDLIST: [BealeWord; 7776] = [\n"); for word in wordlist { output.push_str(" BealeWord(\""); @@ -40,6 +42,8 @@ fn make_beale_struct(wordlist: Vec<&str>) -> std::string::String { fn make_reinhold_struct(wordlist: Vec<&str>) -> std::string::String { let mut output = std::string::String::new(); + + // 7776 words = 6*6*6*6*6; five 6 faced dice throws. output.push_str("const REINHOLD_WORDLIST: [ReinholdWord; 7776] = [\n"); for word in wordlist { output.push_str(" ReinholdWord(\""); @@ -58,6 +62,8 @@ fn make_reinhold_struct(wordlist: Vec<&str>) -> std::string::String { fn make_minilock_struct(wordlist: Vec<&str>) -> std::string::String { let mut output = std::string::String::new(); + + // 58110 words in the MiniLock wordlist. output.push_str("const MINILOCK_WORDLIST: [MiniLockWord; 58110] = [\n"); for word in wordlist { output.push_str(" MiniLockWord(\""); diff --git a/src/diceware.rs b/src/diceware.rs @@ -14,15 +14,48 @@ pub struct ReinholdWord(&'static str); pub struct MiniLockWord(&'static str); impl BealeWord { + #[cfg(test)] pub fn new(word: &'static str) -> BealeWord { BealeWord(word.clone()) } + + pub fn entropy() -> f64 { + (BEALE_WORDLIST.len() as f64).log2() + } + + pub fn entropyn(n: u64) -> f64 { + BealeWord::entropy() * (n as f64) + } } impl ReinholdWord { + #[cfg(test)] pub fn new(word: &'static str) -> ReinholdWord { ReinholdWord(word.clone()) } + + pub fn entropy() -> f64 { + (REINHOLD_WORDLIST.len() as f64).log2() + } + + pub fn entropyn(n: u64) -> f64 { + ReinholdWord::entropy() * (n as f64) + } +} + +impl MiniLockWord { + #[cfg(test)] + pub fn new(word: &'static str) -> MiniLockWord { + MiniLockWord(word.clone()) + } + + pub fn entropy() -> f64 { + (MINILOCK_WORDLIST.len() as f64).log2() + } + + pub fn entropyn(n: u64) -> f64 { + MiniLockWord::entropy() * (n as f64) + } } impl rand::Rand for BealeWord { diff --git a/src/main.rs b/src/main.rs @@ -1,26 +1,31 @@ mod diceware; +#[cfg(test)] +mod tests; + extern crate rand; extern crate getopts; -//use std::env; -//use std::io::Read; -// use std::fs::File; +use std::env; -// use getopts::Options; +use getopts::Options; use rand::Rng; use diceware::{BealeWord, ReinholdWord, MiniLockWord}; -/* + + fn make_options() -> Options { let mut opts = Options::new(); opts.optflag("h", "help", "this help message"); - opts.optflag("", "beale", "use the beale wordlist"); + opts.optflag("", "minilock", "use the MiniLock wordlist (default)"); opts.optflag("", "reinhold", "use the standard wordlist"); + opts.optflag("", "beale", "use the beale wordlist"); + opts.optflag("e", "entropy", "display number of entropy bits"); opts.optopt("n", "nword", "number of words in a passphrase", "NWORD"); opts } + fn print_passphrase(wordlist: Vec<&str>, word_num: u64) -> () { let mut rng = rand::OsRng::new().unwrap(); let mut c = rng.choose(&wordlist); @@ -31,16 +36,15 @@ fn print_passphrase(wordlist: Vec<&str>, word_num: u64) -> () { println!("{}", c.unwrap()); } + fn print_usage(program: &str, opts: Options) { let brief = format!("Usage: {} [options]", program); print!("{}", opts.usage(&brief)); } -*/ #[cfg(not(test))] fn main() { - /* let args: Vec<String> = env::args().collect(); let program = args[0].clone(); @@ -54,75 +58,44 @@ fn main() { if matches.opt_present("h") { print_usage(&program, opts); return; - } - - let word_num: u64 = matches.opt_str("n").ok() { - Some(n) => { n.parse::<u64>().err } - None => { - print_usage(&program, opts); - return; - } }; - */ + + let word_num: u64 = matches.opt_str("n") + .map_or(8, |n_str| n_str.parse::<u64>().ok().unwrap()); let mut rng = rand::OsRng::new().unwrap(); - println!("Beale:"); - for _ in 1..8 { - let word: diceware::BealeWord = rng.gen(); - print!("{} ", word); + if matches.opt_present("reinhold") { + for _ in 0..word_num { + let word: diceware::ReinholdWord = rng.gen(); + print!("{} ", word); + } + println!(""); + if matches.opt_present("entropy") { + println!("{}", diceware::ReinholdWord::entropyn(word_num)) + } + return; } - println!(""); - println!(""); - println!("Reinhold:"); - for _ in 1..8 { - let word: diceware::ReinholdWord = rng.gen(); - print!("{} ", word); + if matches.opt_present("beale") { + for _ in 0..word_num { + let word: diceware::BealeWord = rng.gen(); + print!("{} ", word); + } + println!(""); + if matches.opt_present("entropy") { + println!("{}", diceware::BealeWord::entropyn(word_num)) + } + return; } - println!(""); - println!(""); - println!("MiniLock:"); - for _ in 1..8 { + for _ in 0..word_num { let word: diceware::MiniLockWord = rng.gen(); print!("{} ", word); } println!(""); - -} - -#[cfg(test)] -mod test { - extern crate rand; - - use rand::{Rng, SeedableRng, StdRng}; - - use diceware::{ReinholdWord, BealeWord}; - - fn make_beale_word() -> BealeWord { - let seed: &[_] = &[1, 2, 3, 4]; - let mut rng: StdRng = SeedableRng::from_seed(seed); - let word = rng.gen(); - word + if matches.opt_present("entropy") { + println!("{}", diceware::MiniLockWord::entropyn(word_num)) } - fn make_reinhold_word() -> ReinholdWord { - let seed: &[_] = &[1, 2, 3, 4]; - let mut rng: StdRng = SeedableRng::from_seed(seed); - let word = rng.gen(); - word - } - - #[test] - fn beale_rng_test() { - let rand_word = make_beale_word(); - assert_eq!(rand_word, BealeWord::new("ladder")) - } - - #[test] - fn reinhold_rng_test() { - let rand_word = make_reinhold_word(); - assert_eq!(rand_word, ReinholdWord::new("ks")) - } }