Passphrases
Diceware passphrases from the EFF word lists, easy to type and remember and hard to guess, with their strength in bits.
Version 1.0.0 · 3 functions · 2 crates
Functions
What use passphrase.qwer gives a program, with the types Quillo sees. To take only some, or under other names: use passphrase, passphrase_with from passphrase (Quillo 0.6).
passphrase(words: int, separator: str) → stror an errorA passphrase of words words (3 to 20) from the EFF long list, joined by separator ("-", " ", "." ...; up to 3 characters). Each word adds 12.9 bits: 5 words, 64.6 bits; 6 words, 77.5. Picked with the system's secure random numbers.
passphrase_with(words: int, separator: str, list_name: str, capitalize: bool, digit: bool) → anyor an errorA passphrase with choices: list "long", "short" or "memorable"; capitalize each word; digit adds one digit to one word, for sites that ask for one. Gives { passphrase, words, bits }, bits being its strength when the guesser knows the list and the rules.
passphrase_bits(words: int, list_name: str) → floator an errorThe strength in bits of words words from list ("long", "short" or "memorable").
Get it
$ quillo install passphrase # passphrase.qwer into this folder$ quillo install passphrase --example # and its example, passphrase.qweOr with curl:
$ curl -O https://quillolang.org/plugins/files/passphrase.qwer$ curl -O https://quillolang.org/plugins/files/passphrase.qweThen, in your program, all of it or only what you call:
use passphrase.qweruse passphrase, passphrase_with from passphrase // Quillo 0.6: only theseIt uses these crates, which cargo fetches the first time the plugin is built:
diceware_wordlists = "1.2"rand = "0.8"Example
// First passwords for new staff accounts, and a recovery phrase, as passphrases.//// quillo run passphrase.qwe then open http://localhost:8080/newuse "passphrase.qwer"route GET /new ? { words: int = 5 } = { password: passphrase(words, "-")?, bits: passphrase_bits(words, "long")? }route GET /wifi = passphrase_with(4, " ", "memorable", true, true)?route GET /strength = { five_long: passphrase_bits(5, "long")?, six_long: passphrase_bits(6, "long")?, eight_short: passphrase_bits(8, "short")? }$ quillo run passphrase.qwe$ curl 'localhost:8080/new'$ curl 'localhost:8080/strength'$ curl 'localhost:8080/wifi'Source
//! Diceware passphrases from the EFF word lists (`crane-shrunk-gristle-unwind-pacific`): easy to type and remember, hard to guess, for first passwords, Wi-Fi keys and recovery phrases.//! version: 1.0.0//!//! [dependencies]//! diceware_wordlists = "1.2"//! rand = "0.8"use diceware_wordlists::Wordlist;use rand::seq::SliceRandom;use rand::Rng;use serde_json::{json, Value};fn list(name: &str) -> Result<&'static [&'static str], String> { match name { "" | "long" => Ok(Wordlist::EffLong.get_list()), "short" => Ok(Wordlist::EffShort1.get_list()), "memorable" => Ok(Wordlist::EffShort2.get_list()), other => Err(format!("unknown list `{}`: long (7,776 words), short (1,296 short words) or memorable (1,296 words with unique 3-letter starts)", other)), }}fn make(words: i64, separator: &str, list_name: &str, capitalize: bool, digit: bool) -> Result<Value, String> { let l = list(list_name)?; let n = words.clamp(3, 20) as usize; let mut rng = rand::rngs::OsRng; let mut picked: Vec<String> = (0..n).map(|_| l.choose(&mut rng).copied().unwrap_or("word").to_string()).collect(); if capitalize { for w in picked.iter_mut() { let mut c = w.chars(); *w = c.next().map(|f| f.to_uppercase().collect::<String>() + c.as_str()).unwrap_or_default(); } } let mut bits = n as f64 * (l.len() as f64).log2(); if digit { let at = rng.gen_range(0..n); picked[at].push_str(&rng.gen_range(0..10).to_string()); bits += 10f64.log2() + (n as f64).log2(); } let sep: String = separator.chars().take(3).collect(); Ok(json!({ "passphrase": picked.join(&sep), "words": n, "bits": (bits * 10.0).round() / 10.0 }))}/// A passphrase of `words` words (3 to 20) from the EFF long list, joined by `separator` ("-", " ", "." ...; up to 3/// characters). Each word adds 12.9 bits: 5 words, 64.6 bits; 6 words, 77.5. Picked with the system's secure random numbers.pub fn passphrase(words: i64, separator: &str) -> Result<String, String> { Ok(make(words, separator, "long", false, false)?["passphrase"].as_str().unwrap_or_default().to_string())}/// A passphrase with choices: `list` "long", "short" or "memorable"; `capitalize` each word; `digit` adds one digit to one/// word, for sites that ask for one. Gives `{ passphrase, words, bits }`, `bits` being its strength when the guesser knows/// the list and the rules.pub fn passphrase_with(words: i64, separator: &str, list_name: &str, capitalize: bool, digit: bool) -> Result<Value, String> { make(words, separator, list_name, capitalize, digit)}/// The strength in bits of `words` words from `list` ("long", "short" or "memorable").pub fn passphrase_bits(words: i64, list_name: &str) -> Result<f64, String> { Ok(((words.max(0) as f64 * (list(list_name)?.len() as f64).log2()) * 10.0).round() / 10.0)}Related
password_strength.qwer · 1.0.0How guessable a password is (zxcvbn): a score from 0 to 4, a warning and suggestions, and how long it would take to crack.6 views · 8 downloadsArgon2 passwords argon2.qwer · 1.0.0Argon2id password hashes with the memory and passes you choose, any Argon2 hash verified, its parameters read, old ones marked for a rehash, and the cost timed on this server.7 views · 6 downloadsBcrypt bcrypt.qwer · 1.0.0Sign in users whose bcrypt hashes came from PHP, Rails, Django or Laravel, then move them to Quillo's Argon2.8 views · 9 downloadsCaptcha captcha.qwer · 1.0.0Picture captchas made on your own server: distorted letters as a PNG data URL and the answer to keep in the session.7 views · 6 downloadsLegacy passwords legacy_passwords.qwer · 1.0.0Check passwords against Django, Flask/Werkzeug and WordPress hashes, to sign in users moved from those apps and rehash them with Argon2.7 views · 7 downloadsPwned passwords pwned.qwer · 1.0.0Have I Been Pwned's Pwned Passwords by k-anonymity: only 5 characters of the SHA-1 leave the server, the answer is checked here.8 views · 9 downloadsThread 0 posts
On Passphrases: questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.