switch to diceware platform independent word list (EffLong)

This commit is contained in:
2026-04-25 07:31:22 -04:00
parent 383a1a2b8b
commit 3734306830
3 changed files with 27 additions and 12 deletions
Generated
+7
View File
@@ -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",
]
+1
View File
@@ -7,3 +7,4 @@ edition = "2024"
rand = "0.8"
webster = "0.3.0"
bitflags = "2"
diceware_wordlists = "1.2.3"
+19 -12
View File
@@ -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<Stri
Ok(res)
}
// todo: haven't updated bits of entropy since adding capitalization, symbols and numbers
// it will add a few, but not many since it's fairly predictable
// todo: haven't updated bits of entropy comments since adding capitalization,
// symbols, numbers and changing to diceware wordlist
//
// How many bits of entropy?
// log2(104078) -> 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