From 37343068304b11dbe49f892cddb17bfa3bae1a4b Mon Sep 17 00:00:00 2001 From: Ed Guloien Date: Sat, 25 Apr 2026 07:31:22 -0400 Subject: [PATCH] switch to diceware platform independent word list (EffLong) --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + src/main.rs | 31 +++++++++++++++++++------------ 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a22401f..5551861 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,6 +29,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "diceware_wordlists" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f9b52b69d268c7a2bc582e3aec5cdfa43ac91cef4fe6b6751b02da2b43d6166" + [[package]] name = "getrandom" version = "0.2.17" @@ -89,6 +95,7 @@ name = "password-generator" version = "0.1.0" dependencies = [ "bitflags", + "diceware_wordlists", "rand", "webster", ] diff --git a/Cargo.toml b/Cargo.toml index 3a23e6d..c68d7d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,4 @@ edition = "2024" rand = "0.8" webster = "0.3.0" bitflags = "2" +diceware_wordlists = "1.2.3" diff --git a/src/main.rs b/src/main.rs index 29c422b..1b6bc6e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,10 +3,12 @@ use rand::rngs::OsRng; use rand::SeedableRng; use rand::rngs::StdRng; -use std::fs; +// use std::fs; use rand::prelude::SliceRandom; use bitflags::bitflags; +use diceware_wordlists::Wordlist; + const UPPERCASE_CHARS: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ"; const LOWERCASE_CHARS: &[u8] = b"abcdefghijklmnopqrstuvwxyz"; const NUMBER_CHARS: &[u8] = b"0123456789"; @@ -196,14 +198,13 @@ fn generate_password(config: &PasswordConfig, rng: &mut impl Rng) -> Result 16.6 bits per word derived from word_list size // log2(18) -> 4.1 bits for separator assuming seporator is one of our SYMBOLs // total 70.5 bits of entropy -// note: dictionary is provided by linux, so entropy is platform dependent ATM // // we can take a slice of "words" because we don't care about: // capacity, mutation (push/pop), allocation strategy @@ -240,16 +241,22 @@ fn random_word<'a>(word_list: &[&'a str], rng: &mut impl Rng) -> &'a str { word_list[rng.gen_range(0..word_list.len())] } -fn main() { - // todo: not cross-platform - // todo: abstract this a bit - let content = fs::read_to_string("/usr/share/dict/words") - .expect("could not read dictionary"); - +fn get_word_list() -> &'static [&'static str] { + // platform dependent word list + // let content = fs::read_to_string("/usr/share/dict/words") + // .expect("could not read dictionary"); // filter words here for only ascii // word_list length is 104078 - let word_list: Vec<&str> = content.lines().filter(|w| - w.is_ascii()).collect(); + // let word_list: Vec<&str> = content.lines().filter(|w| + // w.is_ascii()).collect(); + + // platform independent word list + // this list doesn't seem to contain non-ascii or even punctuation + Wordlist::get_list(&Wordlist::EffLong) +} + +fn main() { + let word_list = get_word_list(); // we definitely want to use the OS for randomness // doesn't require seeding because it is backed by CSPRNG, backed by OS